STM32--MPU内存保护单元(一)

先说明一下MPU,MPU有很多含义,我们常见的有:

MPU:Memory Protection Unit,内存保护单元(本文描述的内容);

MPU:Microprocessor Unit,微处理器;

MPU-6050 陀螺仪 跟这个就更是差了十万八千里了

所以请不要搞混

STM32–MPU内存保护单元(二)

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

  1. Read through:直接从内存区读取数据
  2. Read allocate:先把数据读取到Cache中,再从Cache中读取数据

二、CPU写Cache
若hit命中,有两种处理方式:

  1. Write-through:在数据更新时,把数据同时写入Cache和存储区
    操作简单,但是写入速度慢
  2. Write-back:只有在数据被替换出缓存时,被修改的缓存数据才会被写到后端存储。
    写入速度快,但是一旦更新后的数据未被写入时出现断电,则数据无法找回

若miss,有两种处理方式:

  1. Write allocate:先把要写的数据载入到Cache中,写Cache,然后再通过flush的方式写入到内存>中。
  2. 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地址

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/as480133937/article/details/123656394