前言
之前在一段时间内接触过MPU,当时由于要完成任务,所以对MPU没有做过多的研究,并且在网上搜索关于MPU的资料,能把他介绍的很全面的很少,下面是我个人结合ARM的官方文档以及自己整理的一些资料,以Cortex-M0+架构为基础讲解MPU,希望能对大家有所帮助。
何为MPU
MPU意思是Memory Protect Unit,即为存储保护单元,它是位于存储器内部的一个可编程的区域,定义了存储器的属性和存储器的访问权限。MPU不会提升嵌入式应用的性能,而是用于系统中问题的检测(比如试图访问非法或者不允许的存储器位置所导致的应用错误)。如果检测到有错误,则会触发HardFault异常。实际上,许多微控制器用不到MPU,但MPU可以提高嵌入式系统的健壮性,在如下的情况中使得系统更加安全:
- 避免应用任务破坏其他任务或者OS内核使用的栈或数据存储器。
- 避免非特权任务访问对系统可靠性和安全性很重要的外设。
- 将SRAM或RAM定义为不可执行的(永不执行,XN),可以防止代码注入攻击。
还可以利用MPU定义其他存储器属性,例如可被输出到系统级的缓存单元或存储器 控制器的可缓存性。MPU默认是禁止的,此时对于存储器来说,其使用的是默认的存储器属性。
MPU适用场景探讨
其实对于简单的应用,比如IO控制,不太可能会用到MPU,除非使用的微处理器中存在系统级的缓存且需要MPU对其进行定义。
物联网,如果应用是和网络相关的东西,或者应用面临着无法信任的通信接口,则MPU有助于提高安全性。例如:将用于通信缓冲的存储器区域定义为不可执行的地址区域后,就可以防止代码注入攻击。
工业控制领域,如果应用需要很高的可靠性,则MPU可为多任务系统中栈加以限制,以检测一些意想不到的错误。
汽车应用,MPU常用于汽车部件中。软件部件间不能互相有接口,所以需要MPU处理存储器区域。
我们可以将MPU的应用分为以下几类:
- 安全管理:
未受信任或者风险较高的软件部件,应该运行在非特权等级。MPU可以限制这些部件访问的存储器空间。
用作通信缓冲RAM空间中可能包含通信注入的恶意代码,MPU可以将存储器空间定义为不可执行。 - 系统可靠性:
在多任务的系统中,MPU可以定义应用任务栈的合法存储器空间,使得任务不会破坏其他任务或OS数据栈的空间。
若应用具有较高的安全需求,则MPU可以将栈空间最后定义为不可访问的存储器空间,这样可以检测出栈溢出。
有些程序可能需要将代码复制到SRAM中执行,或者将向量表复制到SRAM中以提高访问速度。在复制完代码或者向量之后,存储器空间可以被定义为只读的,防止存储器空间被意外的修改。 - 存储器属性管理:
可以利用MPU定义可被缓存的存储器空间,以及存储策略(写通vs写回)。
利用MPU配置覆盖掉某个存储器空间的默认配置。
总之,我们需要根据具体的项目需要,选择MPU是默认配置还是需要改一些配置,这样才能使我们的应用更加符合要求。
MPU相关寄存器介绍
Cortex-M0+处理器中的MPU最多支持8个可编程的存储器空间以及1个可选的背景区域。每个可编程的区域都有自己的起始地址、大小以及属性设置。对于ARM-v6M和ARM-v7M架构,MPU的区域可以重叠,如果某存储区域位于两个已编程的MPU区域中,则其存储属性和权限会基于编号更大的那个区域
,处理器在执行不可屏蔽中断(NMI)或HardFault处理时,MPU访问权限会被忽略。例如,可以将SRAM栈底的一小块SRAM空间定义为不可执行,将MPU用作栈溢出的检测机制。当栈到达边界的时候,HardFault可以忽略MPU限制并在错误的处理中使用预留的SRAM空间。
下面介绍MPU相关寄存器。
1.MPU类型寄存器
其可用于确定MPU是否存在,若DREGION区域读出为0,则表明MPU不存在。
(MPU->TYPE, 0xE000ED90)
位 | 名称 | 类型 | 复位值 | 描述 |
---|---|---|---|---|
23:16 | IREGION | R | 0 | 本MPU支持的指令区域数,由于ARM-v6M架构使用统一的MPU,其总数为0 |
15:8 | DREGION | R | 0或8 | MPU支持区域数 |
0 | SEPARATE | R | 0 | 由于MPU为统一的,其总为0 |
2.MPU控制寄存器
其有3个控制位,复位后,该寄存器数值为0,这样会禁止MPU。若要使能MPU,软件需要首先设置MPU区域,然后设置控制寄存器中的ENABLE位。
(MPU->CTRL, 0xE000ED94)
位 | 名称 | 类型 | 复位值 | 描述 |
---|