存储器保护单元
在嵌入式技术中,为了提高应用的稳定可靠性,微处理器通常都配置有内存管理单元(Memory Management Unit,MMU),用来合理、有效地管理系统中的存储器,这也是区分微处理器和微控制器的条件之一。ARM公司的ARM9、ARM10、ARM11以及ARM Cortex-A系列的处理器都带有MMU。在ARM Cortex-M3内核中选配了一个存储器保护单元(Memory Protection Unit,MPU),其作用是对存储器(主要是内存和外设寄存器)进行保护,从而使软件更加健壮、可靠。MPU具有如下功能,可以提高系统的可靠性。
(1)阻止用户应用程序破坏操作系统使用的数据。
(2)阻止一个任务访问其他任务的数据区,从而把任务隔开。
(3)可以把关键数据区设置为只读,从根本上消除数据被破坏的可能。
(4)检测意外的存储访问,如堆栈溢出、数组越界。
(5)可以通过MPU设置存储器片块的其他访问属性,如是否缓冲等。
1.MPU寄存器组织及描述
ARM Cortex-M3中的MPU寄存器有MPU类型寄存器(MPU Type Register,MPUTR)、MPU控制寄存器(MPU Control Register,MPUCR)、MPU区号寄存器(MPU Region Number Register,MPURNR)、MPU区域基址寄存器(MPU Regon Base Address Register,MPURBAR)、MPU区域属性与大小寄存器(MPU Region Attributc and Size Register,MPURASR)和MPU别名寄存器,如表1所示。
表1 MPU寄存器

1)MPU类型寄存器
MPU类型寄存器如表2所示,其地址为0xE000ED90。使用MPU类型寄存器可以查看MPU支持的区域数,读取位[15∶8]的内容可以判断是否存在MPU。
表2 MPU类型寄存器

2)MPU控制寄存器
MPU控制寄存器功能如下。
(1)使能MPU。
(2)使能默认时的存储器映射。
(3)在处于硬故障、NMI和FAUTMASK升级处理时使能MPU。
MPU控制寄存器如表3所示。
表3 MPU控制寄存器

在使能MPU时,为了运行MPU,除非PRIVDEFENA位置位,否则必须至少使能一个存储器映射区。如果PRIVDEFENA位置位而没有区域被使能,那么只能运行特权代码。
MPU禁止时,使用默认的地址映射,相当于没有MPU。
MPU使能时,只有系统分区和向量表装载总是可访问。其他区必须根据具体的区域以及PRIVDEFENA是否使能决定其是否可访问。
除非HFNMIENA置位,否则MPU在异常优先级为-1或-2时不能被使能。这些优先级仅在处于硬故障、NMI或当FAULTMASK使能时才存在。当HFNMIENA位和这两个优先级一起工作时,它用于使能MPU。
3)MPU区号寄存器
MPU区号寄存器如表4所示,它用于选择进行访问的保护区,然后写MPU区域基址寄存器或MPU属性与大小寄存器以对保护区的特性进行配置,其地址为0xE000ED98。
表4 MPU区号寄存器

4)MPU区域基址寄存器
MPU区域基址寄存器如表5所示。MPU区域基址寄存器用于写区域的基址。区域基址寄存器还含有REGION域,如果VALID置位,可以将它用于覆盖MPU区号寄存器中的REGION域。(https://www.daowen.com)
表5 MPU区域基址寄存器

区域基址寄存器为区域设置基址,按照大小对齐。一个64 KB大小的区域必须按64 KB的倍数对齐,如0x00010000、0x00020000等。
区读回的结果总是当前MPU的区号。VALID总是当作0读回。将VALID和REGION分别设成VALID=1和REGION=n时,区号将变为n。这是写MPU区号寄存器的一个快捷方法。
如果不是按字访问,那么寄存器将不可预测。
5)MPU区域属性与大小寄存器
MPU区域属性与大小寄存器如表6所示,其地址为0xE000EDA0。MPU区域属性与大小寄存器用于控制MPU的访问权限。该寄存器由两个局部寄存器组成,每个都是半字大小。可以使用单独的长度对这些寄存器进行访问,也可以使用字操作同时对它们进行访问。
表6 MPU区域属性与大小寄存器

续表

表7 MPU保护区域大小域

表6中的[15∶8]位提到了“子区”的概念。由于8个区的定义区域较大,所以系统允许把每个区的内部进一步划分成更小的块,这就是子区。子区的使用有一定的限制:每个区必须等分为8个子区,而且所有子区的属性都与“父区”相同。每个子区可以独立地使能或禁止,SRD中的8个位,每个位控制一个子区是否被禁止,如SRD.3=0,则3号子区被禁止。若某个子区被禁止,且其对应的地址范围又没有落在其他区中,则对该子区覆盖范围的访问将引发错误。子区最小也要有256字节,若是对128字节或者是更小的区划分子区,则后果是不可预料的。
表6中的[26∶24]为AP位段,AP位段用于限定各种访问权限,这也是分区保护的重要组成部分。
表6中的位段[28]的名称是XN(eXecute Never),它决定在本区中是否允许取指。若不允许取指(清零),则任何指令预取都将触发存储器管理异常。其作用是可以把新得到的还不受信任的代码先存储到此区,待经过身份鉴定后,再允许执行。
表6中的[21∶16]位段中TEX、S、B和C对应着存储系统中比较高级的操作。ARM Cortex-M3中没有缓存,是以v7-M的架构设计的,而v7-M支持外部缓存以及更先进的存储器系统。按照v7-M的规格说明,可以通过对这些位段的编程,来支持多样的内存管理模型。TEX、C、B位段组合的详细功能如表8所示。
表8 TEX、C、B位段组合的详细功能

表8中,当TEX=1 BB时,若该区是片内存储器,则由C和B决定其缓存属性(AA);若是片外存储器,则由TEX的[1∶0]决定其缓存属性(BB)。不管是AA还是BB,每个数值的含义都是相同的。缓存方针编码如表9所示。
表9 缓存方针编码

2.MPU的应用
ARM Cortex-M3中的MPU可定义8个内存区,每个区都有一个基址(对应MPURBAR)、一个大小(对应MPURASR中的[5∶1]位)以及相应的属性(对应MPURASR)。其中,区的大小为2的幂次方,范围为32字节~4 GB(包括32字节和4 GB)。区的基址必须对齐区的大小。一个区可以允许或不允许有代码执行体。对于特权模式和用户模式,区能被设置成只读访问、读/写访问或无访问权。每个区内还可创建8个子区。一旦区已定义并且MPU使能,对区进行任何一个非法访问将会导致一个内存管理故障,并且故障处理程序将会被激活。
在ARM Cortex-M3中,MPU的管理实际上是对存储器映射中的区域进行管理,MPU在ARM Cortex-M3中的管理区域如表10所示。
表10 MPU在ARM Cortex-M3中的管理区域

例如,有一应用项目要求对代码区的特权级代码8 MB(0x0000_0000~0x008F_FFFF)全访问,可缓存;对SRAM区的特权级数据64 KB(0x2000_0000~0x2000_FFFF)全访问,可缓存;对片上外设区512 MB(0x4000_0000~0x5 FFF_FFFF)全访问,共享设备;对系统私有区1 MB(0xE000_0000~0xE00F_FFFF)特权级访问,严格按顺序,程序如下。


