【ARM CM3微控制器--内存管理单元(MMU)】

本文介绍了Cortex-M3处理器中的MemoryProtectionUnit(MPU)功能,包括内存区域划分、权限控制、粒度管理和硬件支持的内存隔离。重点讲解了MPU_Initialize和MPU_ConfigRegion函数的使用,展示了如何通过这些函数实现内存区域的访问权限设置和保护。
摘要由CSDN通过智能技术生成

目录

一 Memory Protection Unit (MPU) 功能概述:

二 MPU_Initialize函数介绍

三 MPU_ConfigRegion函数介绍


在ARM Cortex-M3(CM3)微控制器中,实际上并没有传统的内存管理单元(MMU)。但是,CM3提供了Memory Protection Unit(MPU),它是MMU的一个轻量级替代方案,用于实现简单的内存保护和分区功能。

一 Memory Protection Unit (MPU) 功能概述:

  1. 内存区域划分:MPU允许开发者将系统内存划分为多个不同的区域(Regions),并对每个区域设置不同的访问权限(读/写/执行)。

  2. 权限控制:每个内存区域可以配置为只读、只写或可读写,也可以完全禁止访问,从而实现对不同任务或中断服务程序访问内存的权限控制,增强系统的安全性。

  3. 粒度管理:Cortex-M3的MPU支持不同的粒度,可以按照区域大小进行划分,例如可以选择整个内存区域,或者按照较小的区块进行管理。

  4. 硬件支持内存隔离:通过MPU,可以在不同的任务之间实现内存隔离,防止一个任务无意或恶意修改另一个任务的数据。

实例说明:

; 假设我们想为Cortex-M3设置一个只读的内存区域,该区域从地址0x20000000开始,大小为4KB

; 首先,需要初始化MPU
MPU_Initialize();

; 然后,配置一个新的内存区域
MPU_SetRegionNum(0);    ; 选择区域编号
MPU_ConfigRegion(0x20000000, 4*1024, MPU_REGION_READ_ONLY);  ; 地址、大小和权限

; 启用MPU
MPU_Enable(MPU_PRIVILEGED_DEFAULT);  ; 启用MPU,并设置默认的访问权限(例如,特权模式)

; 之后,当尝试在非特权模式下对0x20000000开始的4KB内存区域进行写操作时,将触发总线错误异常(BusFault)。

这段代码是一个简化的示例,表明了如何使用MPU来保护一段内存区域使其变为只读。在实际应用中,程序员需要使用CMSIS(Cortex Microcontroller Software Interface Standard)或特定微控制器供应商提供的库函数来操作MPU。

由于Cortex-M3并不支持虚拟内存和地址转换,所以MPU并不负责虚拟地址到物理地址的转换,其主要关注的是物理内存的保护和隔离。在更高级别的ARM架构(如Cortex-A系列)中,才会有支持完整地址转换和页面替换机制的MMU。

二 MPU_Initialize函数介绍

`MPU_Initialize` 是一个用于初始化内存保护单元(MPU)的函数。在基于 ARM Cortex-M 处理器的嵌入式系统中,特别是 STM32 系列微控制器中,MPU 可以帮助实现对内存区域的访问权限控制,防止非法或意外的内存访问导致系统不稳定或数据泄露。

`MPU_Initialize` 函数通常由芯片厂商提供的 SDK 或 CMSIS 库提供,其主要作用是:

1. 关闭所有已配置的 MPU 区域,清空所有 MPU 寄存器的设置。
2. 设置 MPU 的基础配置,如启用 MPU、设置异常响应方式等。
3. 为后续对 MPU 区域的配置做好准备。

下面是一个简化的 `MPU_Initialize` 函数调用示例(基于 STM32 Cube HAL 库的风格):


void MPU_Initialize(void) {
    HAL_MPU_Disable(); // 关闭 MPU,清除所有之前的配置

    // 设置 MPU 控制寄存器的属性,例如是否启用 MPU,异常响应方式等
    MPU_CTRL_Type MPU_Ctrl;
    MPU_Ctrl.Enable = MPU_ENABLE;
    MPU_Ctrl.HFNMIENA = MPU_HFNMI_PRIVDEF_DISABLE; // HFNMI 异常情况下保持特权模式默认内存映射
    MPU_Ctrl.PrivilegeDefault = MPU_PRIVILEGED_DEFAULT_DISABLE; // 非特权模式下默认关闭内存访问
    MPU_Ctrl.HardFaultNMI = MPU_HARDFAULT_NMI_DISABLE; // 硬故障和 NMI 不影响 MPU

    HAL_MPU_ConfigCtrl(&MPU_Ctrl); // 应用 MPU 控制寄存器的设置

    HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT); // 启用 MPU,设置默认的访问权限(例如,特权模式)
}

在实际应用中,调用 `MPU_Initialize` 函数是配置 MPU 的第一步,初始化完成后,就可以通过类似 `MPU_ConfigRegion` 的函数进一步配置内存区域的访问权限。

三 MPU_ConfigRegion函数介绍

`MPU_ConfigRegion` 是一个抽象函数名,通常在基于 ARM Cortex-M 内核的微控制器(如 STM32 系列)中用于配置内存保护单元(MPU)的一个内存区域。这个函数通常由芯片厂商提供的 SDK 或 CMSIS 库提供,用于设置 MPU 的各个区域属性,如基地址、大小、访问权限等。

下面是一个简化的 `MPU_ConfigRegion` 函数调用示例(基于 STM32 Cube HAL 库的风格):


#define REGION_NUMBER 0
#define START_ADDRESS 0x20000000
#define SIZE_BYTES 4096
#define ACCESS_PERMISSION MPU_REGION_FULL_ACCESS

void MPU_ConfigRegion(uint32_t Mem_Rgn, uint32_t BaseAddress, uint32_t Size, uint32_t AccessPermission) {
    MPU_Region_InitTypeDef MPU_Init;

    MPU_Init.Enable = MPU_REGION_ENABLE;
    MPU_Init.Number = Mem_Rgn; // 区域编号
    MPU_Init.BaseAddress = BaseAddress; // 区域起始地址
    MPU_Init.Size = MPU_REGION_SIZE_4KB; // 区域大小,这里假设为4KB
    MPU_Init.AccessPermission = AccessPermission; // 访问权限设置

    // 根据实际需求配置其他属性,如缓冲特性、缓存特性、共享属性等

    HAL_MPU_ConfigRegion(&MPU_Init); // 调用HAL库函数实际配置MPU区域
}

// 使用示例
void Configure_MPU(void) {
    MPU_ConfigRegion(REGION_NUMBER, START_ADDRESS, SIZE_BYTES, ACCESS_PERMISSION);
}

在这个示例中,`MPU_ConfigRegion` 函数接受四个参数:

1. `Mem_Rgn`: 要配置的MPU区域编号。
2. `BaseAddress`: 配置的内存区域的起始地址。
3. `Size`: 配置的内存区域的大小,通常是以字节为单位。
4. `AccessPermission`: 配置的内存区域的访问权限,可以是只读、读写、执行等各种组合。

实际调用该函数时,会根据传入的参数设置对应的 MPU 区域属性,然后通过 HAL 库函数 `HAL_MPU_ConfigRegion` 将这些属性配置到 MPU 控制器中。

  • 10
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值