Cortex-R52 MPU学习总结
1. MPU 相关基础
内存保护单元(MPU)是 Cortex-R52 中用于管理内存访问权限和属性的硬件模块。它通过划分内存区域来工作,每个区域最小为 64 字节,并且起始地址必须对齐到其大小的整数倍(例如,一个 64 字节的区域必须从一个能被 64 整除的地址开始)。对齐要求就像整理书架时规定每本书必须从固定的格子开始摆放,这样系统才能快速、准确地找到和管理这些内存区域,否则可能导致硬件错误或性能下降。
1.1. 4.1. R52 内存模型功能支持
Cortex-R52 的内存模型有若干关键特性,这些特性深刻影响着系统设计和编程:
-
共享性与缓存的强制规则:为了在无硬件缓存一致性的多核系统中保证数据安全,任何被标记为 Inner Shareable(集群内共享)或 Outer Shareable(集群间共享)的内存区域,其数据访问都会强制绕过缓存,变为不可缓存(Non-cacheable)。这就像在团队协作中,所有需要共享给团队成员的文件都必须放在公共公告板上,而不是个人的抽屉里,确保每个人看到的都是最新版本,避免了数据不一致的风险。
-
不支持快速上下文切换(FCSE):Cortex-R52 作为实时处理器,优先考虑确定性和简单性,因此不支持 FCSE 这一用于加速任务切换的功能。这意味着任务切换的延迟可能稍高,但系统行为更可预测。
-
辅助寄存器支持:Cortex-R52 提供了一组用于深度调试和系统控制的辅助寄存器,它们是系统工程师的“诊断工具”。
- Auxiliary Fault Status Registers (AIFSR 和 ADFSR):当处理器遇到指令获取错误(AIFSR)或数据访问错误(ADFSR)时,这些寄存器会记录详细的错误原因。例如,当 DMA 控制器试图访问一个未配置权限的内存区域而触发总线错误时,工程师可以通过读取 ADFSR 来定位问题根源。
- Auxiliary Control Register (ACTLR):这是一个权限寄存器(通常在 EL1 或 EL3 级别才能访问),用于微架构行为控制,例如调整缓存策略、预取器行为或多核交互。一个典型应用是禁用特定核心的 L2 缓存预取功能,以在特定工作负载下降低功耗。
-
受限的 PMSA 架构:Cortex-R52 采用受保护的存储器系统架构(PMSA),它不支持虚拟内存(这与 MMU 的 VMSA 不同),而是通过 MPU 实现物理内存的保护,架构更简单,非常适合实时嵌入式系统。
-
支持 TCM 及相关 DMA:TCM 是一种紧耦合内存,具有低延迟、高带宽的特性,常用于存储关键代码和数据。Cortex-R52 支持 TCM 并且能够与 DMA 控制器高效协作,例如,DMA 可以将传感器数据直接写入 TCM,然后 CPU 核心能够极速处理这些数据。
-
两级共享等级:共享性分为两个层级,Inner Shareable 通常指在一个处理器集群内部(例如,同一芯片上的多个 R52 核心)之间的共享;Outer Shareable 范围更广,指在不同集群之间(例如,系统中多个芯片)的共享。在 R52 中,无论哪个级别的共享,都会触发上述的不可缓存强制规则。
1.2. 4.2. MPU 寄存器详解
MPU 的功能通过一系列寄存器进行配置,理解它们是进行内存保护编程的关键。
-
MPU 的启用与背景区域:MPU 的全局开关由系统控制寄存器(SCTLR)的 M 位控制。当 SCTLR.M=0,MPU 被禁用,此时系统会使用 EL1 控制的 MPU 背景区域作为默认内存映射,这相当于一个“安全网”,定义了未受 MPU 明确管理的内存区域的属性。当 MPU 启用(SCTLR.M=1) 后,还可以通过设置 SCTLR.BR 位来单独启用或禁用这个背景区域。
-
MPU 区域数量:系统支持的 MPU 区域数量(即可配置的内存保护区块数)是一个硬件特性,可以从 MPU Type 寄存器中读取。
-
EL2 Hypervisor 支持:对于支持虚拟化的场景,EL2 级别的 MPU 是可选的。如果实现,其相关配置寄存器为 HPRBAR(Hypervisor Physical Region Base Address Register)和 HPRLAR(Hypervisor Physical Region Limit Address Register)。在 Hypervisor 模式下,一次内存访问会同时检查 EL1 和 EL2 的 MPU 区域设置,两者共同决定最终的访问权限和内存属性。
-
区域配置寄存器(以 EL1 为例):每个 MPU 区域通过一对寄存器定义:
- PRBAR(区域基址寄存器):
- SH 字段:控制内存区域的共享性(Shareable)。对于普通内存,一旦设置为共享,该区域即被强制为不可缓存。
- AP 字段:控制访问权限(Access Permission),定义在 EL1(操作系统)和 EL0(应用程序)特权等级下是否可读、可写。
- XN 字段:控制是否可执行(eXecute Never)。设置为 1 可防止在该区域执行代码,有效抵御某些代码注入攻击。
- PRLAR(区域限界寄存器):
- AttrIndx 字段:这是一个索引值,用于选择 MAIR(Memory Attribute Indirection Register) 寄存器中的属性配置。MAIR 寄存器可以看作一个“属性模板库”,提供了 8 个(attr0 到 attr7)可编程的内存属性槽。
- EN 位:区域启用位。只有设为 1,该 MPU 区域的配置才生效。
- PRBAR(区域基址寄存器):
1.3. 4.3. 内存属性深度解析
内存属性决定了处理器访问内存时的微观行为,如缓存策略、排序要求等。Cortex-R52 在此有特殊规定。
2. 4.3.1. Cortex-R52+ 内存属性核心行为要点
- 数据缓存策略强制为 Write-Through(直写):这是 R52 的一个关键特性。无论软件在属性中配置为 Write-Back(回写)还是其他,实际的内存访问行为都是 Write-Through。这意味着数据写入时会同时更新缓存和主内存,保证了数据的实时一致性,简化了多核数据共享的处理,但可能比 Write-Back 模式性能稍低。
- Shareable 属性强制为 Non-cacheable:如前所述,标记为 Inner 或 Outer Shareable 的内存区域会被强制当作 Non-cacheable 处理,所有访问直接到达内存,这是保证多核数据一致性的核心机制。
- Transient 提示被忽略:Transient 属性用于提示某次访问是临时的、可能不会重用,但 Cortex-R52 忽略所有 Transient 提示,统一按 Non-transient 处理。
- 非一致性架构:Cortex-R52 的各个核心的缓存之间没有硬件自动维护一致性,因此对共享数据的软件管理要求更高。
3. 4.3.2. 属性编码与实际行为
内存属性编码分为外层(Outer)和内层(Inner)属性,但对于 Cortex-R52 的实时应用场景,许多配置的实际行为被简化或强制改变。
3.1. Device 内存类型(用于访问外设寄存器)
当外层属性编码为 0000 时,内存类型为 Device。其内层编码决定了访问设备的严格程度,这对于外设的正确操作至关重要。
| 内层编码 | Device 类型 | 严格程度 | 实际行为(对寄存器的操作) | 典型使用场景 |
|---|---|---|---|---|
0b0000 |
nGnRnE | 最严格 | 无合并、无重排序、无提前写确认 | 中断控制器、系统关键控制寄存器 |
0b0100 |
nGnRE | 较严格 | 无合并、无重排序、有提前写确认 | UART、SPI、定时器等普通外设 |
0b1000 |
nGRE | 较宽松 | 无合并、有重排序、有提前写确认 | 帧缓冲区、DMA 描述符表 |
0b1100 |
GRE | 最宽松 | 有合并、有重排序、有提前写确认 | 大块内存映射 IO 区域 |
- 名词解释:
- 聚集(Gathering):将多个小访问合并成一次大访问。
- 重排序(Reordering):改变内存访问的先后顺序。
- 提前写确认(Early-acknowledge):在写入操作实际完成前就通知处理器完成。
3.2. Normal 内存类型(用于普通数据内存)
当外层属性编码不为 0000 时,内存类型为 Normal。下表展示了配置值与 Cortex-R52 实际行为的差异。
外层/内层属性编码与实际行为对照
| 配置的编码 | 软件配置的类型 | Cortex-R52+ 实际行为 | 说明 |
|---|---|---|---|
0b00RW (RW≠00) |
Write-Through Transient | 实际为 Write-Through,Transient 被忽略 | |
0b0100 |
Non-Cacheable | Non-Cacheable | |
0b01RW (RW≠00) |
Write-Back Transient | 实际为 Write-Through,Transient 被忽略 | Write-Back 配置被强制转换 |
0b10RW |
Write-Through Non-transient | Write-Through Non-transient | |
0b11RW |
Write-Back Non-transient | 实际为 Write-Through Non-transient | Write-Back 配置被强制转换 |
R/W 分配策略编码 此策略控制当缓存未命中时,是否为读(R)或写(W)操作分配缓存行。
| R/W 值 | 含义 | 实际效果 |
|---|---|---|
| R=0, W=0 | 读写都不分配 | 直接访问内存,不占用缓存空间 |
| R=0, W=1 | 读不分配,写分配 | 仅当写入数据且不在缓存时,才将其载入缓存 |
| R=1, W=0 | 读分配,写不分配 | 仅当读取数据且不在缓存时,才将其载入缓存 |
| R=1, W=1 | 读写都分配 | 只要访问的数据不在缓存,就将其载入缓存 |
4. 4.3.3. 配置指南与决策流程
4.1. 推荐配置场景
-
私有数据(单核心访问):
- 配置:Non-Shareable + Write-Through + 合适的 R/W 分配。
- 场景:核心内部的局部变量、临时计算数据。
- 策略建议:频繁读写的小数据用
R=1, W=1;读多写少的数据用R=1, W=0。
-
共享数据(多核心/DMA 访问):
- 配置:Shareable(自动变为 Non-cacheable)。
- 场景:核心间通信缓冲区、DMA 数据区。
- 说明:这是最简单且安全地保证数据一致性的方法。
-
设备寄存器:
- 配置:Device 内存类型(根据外设要求选择 nGnRnE, nGnRE 等)。
- 场景:外设控制/状态寄存器。
- 原则:对顺序敏感的关键寄存器用 nGnRnE;对顺序要求不高的普通外设可用 nGnRE。
-
代码段:
- 配置:Non-Shareable + Write-Through + R=1, W=0。
- 场景:程序代码、常量数据。
- 说明:利用缓存加速指令读取(R=1),由于代码通常不写入,故 W=0。
-
流式数据处理:
- 配置:Non-Shareable + Write-Through + R=0, W=0。
- 场景:处理大型数据块、一次性 DMA 传输缓冲区。
- 说明:避免被只使用一次的数据“污染”缓存,提升缓存效率。
4.2. 配置决策流程
初学者可以遵循以下步骤来配置内存属性:
- 是否需要共享? 如果该内存区域会被多个核心或 DMA 访问 → 标记为 Shareable(它将自动变为 Non-cacheable,一致性得到保证)。如果否 → 进入下一步。
- 是否是设备内存? 如果该区域是映射的外设寄存器 → 选择合适严格程度的 Device 类型。如果否 → 配置为 Normal 内存。
- 选择分配策略:根据对该 Normal 内存区域的访问模式(读多还是写多)来选择合适的 R/W 位。请记住:Transient 属性可忽略,且任何 Write-Back 配置都无效。
5. 4.3.4. nGnRnE 深度解读
nGnRnE 是 ARM 架构中用于描述设备内存行为的最严格类型,其名称中的每个字母都代表一个限制:
- nG (No Gathering):不允许事务合并。多个对同一设备的访问不能合并为一次更大的传输。
- nR (No Reordering):不允许事务重排序。对该设备的访问必须严格按照程序代码的顺序执行。
- nE (No Early-acknowledge):不允许提前确认。写操作必须在该操作确实在设备端完成之后,才能向处理器发送“完成”信号。
应用场景:nGnRnE 用于访问那些对操作顺序极其敏感的设备寄存器,例如中断控制器和系统关键控制寄存器。确保一个“开启”指令绝对在“配置”指令之后执行,是系统稳定性的基石。在 ARMv7 架构中,它对应于 Strongly Ordered 内存类型。
更多推荐


所有评论(0)