S32K14x - MPU

本文详细阐述了S32K14x单片机中的MPU内存保护单元的工作原理,包括MPU模块的结构、AccessEvaluationMacro的判断流程、地址权限管理和遗留问题的解决方案。通过实例和S32DS库,展示了如何配置和使用MPU以确保系统的安全运行。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

S32K14x - MPU

1. 前言

MPU(Memory Protection Unit),用于内存保护。现在很多的产品使用了操作系统,有宏内核、微内核、混合内核等设计,因此对于内存保护极为重要。在运行APP的时候,如果不小心篡改了内核数据,则会导致系统瘫痪,APP与APP之间如果篡改了数据,也有可能让APP不能正常运行。想象一下,如果此时你动态地安装一个APP到你的单片机中,这个APP中存在野指针的访问操作,那么当你这个APP加载成功并运行的时候,一访问这个野指针,那么整个系统就瘫痪了,我们可不能让一颗"老鼠屎"坏了一锅粥,因此使用MPU内存保护单元来限制这些非法的内存操作,将内存划分设置访问权限,当某个APP出现非法操作的时候,我们就可以知道是谁在捣乱,就可以单独卸载、禁止运行这个"老鼠屎"。

2. 工作原理

2.1 S32K14x 系统框图

在这里插入图片描述

如上图所示,内核(①)访问内存(③),需要通过总线(DCODE/ICODE/System)进行数据传输,期间需要经过交叉开关(②),从上图可以看到,(②)中可以看到有MPU模块"卡"在内存访问之前(到这里可以先猜测MPU是根据总线上的信息对访问进行合法性判断,因为指令信息包含地址、操作符)。

从上图可以看到,针对DMA以及QSPI也是纳入保护范围。

在这里插入图片描述

S32K146访问MPU的资源分布如上图所示。

2.2 MPU模块

在这里插入图片描述

如上图所示,输入信号有两部分组成:Address Phase Signal(地址信号)、Internal Peripheral Bus(内部外设总线),地址信号我理解是2.1中所说的总线信息(对指定地址的读/写等),内部外设总线获取到的是用户设置的信息(内存范围、访问权限等),将两部分信息通过Access Evaluation Macro模块进行判断,判断分为两部分:命中判断特权违反判断

2.2.1 Access Evaluation Macro

在这里插入图片描述

Access Evaluation Macro模块判断流程如上图所示,该判断的输入由(Address、Start address、end address、access - r/w/x)组成,经过一系列判断最终输出错误信息、操作权限。

2.2.1.1 Hit determination(命中判断)

① 命中条件:

region_hit = ((addr[31:5] >= RGDn_Word0[SRTADDR]) & (addr[31:5] <= RGDn_Word1[ENDADDR])) & RGDn_Word3[VLD]

(地址 >= 起始地址 && 地址 <= 结束地址 && 区域描述符有效)

② 命中条件(with peocess id)

pid_hit = ~RGDn_Word2[MxPE] | ((current_pid | RGDn_Word3[PIDMASK]) == (RGDn_Word3[PID] | RGDn_Word3[PIDMASK]))

(每个Region中可以包含多个master,通过pid可以实现对多个master进行访问控制)

master逻辑控制ID如下图所示:

在这里插入图片描述

2.2.1.2 Privilege violation determination(特权违反判断)

在这里插入图片描述

系统指令与用户设置的权限进行比较,各此操作允许访问权限如上图所示。

保护区域重叠优先级该如何决定?

重叠区域的权限使用or运算,允许访问(1)覆盖拒绝访问(0)。

2.2.2 错误
  • 如果未在任何区域描述符中命中该访问,则会报告一个保护错误
  • 如果访问命中单个区域描述符,并且该区域表示违反保护,则报告保护错误
  • 如果访问击中多个(重叠)区域,并且所有区域都出现违反保护的信号,则报告保护错误

每一组Slave port都会有如下的一组错误寄存器:

在这里插入图片描述

① 错误地址寄存器:

在这里插入图片描述

② 错误详细信息寄存器:

在这里插入图片描述

2.2.4 MPU使用
  • 配置内存保护地址范围
  • 配置访问权限
  • 配置Valid位

这里我是直接使用S32DS-Components的mpu_pal抽象库和图形化配置界面,参考自带的demo工程,这里不再赘述

mpu 初始化:

MPU_Init(&mpu_pal1_Instance, MPU_PAL_REGION_CFG_CNT0, mpu_pal1_RegionConfig0);

mpu region 使能/禁用:

MPU_EnableRegion(&mpu_pal1_Instance, 1, true);	// 使能
MPU_EnableRegion(&mpu_pal1_Instance, 1, false); // 禁用

当触发故障后,会触发HardFault

3. 遗留问题

  • MPU Region 使能/禁用逻辑:

    按照手册上说,当Valid位启用时,区域描述符才会有效(如下图所示),但是当我调用MPU_EnableRegion并且传入参数为true的时候,Valid被置1,这个时候我去从不可读区域读取数据,并没有产生错误标志以及进入HardFault,但是当我传入false时,Vaild被置0,这个时候重复上述操作能够触发错误标志且进入HardFault,此部分与我所理解相反。
    在这里插入图片描述
    已解决:
    在设置地址的时候,原本是设置成0x6000,但是S32DS自动配置成了0x6001F,导致与后面的区域重叠,在区域重叠下,由于后面的区域为可读权限,导致权限被覆盖,因此造成了上面的乌龙😄。此处感谢@mfketggo的提醒。

  • MemManage 无法触发:

    出现错误的内存访问操作时,如果开启了MemManage,那么应该不会触发HardFault而是触发MemManageFault,但是当我执行如下代码使能MemManage后,还是触发的HardFault,MemManage并没有起效。

    /** Peripheral S32_SCB base address */
    #define S32_SCB_BASE                             (0xE000E000u)
    /** Peripheral S32_SCB base pointer */
    #define S32_SCB                                  ((S32_SCB_Type *)S32_SCB_BASE)
    
    S32_SCB->SHCSR |= (1 << 16);
    

    后来我将BusFault也使能,发现竟然会触发BusFault如下图所示,且故障原因是BFARVALID和PRECISERR:

    在这里插入图片描述
    在这里插入图片描述
    已解决:
    根据NXP的FAE回复芯片设计如此,无法触发mm,只能触发bf,此处感谢@mfketggo的分享。


参考资料:

S32K-RM.pdf - NXP

Cortex-M3/4内核手册

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值