ARM Cortex-M MPU的保护设置

ARM Cortex-M 内存保护单元(MPU)

MPU 的作用

MPU 可以将内存划分为不同的区域,并且可以设置每个区域的访问属性。提高系统的稳定性。典型应用如下:
 划分特权用户访问区域和普通用户访问区域,在 OS 系统中提高系统稳定性。
 设置只读区域,防止关键数据被意外修改。
 检测堆、栈是否溢出。

MPU 相关寄存器

  • 寄存器

寄存器名-------------- 类型 ----复位值 ----------寄存器功能描述
MPU_TYPE-----------RO --------------------------MPU 类型寄存器
MPU_CTRL --------- RW — 0x00000000------MPU 控制寄存器
MPU_RNR -----------RW — UNKNOWN-------MPU 区域号寄存器(region 号)
MPU_RBAR ---------RW — UNKNOWN-------MPU 区域基地址寄存器
MPU_RASR--------- RW — UNKNOWN-------MPU 区域属性和大小寄存器
MPU_RBAR_A1 — RW---------------------------MPU_RBAR 的别名 1
MPU_RASR_A1 ----RW---------------------------MPU_RASR 的别名 1
MPU_RBAR_A2 ----RW ---------------------------MPU_RBAR 的别名 2
MPU_RASR_A2 ----RW--------------------------- MPU_RASR 的别名 2
MPU_RBAR_A3 ----RW ---------------------------MPU_RBAR 的别名 3
MPU_RASR_A3 ----RW -------------------------- MPU_RASR 的别名 3

  • 区域基地址寄存器(MPU_RBAR)

名称-------位段 功能描述
ADDR------bits[31:5]–区域的基地址
VALID------bit[4]-------决定 REGION 字段设置的区域编号是否覆盖 MPU_RNR 寄存器设置的区域 编号
REGION—bits[3:0]—MPU 区域编号复写字段

该寄存器提供了另外一种改变区域编号方法,即 REGION = 区域编号,VALID = 1。
使用这种方法设置区域编号更快捷。ADDR,保存区域基地址.

注意点:地址不能是任意地址.
在这里插入图片描述
代码:

/* 设置的地址,直接把底5bit给清零处理. 并且还会根据保护区域的大小还会进一步处理. 
The ADDR field
The ADDR field is bits[31:N] of the MPU_RBAR. The region size, as specified by the SIZE 
field in the MPU_RASR, defines the value of N:
N = Log2(Region size in bytes).
If the region size is configured to 4GB, in the MPU_RASR, there is no valid ADDR field. In 
this case, the region occupies the complete memory map, and the base address is 0x00000000.
The base address is aligned to the size of the region. For example, a 64KB region must be 
aligned on a multiple of 64KB, for example, at 0x00010000 or 0x00020000.
 */
#define MPU_RBAR_ADDR_Pos                   5U                                            /*!< MPU RBAR: ADDR Position */
#define MPU_RBAR_ADDR_Msk                  (0x7FFFFFFUL << MPU_RBAR_ADDR_Pos)             /*!< MPU RBAR: ADDR Mask */

#define ARM_MPU_RBAR(Region, BaseAddress) \
  (((BaseAddress) & MPU_RBAR_ADDR_Msk) |  \
   ((Region) & MPU_RBAR_REGION_Msk)    |  \
   (MPU_RBAR_VALID_Msk))
  • 区域属性和大小寄存器(MPU_RASR)
    在这里插入图片描述
#define ARM_MPU_RASR(DisableExec, AccessPermission, TypeExtField, IsShareable, IsCacheable, IsBufferable, SubRegionDisable, Size) \
  ((((DisableExec     ) << MPU_RASR_XN_Pos)     & MPU_RASR_XN_Msk)     | \
   (((AccessPermission) << MPU_RASR_AP_Pos)     & MPU_RASR_AP_Msk)     | \
   (((TypeExtField    ) << MPU_RASR_TEX_Pos)    & MPU_RASR_TEX_Msk)    | \
   (((IsShareable     ) << MPU_RASR_S_Pos)      & MPU_RASR_S_Msk)      | \
   (((IsCacheable     ) << MPU_RASR_C_Pos)      & MPU_RASR_C_Msk)      | \
   (((IsBufferable    ) << MPU_RASR_B_Pos)      & MPU_RASR_B_Msk)      | \
   (((SubRegionDisable) << MPU_RASR_SRD_Pos)    & MPU_RASR_SRD_Msk)    | \
   (((Size            ) << MPU_RASR_SIZE_Pos)   & MPU_RASR_SIZE_Msk)   | \
   (MPU_RASR_ENABLE_Msk))
举例:给内存的256byte区域设置只读属性
	/*全局变量如果是需要 需要做对齐,
	N = Log2(Region size in bytes) = Log2(256) = 8 :代表底8位是清零.也就是对齐256,
	不然开始地址和保护区域地址不一致,会影响其他内存变量
	*/
	__align(256)  char g_xxx_test[256];
	
    /* Memory with Normal type, not shareable, non-cacheable */
    MPU->RBAR = ARM_MPU_RBAR(8, g_xxx_test);
    MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 1, 0, 0, 0, 0, ARM_MPU_REGION_SIZE_256B);

    /* 是能MPU */
    ARM_MPU_Enable(MPU_CTRL_PRIVDEFENA_Msk);
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值