STM32H7的CACHE、RAM、MPU直接的联系以及如何使用
2025-10-21 来源:bilibili
前言
本文主要讲解STM32H7系列的CACHE是如何使用的,以及能给程序带来怎样的提升,还有过程中遇到的问题以及解决方法。

一、启用CACHE
启用cache很简单,就是这两句,分别打开I-Cache和D-Cache,但是如果只使用这两句,再操作DMA和FLASH时就很有可能遇到问题,后面会具体说明。
SCB_EnableICache();//使能I-Cache SCB_EnableDCache();//使能D-Cache

二、使用MPU
CACHE和MPU一般都是要结合在一起使用的,因为MPU可以保护对RAM的访问。
下面是一个RAM的MPU保护配置。
/* Disables the MPU */
HAL_MPU_Disable();
/** Initializes and configures the Region and the memory to be protected
*/
MPU_InitStruct.Enable = MPU_REGION_ENABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER0;
MPU_InitStruct.BaseAddress = D1_AXISRAM_BASE;
MPU_InitStruct.Size = MPU_REGION_SIZE_512KB;
MPU_InitStruct.SubRegionDisable = 0x0;
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE;
MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
/* Enables the MPU */
HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
1.首先是配置MPU时需要先关闭MPU。
HAL_MPU_Disable(); //关闭MPU
2.MPU_InitStruct.Enable
可以赋值是为MPU_REGION_ENABLE、MPU_REGION_DISABLE,分别代表这个区域的MPU是否启用。
3.MPU_InitStruct.Number
可以赋值MPU_REGION_NUMBER0、MPU_REGION_NUMBER1、MPU_REGION_NUMBER2...一共是8个,代表所配置保护内存区域的编号。
这里的序号只是代表优先级的高低,序号越高优先级越高,因为存在一种情况就是配置的两块内存重叠了,重叠的部分会按照优先级高的来执行,这个概念和中断优先级有些类似。
4.MPU_InitStruct.BaseAddress
可以赋值的就是要保存内存的起始地址,这里的D1_AXISRAM_BASE是0x24000000,是一个512K的RAM。当然也可以中这0x24001000开始,具体从哪里开始,可以自己来定义。
5.MPU_InitStruct.Size
就是所保护内存的大小,MPU_REGION_SIZE_512KB就是要保护区域的大小,还有其他大小可选,具体可以看宏定义中所定义的大小。
6.MPU_InitStruct.SubRegionDisable
是配置子区域,每个MPU配置的内存区域都被分为了8个子区域,数值从0~255,每一个bit对应着一个子区域的禁用(1)或者启用(0)。最高位(控制最后一个子区域,最低位控制第一个子区域,最后注意的是大于128字节才可以使用子区域。
7.MPU_InitStruct.AccessPermission
是配置RAM的读写权限,没有什么特殊需求的话就配置为MPU_REGION_FULL_ACCESS,就是完全访问。
/** @defgroup CORTEX_MPU_Region_Permission_Attributes CORTEX MPU Region Permission Attributes
* @{
*/
#define MPU_REGION_NO_ACCESS ((uint8_t)0x00) //禁止所有情况下的访问(读/写)
#define MPU_REGION_PRIV_RW ((uint8_t)0x01) //仅允许在特权模式下读写
#define MPU_REGION_PRIV_RW_URO ((uint8_t)0x02) //特权模式下可读写,用户模式下只读
#define MPU_REGION_FULL_ACCESS ((uint8_t)0x03) //完全访问,特权和用户模式下都可以读写
#define MPU_REGION_PRIV_RO ((uint8_t)0x05) //仅允许在特权模式下读取
#define MPU_REGION_PRIV_RO_URO ((uint8_t)0x06) //特权和用户模式下都只读
8.MPU_InitStruct.DisableExec
表示代码是否在RAM中可执行,MPU_INSTRUCTION_ACCESS_ENABLE代表可执行,没有特殊需求的话也配置成该模式,这个就类似于Linux中的可读可写可执行的权限,这里算是加了一个可执行的权限。
9.最后的4个参数需要一起看MPU_InitStruct.TypeExtField;MPU_InitStruct.IsShareable;MPU_InitStruct.IsCacheable;MPU_InitStruct.IsBufferable
四个参数的组合意义如下图所示

图1
Write through, no write allocate(透写)
(1)写入策略:如果cache命中,则同时向cache和对应的内存区域中写入;如果未命中,则只写入对应的内存区域,不开辟新的cache。 (2)读取策略:如果cache命中,则直接从cache中读取,不再读取对应的内存区域,如果cache未命中,则开辟对应的cache区域,并从对应的内存区域中将数据同步至cache,并读取cache。
Write back, write and read allocate
(1)写入策略:如果cache命中,则只写入cache,不再写入到对应的内存区域;如果未命中,则开辟对应的cache,并同时向cache和对应的内存区域写入。 (2)读取策略:如果cache命中,则直接从cache中读取,不再读取对应的内存区域,如果cache未命中,则开辟对应的cache区域,并从对应的内存区域中将数据同步至cache,并读取cache。
Write back, no write allocate
(1)写入策略:如果cache命中,则只写入cache,不再写入到对应的内存区域;如果未命中,则只写入对应的内存区域,不开辟新的cache。 (2)读取策略:如果cache命中,则直接从cache中读取,不再读取对应的内存区域,如果cache未命中,则开辟对应的cache区域,并从对应的内存区域中将数据同步至cache,并读取cache。
通过上面介绍的特性,可以看到,使用的时候最好使用Write through, no write allocate这种模式,因为cache命中,则同时向cache和对应的内存区域中写入,不用担心数据的不统一。H7系列使用cache代码的执行速度提高两倍以上,当然这个两倍只是我大概试了一下,这里的两倍大概就是测试的中断处理的能力,还有就是如果使用了LTDC+外部RAM,速度提升更加明显,整个UI都流畅了很多。

三、RAM
下面图2~图6分别展示了STM32H743单片机当把时钟频率配置为400M的内部RAM的总线的速度。总线位数越大,以及频率越高代表着处理速度越快,当某些程序段需要极快的速度运行,可以将内存指定在TCM区,至于如何指定,后面会有文档来讲解。
1.TCM区

图2
2.AXI SRAM区

图3
3.SRAM1、SRAM2、SRAM3区

图4
4.SRAM4区

图5
5.Backup SRAM区

图6

四、注意问题
如图7所示,可以看出ITCM、DTCM、AXI SRAM是不可以使用DMA的。
如果使用了可以使用DMA的SRAM,需要注意开启了CACHE,记得要配置MPU然后选择为MPU_ACCESS_NOT_CACHEABLE不可使用cahe,所以可以将DMA的数据单独指定到另一块SRAM上,然后将该RAM设置为MPU_ACCESS_NOT_CACHEABLE就可以了,否则DMA数据很有可能是不更新的。
开启CACHE的情况下操作内部flash的时候,也要注意清除D-CACHE,否则写入会有问题,操作内部FLASH清除的函数。

图7
上一篇:常见STM32术语解释
- 信息安全专题 | 代码保护(1)使用STM32H7新特性保护片上代码的机密性
- H7-TOOL自制Flash读写保护算法,为STM32H7全系列芯片添加支持,支持在线和脱机烧录
- STM32H7高精度定时器(HRTIM)的移相配置
- 历时456天,实测STM32H7的内置RTC不断电,不校准,快了44分钟
- STM32H7系列芯片发不出去的hello问题
- 如何将ThreadX移植到STM32H7平台
- STM32H7各产品应用定位
- 探究STM32H7芯片IAP跳转失败案例
- 关于高速单片机STM32H7定时器同步启动并输出多路PWM波形的探究
- 美光预测:L4 自动驾驶汽车将需超 300GB 内存
- 六大全新产品系列推出,MCX A微控制器家族迎来创新
- 意法半导体全新STM32C5系列,重新定义入门级微控制器性能与价值,赋能万千智能设备
- 模组复用与整机重测在SRRC、CCC、CTA/NAL认证中的实践操作指南
- 从控制到系统:TI利用边缘AI重塑嵌入式MCU的边界
- 有源晶振与无源晶振的六大区别详解
- 英飞凌持续巩固全球微控制器市场领导地位
- 使用 Keil Studio for Visual Studio Code开发 STM32 设备
- 蓝牙信道探测技术原理与开发套件实践
- Microchip 推出生产就绪型全栈边缘 AI 解决方案,赋能MCU和MPU实现 智能实时决策
- LoRa、LoRaWAN、NB-IoT与4G DTU技术对比及工业无线方案选型分析




