单片机
返回首页

STM32H7的CACHE、RAM、MPU直接的联系以及如何使用

2025-10-21 来源:bilibili

前言

本文主要讲解STM32H7系列的CACHE是如何使用的,以及能给程序带来怎样的提升,还有过程中遇到的问题以及解决方法。

cut-off

一、启用CACHE

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

SCB_EnableICache();//使能I-Cache SCB_EnableDCache();//使能D-Cache


cut-off

二、使用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都流畅了很多。

cut-off

三、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


cut-off

四、注意问题

如图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


进入单片机查看更多内容>>
相关视频
  • 【TI MSPM0 应用实战】智能小车+工业角度编码器+血氧仪+烟雾探测器!硬核参考设计详解!

  • 2022 Digi-Key KOL 系列: 你见过1GHz主频的单片机吗?Teensy 4.1开发板介绍

  • TI 新一代 C2000™ 微控制器:全方位助力伺服及马达驱动应用

  • MSP430电容触摸技术 - 防水Demo演示

  • 直播回放: Microchip Timberwolf™ 音频处理器在线研讨会

  • 基于灵动MM32W0系列MCU的指夹血氧仪控制及OTA升级应用方案分享

精选电路图
  • 1瓦线性调频增强器

  • 1瓦四级调频发射机

  • 500W MOS场效应管电源逆变器,12V转110V/220V

  • 红外开关

  • LM317过压保护

  • 0-30V/20A 大功率稳压电源(采用LM338)

    相关电子头条文章