STM32--MPU内存保护单元
Posted Z小旋
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了STM32--MPU内存保护单元相关的知识,希望对你有一定的参考价值。
先说明一下MPU,MPU有很多含义,我们常见的有:
MPU:Memory Protection Unit,内存保护单元(本文描述的内容);
MPU:Microprocessor Unit,微处理器;
MPU-6050 陀螺仪 跟这个就更是差了十万八千里了
所以请不要搞混
MPU
MPU,即内存保护单元,可以设置不同存储区域的存储器访问特性(如只支持特权访问或全访问)和存储器属性(如可缓存、可缓冲、可共享),对存储器(主要是内存和外设)提供保护,从而提高系统可靠性
通过这些规则可以实现如下功能
- 防止不受信任的应用程序访问受保护的内存区域。
- 防止用户应用程序破坏操作系统使用的数据。
- 通过阻止任务访问其它任务的数据区。
- 允许将内存区域定义为只读,以便保护重要数据。
- 检测意外的内存访问。
也就是内存保护、外设保护和代码访问保护 设置一段内存是只读,还是只允许高权限访问,还是禁止访问等
MPU可以保护的区域为内存映射区 memory map
内存映射区就是 32 位的 CM7 内核整体可以寻址的 0 到 2^32 -1 共计 4GB 的寻址空间。通过这些地址可以访 问 RAM、Flash、外设等。下面是内存映射的轮廓图,IC 厂家使用时,再做细分,添加相应的硬件功能
也就是说 MPU可以保护我们的保护内存区域(SRAM 区)不受非法干扰,也可以保护我们的外设区(比如 FMC)
MPU 区域(region)
STM32H7 的 MPU 提供多达 16 个可编程保护区域(region)每个区域最小要求 256 字节,序号范围是 0 到 15, 每个区域(region)还可以被进一步划分为更小的子区域(sub region),每个区域(region)都有自己的可编程起始地址、大小及设置。
这些内存区可以嵌套和重叠,所以这些区域在嵌套或者重叠的时候有个优先级的问题。MPU 可以配置的 16 个内存区的序号范围是 0 到 15,序号15 的优先级最高,以此递减,还有默认区 default region,也叫作背景区,序号-1,即背景区的优先级最低。这些优先级是固定的
MPU 功能必须开启才会有效,默认条件下,MPU 是关闭的
MPU在执行其功能时,是以“region区域”为单位的。一个region其实就是一段连续的地址,只是它们的位置和范围都要满足一些限制(对齐方式,最小容量等)
MPU 区域(region)优先级
MPU 定义的区域(region)还可以相互交迭。如果某块内存落在多个区域(region)中,则访问属性和权限将由编号最大的 region 来决定。比如,若 3 号 region 与 5 号 region 交迭,则交迭的部分受 5 号 region 控制
比方说5号区域(region)内存是只读模式, 3 号 region内存是读写模式 那么重叠的部分就变成了只读模式,如果对其写入数据则会报错
MPU背景区
MPU在Region区域之外,还允许启用一个背景区域(即没有MPU 设置的其他所有地址空间),上面图片的空白存储区域。背景区域只允许特权访问。在启用 MPU 后,就不得再访问定义之外的地址区间,也不得访问未经授权的区域(region),否则,将以“访问违例”处理,触发 MemManage 异常
具体的我们在寄存器中讲解,你就会有一个清晰的了解。
MPU 设置是由 CTRL、RNR、RBAR 和 RASR 等寄存器控制的,其中最主要的就是RASR寄存器,下面我们来一一介绍
1.MPU 控制寄存器(CTRL),该寄存器只有最低三位有效
- PRIVDEFENA 位用于设置是否开启背景区域(region),通过设置该位为 1 即可打开背景区
- HFNMIENA 位用于控制是否在 NMI 和硬件 fault
- ENABLE 位,则用于控制是否使能 MPU
如果PRIVDEFENA 设置为0 那么就只能访问MPU的设置的内存区域,如果访问其他地址就会报错
2.MPU 区域编号寄存器(RNR)
该寄存器只有低 8 位有效 可以读写
在配置一个区域(region)之前,必须先在 MPU 内选中这个区域,我们可以通过将区域编号写入 MPU_RNR 寄存器来完成这个操作。该寄存器只有低 8 位有效,不过由于 STM32H7最多只支持 16 个区域,所以,实际上只有最低 4 位有效(0~15)。在配置完区域编号以后,我们就可以对区域属性进行设置了。
也就是设置要配置那个一内存区域(region)
3. MPU 区域属性和容量寄存器(RASR)
该寄存器是一个32位的寄存器 其中31:29位 27位 23:22位保存,没有作用
- XN(28位):用于控制是否允许从此区域提取指令,如果 XN=1,说明禁止从区域提取指令,即这块内存区禁止执行程序代码,如果设置XN=0,则允许提取指令 即这块内存区可以执行程序代码
- AP 位(bit[26:24]),用于控制Region区域内数据的访问权限(访问许可)三位就对应8中情况
具体设置如下:
注意: 下面的TEX,C,B 和 S 都是设置Cache高速缓存的,正常使用MPU是做内存保护,用上面的AP位即可,如果没有用到Cache,下面的配置有个了解即可,在HAL库配置的时候直接禁止,不会有任何影响
如果对Cache不了解,具体可看:STM32H7—高速缓存Cache(一)
TEX,C,B 和 S 的定义如下,这仅关注 TEX = 000 和 001,其它的 TEX 配置基本用不到。
- C位:用于使能或者禁止Cache
- B位:用于配合C位实现Cache下是否使用缓冲
- S位:用于位用于控制存储器的共享特性,S=1,则二级存储器不可以缓存(Cache),如果设
置 S=0,则可以缓存(Cache),一般我们设置该位为 0 即可。
按照配置的不同,总共可以分成以下四种:
read/write-through/back/allocate的区别:
一、CPU读Cache
- Read through:直接从内存区读取数据
- Read allocate:先把数据读取到Cache中,再从Cache中读取数据
二、CPU写Cache
若hit命中,有两种处理方式:
- Write-through:在数据更新时,把数据同时写入Cache和存储区
操作简单,但是写入速度慢- Write-back:只有在数据被替换出缓存时,被修改的缓存数据才会被写到后端存储。
写入速度快,但是一旦更新后的数据未被写入时出现断电,则数据无法找回若miss,有两种处理方式:
- Write allocate:先把要写的数据载入到Cache中,写Cache,然后再通过flush的方式写入到内存>中。
- No-write allocate:并不将写入位置读入缓存,直接把要写的数据写入到内存中。
什么叫hit/miss:
一、读操作
如果CPU要读取的SRAM区数据在Cache中已经加载好,这就叫读命 中(Cache hit),如果Cache里面没有怎么办,这就是所谓的读Cache Miss。
二、写操作
如果CPU要写的SRAM区数据在Cache中已经开辟了对应的区域(专业词汇叫Cache Line,以32字节为单位),这就叫写命中(Cache hit),如果Cache里面没有开辟对应的区域怎么办,这就是所谓的写Cache Miss。
- SRD位: 用于控制内存区的子区域,一共有8bit,一个bit控制一个子区域,一般都开启
- RegionSIZE位:配置Region内存区域的大小,最小为32位 可以为32kb 64kb 128kb等等
4. MPU 基地址寄存器(RBAR)
- ADDR: Region内存区的首地址
注意一定要保证首地址跟内存区的大小(RegionSIZE位)对齐,例如,我们定义某个 region 的容量(RegionSIZE位)是 64KB,那么它的基址(ADDR)就必须能被 64KB 整除,也就是这个地址对 64KB,即 0x00010000 求余数等于 0,比如0X0001 0000、0X0002 0000、0X0003 0000 等都可以被整除
- VALID 区域编号是否覆盖,如果为1的话将会重新修改ADDR Region内存区的编号
- REGION 段(bit[3:0]) : 新编号,四位地址对应(0~15)
Region内存区的编号在初始化的时候就设置完成,所以一般VALID位设置为0
关于MPU一些基本原理和寄存器就先探讨到这里,下一篇我们来看下HAL库里MPU的配置以及如何使用。
STM32H7内存默认映射和属性
STM32H7 FMC地址
以上是关于STM32--MPU内存保护单元的主要内容,如果未能解决你的问题,请参考以下文章
STM32+MPU6050设计便携式Mini桌面时钟(自动调整时间显示方向)