本应用笔记介绍如何管理 STM32 产品中的内存保护单元(MPU)。MPU 是用于存储器保护的可选组件。STM32 微控制器(MCU)中嵌入 MPU 之后变得更稳健可靠。在使用 MPU 之前,必须对其进行编程并加以启用。如果 MPU 没有启用,则存储系统的行为不会变化。
MPU 可以使嵌入式系统更加稳健和安全:
- 禁止用户应用程序破坏关键任务(例如操作系统核心)使用的数据
- 将 SRAM 存储区域定义为非可执行(禁止执行 XN),以防止代码注入攻击
- 修改存储访问属性
MPU可最多保护16个内存区域。在 Armv6、Armv7 架构(Cortex-M0+、M3、M4、M7)下,这些区域可以依次拥有 8 个子区域(前提是区域至少有 256 字节))。在 STM32 中,受保护区域的确切数量可能因内核和器件而有所不同,子区域的大小都是相等的,可以根据子区域号进行启用或禁用。因为最小区域大小是由缓存行长度(32 字节)驱动的,所以 8 个 32 字节的子区域对应一个 256 字节的区域。
区域的编号为 0 至 15。此外,还有一处默认区域,其 id 为-1。所有编号 0-15 的存储区域的优先级高于默认区域。
这些区域可以重叠,也可以嵌套。区域 0-15 的优先级由低到高,这也决定了区域重叠的方式。优先级是固定的,不可更改。
在 Armv8 架构(Cortex-M33)中,使用起始地址和终止地址来定义区域,使开发人员能够以灵活、简单的方式组织这些区域。此外,正是区域大小的可灵活配置得到提升,故Cortex-M33就没有子区域的概念了。
在 Armv8 架构(Cortex-M33)中,现在不允许区域重叠。由于 MPU 区域的定义更加灵活,因此没有必要重叠MPU 区域。
MPU 是统一的,意味着没有单独的区域用于数据和指令。
MPU 还可以用于定义其他存储器属性(如可缓存性),可以导出到系统级缓存单元或存储存控制器。Arm 架构中的存储器属性设置可以支持两种级别的缓存:内部缓存和外部缓存。STM32F7 和 STM32H7 系列仅支持一种级别的缓存(L1-缓存)。
缓存控制由缓存控制寄存器实现全局控制,但 MPU 可以指定缓存策略以及区域是否可缓存。