3. MPU核心寄存器详解:SPROT、DPROT、GPR、LPR寄存器组

好,咱们进入正题。MPU的配置,说白了就是跟这几个寄存器打交道。你想想看,CPU要访问内存,总得有个「交通规则」吧?SPROT、DPROT、GPR、LPR就是制定规则的那几张纸。我刚开始接触TC3xx时,对着寄存器手册看了三天,头都大了。后来发现,其实核心就四个寄存器组,搞懂了它们,MPU也就通了八成。

3.1 SPROT寄存器——代码区的「守门员」

SPROT,全称是代码段保护寄存器。它管的是指令读取,也就是CPU取指令时的访问权限。

我个人习惯,先把SPROT分成两部分看:

  • SPROT_ACCENx:使能位。你得先告诉MPU,「嘿,我要对这段代码区做保护了」。否则配置了也白搭。
  • SPROT_APx:权限位。读?执行?还是读写都行?这里定。

举个例子,假设你想保护0x80000000开始的64KB代码区,只允许CPU读和执行,不允许写。配置大概是这样的:

// 伪代码示意
SPROT_ACCEN0.B.ENABLE = 1;   // 使能保护
SPROT_AP0.B.AP = 0b10;       // 只读+执行,不可写
SPROT_ADDR0.B.ADDR = 0x8000; // 起始地址(高16位)
SPROT_MASK0.B.MASK = 0xFF;   // 64KB范围

嗯,这里要注意:地址对齐要求很严格。起始地址必须是保护区域大小的整数倍。我在项目中遇到过有人把起始地址写成了0x80000100,结果MPU直接罢工,CPU跑飞了。排查了半天才发现是地址没对齐。

避坑指南:我曾经在一个Bootloader项目中,因为SPROT配置错误,导致跳转到APP时触发Trap。后来发现是SPROT的使能位没有在修改地址前关闭。记住:改地址前先清使能,改完再开

3.2 DPROT寄存器——数据区的「安检员」

DPROT跟SPROT长得几乎一模一样,但管的是数据访问。说白了,就是CPU读写数据时的权限控制。

你想想看,如果某个关键数据区(比如系统配置参数)被意外篡改,后果可能很严重。DPROT就是干这个的——谁可以读,谁可以写,全由它说了算。

DPROT的寄存器结构:

寄存器 功能 位宽
DPROT_ACCENx 使能控制 32位
DPROT_APx 访问权限(读/写/无) 2位
DPROT_ADDRx 保护区域起始地址 16位(高地址位)
DPROT_MASKx 区域大小掩码 16位

我建议你把DPROT和SPROT当成一对兄弟来记。一个管指令,一个管数据。配置方法几乎一样,只是应用场景不同。

3.3 GPR寄存器——全局的「总闸」

GPR,全局保护寄存器。它不直接定义某个区域的权限,而是控制MPU的全局行为

GPR里最重要的几个位:

  • PROTEN:MPU总使能。关了它,所有保护都失效。调试时常用。
  • SPROTEN:代码保护使能。单独开关代码保护。
  • DPROTEN:数据保护使能。单独开关数据保护。
  • LOCK:锁定位。一旦置1,MPU配置就不能再改了。产品发布前记得锁上。

我记得有一次,客户反馈说设备在运行中突然失去保护。查了半天,发现是某个中断服务程序里不小心把GPR的PROTEN位清零了。从那以后,我写代码时都会在MPU初始化最后加上LOCK操作。

小技巧:调试阶段别急着LOCK。我习惯先用PROTEN做全局开关,等所有功能验证通过后,再在最终版本里加上LOCK。这样既安全又灵活。

3.4 LPR寄存器——本地的「分闸」

LPR,本地保护寄存器。它跟GPR的区别在于:GPR是全局的,LPR是每个CPU核心独立的。

TC3xx是多核架构,每个核都有自己的LPR。这意味着你可以给Core0开一个权限,给Core1关掉。这在多核系统中非常实用。

LPR的核心字段:

  • LPR_ACCENx:本地使能位
  • LPR_APx:本地权限位
  • LPR_ADDRx:本地地址范围
  • LPR_MASKx:本地掩码

说白了,LPR就是每个核自己的「小MPU」。你可以用它来隔离不同核之间的数据访问。比如Core0的堆栈区,Core1不能碰。这在功能安全项目中是标配。

为什么会这样设计?你想想看,如果所有核共享一套保护规则,那一个核的配置错误就可能影响整个系统。LPR的存在,让每个核都能「自扫门前雪」。

核心总结:
  • SPROT:管代码(指令读取)
  • DPROT:管数据(读写访问)
  • GPR:全局总开关,控制MPU整体行为
  • LPR:每个核自己的本地保护,实现核间隔离
配置顺序:先配SPROT/DPROT定义区域,再配GPR开总闸,最后用LPR做核间微调。

嗯,这四个寄存器组搞明白了,MPU的骨架就有了。下一节咱们会讲怎么用它们搭出实际的内存保护方案。到时候我会拿一个真实的汽车ECU项目做例子,手把手带你配一遍。