1 前言
这一节就来看看S32K3的资源访问保护器,S32K3在资源管理方面主要有三个玩意可以对其片上资源提供了强有力的保护,分别是REG_PORT(Register Protection),MPU(Memory Protection Unit)和XRDC(Extended Resource Domain Controller)。其中REG_PORT针对的是寄存器操作的保护;MPU其实是ARM核里自带的一个外设,它所管理的是单核对整个片上内存的访问权限;XRDC管理的则是所有访问Master(核,DMA等)对外设和Memory的访问权限。
2 REG_PORT
REG_PORT功能简单来说就是给寄存器加一把硬件锁,当需要修改寄存器时,必须先解锁才能进行相关操作,其功能框图如下:
但是并不是K3所有的寄存器都可以通过REG_PORT来加锁保护,可以在RM手册的附件里面有个叫做S32K3xx_REG_PROT_details.xlsx的表格,在这个表格里记录所有能够被REG_PORT上锁保护的寄存器。那这个功能在MCAL中怎么去配置呢?其实很简单,在很多模块中,都会有一个Enable User Mode Support选项,我以Port模块为例,如下:
查看这个选项的描述如下:
仔细一读就可以知道在user mode下,REG_PORT就会被使能,但是一般这个功能用的不多,在一般的应用下,CPU都是工作在Supervisor模式下的,所有REG_PORT感觉就是被浪费了。
3 MPU
3.1 MPU简介
MPU是ARM核自带的一个核内外设,它所要保护的其实MPU所在核对内存(这里的内存包括整个MCU地址映射空间,包括外设寄存器,RAM,Flash等)的访问权限,所以MPU管理的访问Mater为M7核,访问Slave为整个内存空间。对MPU不太清楚的可以参考这篇文章:《小猫爪:嵌入式小知识11-MPU详解及其应用》,我在这里就不多嘴了。
当使能和配置MPU后,一旦核非法访问禁止区域就会触发MemManage_Handler中断(需通过写SCB->SHCSR使能,否则触发HardFault_Handler中断)。
3.2 MCAL配置
接下来,废话不多说,直接进入主题,怎么在MCAL中实现MPU的相关配置?MPU以CDD的形式被集成在了Rm模块中,如下:
点开后,在配置页面中配置MPU,如下:
接下来就是配置和添加域,对于S32K3来说,可以最大配置16个MPU域,下图为K3的默认MPU配置如下:
我们可以根据上表来添加域和配置每个域的类型和权限,如下:
注意①:配置MPU域的大小起始地址需要满足两个条件,第一就是域的大小必须是2的次方大小,第二就是起始地址必须要是域大小的整数倍。
注意②:在配置域的类型时最好根据域的物理和功能特性来配置,可参考下表:
域的类型 | MPU 类型 |
---|---|
code flash | Normal Cacheable |
ITCM and DTCM | Strong ordered |
System RAM | Normal Cacheable |
Shared RAM | Normal IO No Cache |
Peripherals registers | Device shared |
Data flash | Device shared |
QSPI buffers | Device no share |
Private periphera | Device no share |
注意③:另外Inter Cache和Outer Cache指的是分层Cache,对于一个多核MCU来说,它可能有多层Cache,L1 Cache,L2 Cache,L3 Cache,而Inter和Outer则是指的是在位置上来区分,一般独属于CPU微架构的叫Inter Cache,不属于CPU微架构的叫outer Cache。K3只有一层Cache,即只有Inter Cache,所以在配置时让Outer Cache Policy和Inner Cache Policy 保持一致即可。至此关于MPU的配置就结束了,非常简单。
注意④:配置两个域的时候,如果这两个域中间有重叠的地方,那么这重叠的地方的权限特征取决于域number大的那个域。比方说1号域,可读可写;而6号域可读不可写,则1号域和6号域重叠的域区域为可读不可写。对,这里的域number其实就是在配置界面中的index,因为在软件中,它就是根据这个index依次配置MPU的寄存器。
注意⑤:在Rm驱动里面也提供了MPU相关的API函数,比如设置相关区域的权限,获取MPU错误信息等等,详情请参考RTD源码中的CDD_Rm.c和CDD_Rm.h。
注意⑥:在实际调试过程中,如果出现问题,可查看SCB寄存器组的CFSR寄存器和MMFAR查看MPU错误标志和触发MPU错误的地址:
4 XRDC
XRDC是S32K3的一个外设,专门用来管理K3上所有资源的访问权限的。因此XRDC管理的访问Mater为片上所有的Bus Master,包括三个核类Master,分别为M7_0,M7_1和HSE,以及三个非核类Master,分别是DMA AHB,TestPort AHB, EMAC AHB;而管理的Slave为K3所有的外设和Memory。
4.1 XRDC的原理和工作机制
XRDC的工作机制非常简单,它就是将访问Master,外设和Memory分别编号,然后将使用这些编号作为索引,将其放在一个区域里面,将这个区域称为Domain,然后Master就可以访问跟它在一个Domain的外设和Memory。XRDC还可以分别对外设和Memory分别设置访问权限,是否可以读写。
XRDC的功能框图如下为:
- MDAC:控制访问Master的所在Domain,同一时刻一个Master只能处在一个Domain,一个Domain可以有多个Master,K3最大可以配置4个Domian。不同的的PN所支持的Domian数量是不一样的,具体可参考RM手册中的表Number of domains。
- MRC:控制3个Domain对每块Memory(起始地址可配置,最大可配置36块Memory区间)的读写权限,另外还可以给每块Memory加硬件信号量(SEMA42,在后面的文章中会介绍到)。
- PAC:控制3个Domain对外设的读写权限,另外还可以给每个外设加硬件信号量(SEMA42,在后面的文章中会介绍到)。
根据其功能框图,就可以很简单的推出在使能XRDC的情况下,Master访问资源的过程就变成了:
- 一个Master对外设或者Memory发起读写申请。
- XRDC的Master控制侧截断申请,并加上MDAC里的跟Domain有关的信息。
- 加上额外信息的读写申请发送到内部crossbar总线上继续传输。
- 当读写申请来到了XRDC的Slave控制侧时,XRDC再次截断读写申请并将之前XRDC强加到读写申请的额外信息与Slave的权限控制信息进行对比(这一步叫做DdACP评估,记住这个词,后面的文章会出现)。
- 如果对比成功,则成功操作并返回读写信息给Master,如果对比不成果,则触发BusFault_Handler中断(需通过写SCB->SHCSR使能,否则触发HardFault_Handler中断)。
除此之外,XRDC针对3个核类Master专门开发了一个PID比对的功能。这个功能针对核类Master访问资源这种情况提供了又一层次的限制。比方说,我需要实现一个在OS下不同任务对资源有不同的权限,那么如果XRDC只是以上述的操作流程是不可能实现这一需求的,所以这个时候就XRDC就引出了PID的功能。
实现方式其实也是很简单,MDAC可以为每个核类Master配置一个固定的PID码(DFMTx[PID])和一个固定PID掩码(DFMTx[PIDM]),这两个码一旦初始化成功后,在后续的软件操作中是不能被修改的,这个时候对应于每个核类Master还有一个软件可配置的PID码,便于区分,暂且称呼它为PID_2码(PIDm[PID]),当核类Master发起了访问申请后,XRDC会进行一个计算,这个计算有两种形式可选,分别如下:
如果上面的计算结果匹配成功,则Master访问申请继续,如果匹配不成功,则访问失败。另外PID_2码(PIDx[PID])的最高位决定了当前访问是Secure访问或者Nonsecure访问,所以软件可以自己决定这次的访问是Secure访问还是Nonsecure访问。与之相对应的是,每一个外设和Memory都可以针对Secure访问和Nonsecure访问来配置不同的访问权限。通过PID这个骚操作就可以实现同一个核内不同任务对一个资源的不同访问权限。
所以PID的用法流程为:先为每一个任务分配一个PID,在该任务执行时,首先设置PID_2码(PIDm[PID]),那么只有满足上面PID计算流程时才能继续正常访问相关资源(一般来说,这个功能不会被用到)。
4.2 MCAL配置
接下来,还是废话不多说,直接进入主题,怎么在MCAL中实现MPU的相关配置?XRDC以CDD的形式被集成在了Rm模块中,如下:
首先在XRDC Memory Config中添加需要被XRDC管理的Memory区域及其起始地址等相关配置等,如下:
在XRDC Peripheral Config中添加需要被XRDC管理的外设,如下:
在XRDC Domain Assignment添加Domian,如下:
给每个Domian添加Master和相关访问资源,并分别对其进行详细的配置,如下:
配置Master总线,如下:
配置Domian中的资源的访问权限,如下:
在Rm驱动里面也提供了XRDC相关的API函数,详情请参考RTD源码中的CDD_Rm.c和CDD_Rm.h。
注意:这里需要注意的是,一旦使能了XRDC,只要牵扯到了Master访问资源,那么访问流程就一定会上文中所述,那么所有不满足XRDC访问配置的一切访问都是不允许的,所以在配置XRDC时一定要考虑所有的访问情况,并将其囊括进去。
至此关于XRDC的相关原理和配置就说完了。