首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

存储器保护单元——基于ARM Cortex-M0技术

存储器保护单元——基于ARM Cortex-M0技术

存储器保护单元(MPU)是用来保护存储器的一个元件。Cortex-M0处理器支持标准的ARMv6  PMSA模型,具有以下功能:
(1)保护内存区域。
(2)将保护区域重叠。
(2)控制访问权限。
(3)将存储器属性输出到系统。
内存访问时,如果MPU不匹配或越权访问,将发生“内存管理错误(MemManage Fault Handler)”,激活存储器管理故障处理程序。表7-18所示为MPU相关寄存器。

表7-18  MPU相关寄存器



                                                                                       
名    称类    型地    址复  位  值
MPU类型寄存器只读0xE000ED900x00000800
MPU控制寄存器读/写0xE000ED940x00000000
MPU区号寄存器读/写0xE000ED98-
MPU区域基址寄存器读/写0xE000ED9C-
MPU区域属性与大小寄存器读/写0xE000EDA0-
MPU别名1区基址寄存器D9C重叠0xE000EDA4-
MPU别名1区属性与大小寄存器DA0重叠0xE000EDA8-
MPU别名2区基址寄存器D9C重叠0xE000EDAC-
MPU别名2区属性与大小寄存器DA0重叠0xE000EDB0-
MPU别名3区基址寄存器D9C重叠0xE000EDB4-
MPU别名3区属性与大小寄存器DA0重叠0xE000EDB8-
对MPU区域的编程,可通过对映射到内存的3个字寄存器的编程来实现。3个寄存器相互独立,程序可分开访问。MPU寄存器相互独立的特性,可以使用户方便地移植现有的ARMv6、ARMv7和CP15的代码,使Cortex-M3很容易地实现向后兼容。当移植ARMv6和CP15的现有代码时,只需使用LDRx和STRx操作代替MRC和MCR。
使用CP15等效代码更新MPU区域的代码实例如下:

R1 = region number
R2 = size/enable
R3 = attributes
R4 = address
MOV R0,#NVIC_BASE
ADD R0,#MPU_REG_CTRL
STR R1,[R0,#0] ;
STR R4,[R0,#4] ;
STRH R2,[R0,#8] ;
STRH R3,[R0,#10] ;
值得注意的是,如果中断在这期间可以抢占,那么它会受MPU区域的影响,即必须禁能、写然后再使能该区域。这对于上下文转换器通常没有太大用处,但是如果需要在其他地方进行更新,这就很有必要了。
MPU可以包含关键的数据,这是因为在更新时得花费一个以上的总线处理,通常是两个字,结果就不是“线程安全”了,即中断可以将两个字分离,使得区域包含不连续的信息。此时要注意以下两个问题。
(1)更新MPU通常会产生中断。这不仅是“读—修改—写”的问题,它还会对“保证中断程序不会修改相同区域”的情形造成影响。这是因为编程取决于正写入寄存器的区号,所以它知道要更新哪个区。因而这种情形下每个更新程序周围都必须禁能中断。
(2)使用域操作更新MPU会产生中断,该中断将使正在更新的区域受到影响,因为只有基址或“大小域”被更新。如果新的大小域发生了改变,但是基址没有变,那么基址 +new_size可能会在一个被另外区域正常处理的区域内重叠。
但是对于标准的OS上下文转换代码,将会改变用户区域,因为这些区域会被预设成用户特权和用户区地址,所以没有风险。也就是说即使是中断也不会产生副作用。因此不需要禁能/使能代码,也不需要禁止中断。
最普通的方法是只从两个位置对MPU进行编程:引导代码和上下文转换器。如果以唯一的两个位置进行编程,且上下文转换器仅更新用户区,那么因为上下文转换器已经是一个关键区域,且引导代码在禁能中断时运行,所以不需要禁能。
继承事业,薪火相传
返回列表