在ARMv7架构中,Protected Memory System Architecture (PMSA)提供了一套完整的系统控制寄存器机制,用于管理处理器的内存保护功能。与VMSA(虚拟内存系统架构)不同,PMSA采用基于区域的保护机制而非页表转换,特别适合对实时性要求高的嵌入式系统。
PMSAv7的系统控制寄存器通过协处理器CP15进行访问,采用统一的编码格式:
这些寄存器按功能可分为以下几组:
PMSAv7的MMU控制寄存器组包含以下关键寄存器:
SCTLR(System Control Register)
DRBAR/IRBAR(数据/指令区域基址寄存器)
DRSR/IRSR(数据/指令区域大小寄存器)
DRACR/IRACR(数据/指令区域访问控制寄存器)
配置一个内存区域的完整流程:
assembly复制; 设置区域编号
MRC p15, 0, r0, c6, c2, 0 ; 读取RGNR
ORR r0, r0, #0x1 ; 选择区域1
MCR p15, 0, r0, c6, c2, 0 ; 写回RGNR
; 配置数据区域
LDR r0, =0x20000000 ; 基地址32MB对齐
MCR p15, 0, r0, c6, c1, 0 ; 写入DRBAR
LDR r0, =0x0000001F ; 大小64MB, 启用区域
MCR p15, 0, r0, c6, c1, 2 ; 写入DRSR
LDR r0, =0x0000030D ; TEX=0b001, C=1, B=1, AP=011(PL1 RW/PL0 RO)
MCR p15, 0, r0, c6, c1, 4 ; 写入DRACR
关键点:配置区域时必须确保基地址与大小对齐,否则会导致UNPREDICTABLE行为。实际项目中建议使用CMSIS提供的封装接口来简化配置。
当发生内存访问异常时,处理器会更新以下寄存器:
DFSR/IFSR(数据/指令故障状态寄存器)
DFAR/IFAR(数据/指令故障地址寄存器)
ADFSR/AIFSR(辅助故障状态寄存器)
典型的异常处理程序框架:
c复制void DataAbort_Handler(void)
{
uint32_t dfsr, dfar;
// 读取故障寄存器
__asm volatile("MRC p15, 0, %0, c5, c0, 0" : "=r"(dfsr));
__asm volatile("MRC p15, 0, %0, c6, c0, 0" : "=r"(dfar));
// 解析故障类型
switch(dfsr & 0xF) {
case 0x1:
printf("对齐错误 @0x%08X\n", dfar);
break;
case 0x5:
printf("背景错误 @0x%08X\n", dfar);
break;
case 0xD:
printf("权限错误 @0x%08X\n", dfar);
break;
default:
printf("未知错误类型\n");
}
// 清除故障状态(如果需要)
__asm volatile("MCR p15, 0, %0, c5, c0, 0" :: "r"(dfsr));
}
PMSAv7提供丰富的缓存维护指令,主要分为以下几类:
按地址操作
按组/路操作
全缓存操作
assembly复制; 假设要DMA传输地址范围0x20000000-0x20001000
MOV r0, #0x20000000
MOV r1, #0x20001000
clean_loop:
MCR p15, 0, r0, c7, c10, 1 ; DCCMVAC - 清理指定地址
ADD r0, r0, #32 ; 缓存行大小(通常32字节)
CMP r0, r1
BLO clean_loop
DSB ; 确保操作完成
c复制void context_switch(void)
{
// 使所有指令缓存无效
__asm volatile("MCR p15, 0, %0, c7, c5, 0" :: "r"(0));
// 使分支预测无效
__asm volatile("MCR p15, 0, %0, c7, c5, 6" :: "r"(0));
// 数据同步屏障
__asm volatile("DSB");
__asm volatile("ISB");
}
区域配置策略
缓存优化
对齐错误
权限错误
缓存一致性问题
c复制void set_task_id(uint32_t id)
{
__asm volatile("MCR p15, 0, %0, c13, c0, 1" :: "r"(id));
}
assembly复制; 配置性能计数器
MOV r0, #0x11 ; 选择L1数据缓存访问事件
MCR p15, 0, r0, c9, c12, 5 ; 写入事件选择寄存器
MOV r0, #0x1 ; 启用计数器0
MCR p15, 0, r0, c9, c12, 1
在实时操作系统中,合理配置PMSAv7寄存器可以显著提升系统可靠性和性能。实际项目中建议结合RTOS提供的抽象层进行配置,同时注意不同ARM核之间的实现差异。通过仔细分析故障状态寄存器和使用性能监控功能,可以快速定位和解决复杂的内存相关问题。