Блок защиты памяти (MPU)
У микроконтроллера нет операционной системы с виртуальной памятью, но защитить часть памяти всё же можно. В ядрах Cortex-M для этого есть блок защиты памяти (MPU): он разрешает или запрещает обращения к заданным областям и выполнение кода из них.
Обновлено Редакция GAW
Блок защиты памяти (Memory Protection Unit, MPU) — необязательный блок ядер Arm Cortex-M, который делит карту памяти на области и для каждой задаёт права доступа и атрибуты: можно ли читать, писать, выполнять код, для привилегированного кода или для всех. Обращение в нарушение правил вызывает отказ MemManage, а если его обработчик не включён — HardFault. Виртуальной памяти, как в процессорах с MMU, у MPU нет: адреса не преобразуются, только проверяются.
Области
По руководству Arm для Cortex-M3 (разд. 4.5):
| Параметр | Значение |
|---|---|
| Число областей | 8 (0–7) плюс фоновая |
| Размер | 2SIZE+1 байт, от 32 байт до 4 ГБ |
| Базовый адрес | выровнен на размер области |
| Подобласти | 8 на область, у областей 128 байт и меньше нет |
| Перекрытие | действует область с большим номером |
Фоновая область повторяет атрибуты стандартной карты памяти, но доступна только привилегированному коду. Бит XN запрещает выполнение кода из области — так защищают ОЗУ и периферию от случайного перехода туда.
Зачем в прошивке
- Защита от переполнения стека. Маленькая область без прав доступа под нижней границей стека превращает тихую порчу данных в немедленный отказ.
- Запрет выполнения из ОЗУ — от ошибок с указателями на функции.
- Изоляция задач в ОС реального времени — ядро ОС перенастраивает области при переключении задач.
Не путать MPU с датчиком MPU-6050 (это название линейки датчиков движения) и с MMU — блоком виртуальной памяти в процессорах приложений. Карта памяти Cortex-M3 и исключения — в статье «Архитектура ARM Cortex-M3», границы областей памяти в прошивке задаёт скрипт компоновщика.
Частые вопросы
Есть ли MPU во всех STM32?
Нет: в Cortex-M3 и M4 MPU — необязательный блок, и производитель решает, ставить ли его. Наличие и число областей можно узнать из регистра MPU_TYPE: если поле DREGION равно нулю, блока нет. Например, у STM32F103 MPU нет: в его заголовке CMSIS `__MPU_PRESENT = 0`. Точный ответ для конкретной серии даёт её даташит или руководство программиста.
Можно ли с помощью MPU поймать переполнение стека?
Да: под нижней границей стека делают маленькую область без прав доступа. Когда стек переполняется и залезает в неё, вместо тихой порчи данных возникает отказ MemManage (или HardFault, если обработчик не включён), и ошибку видно сразу. Наименьшая область у Cortex-M3 — 32 байта, адрес должен быть выровнен на её размер.
Почему размер области MPU — степень двойки?
Так устроен регистр MPU_RASR: размер задаётся полем SIZE как 2^(SIZE+1) байт, от 32 байт до 4 ГБ, а базовый адрес должен быть выровнен на этот размер. Для более точной настройки область делится на 8 подобластей, которые можно отключать по отдельности.
Источники
- Arm. Cortex-M3 Devices Generic User Guide, DUI 0552A, 2010 — разд. 4.5: MPU необязателен; делит карту памяти на области с адресом, размером, правами и атрибутами; у Cortex-M3 8 областей (0–7) и фоновая область, доступная только привилегированному коду; при перекрытии действует область с большим номером; запрещённое обращение вызывает отказ MemManage; табл. 4-43: размер области 2^(SIZE+1) байт, наименьший 32 байта, наибольший 4 ГБ; базовый адрес выровнен на размер области; 8 подобластей, у областей 128 байт и меньше их нет; бит XN запрещает выборку команд
- Arm. ARMv7-M Architecture Reference Manual, DDI 0403E.e, 2021 — архитектура защищённой системы памяти PMSAv7, регистры MPU_TYPE, MPU_CTRL, MPU_RNR, MPU_RBAR, MPU_RASR
Нашли ошибку?