STM32H7---高速缓存Cache

Posted Z小旋

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了STM32H7---高速缓存Cache相关的知识,希望对你有一定的参考价值。

上一讲我们说了cache的一些基本原理,这一讲我们来说说H7的cache配置

STM32H7—高速缓存Cache(一)

Cortex-M7内核的L1 Cache由多行内存区组成,我们的H7是分为 16Kbytes 的 I-Cache 和 D-Cache
每行有32字节,每行都配有一个地址标签。数据缓冲DCache是每4行为一组,称为4-way set associative。而指令缓冲区ICache是2行为一组,2-way set 这样节省地址标签,不用每个行都标记一个地址

  • 以16 KBytes 的 D-Cache 来计算,一共128 个组(sets), 512 个缓冲行(lines),每个缓冲行 32 个字节

首先来看下H7的默认内存地址映射范围:

其中,WT 表示 Write-through(透写),WB 表示 Write-back(回写),WA 表示 Write-allocate(写分配),没有明确标注 WA 的就是 RA(读分配)。XN 的意思是 Execute-Never, 其含义为如果相应的地址空间是 XN,是绝不允许执行代码的。

存储器类型为 Normal 的才能使用 cache,并且 TCM 接口是 not cacheable 的。

在H7中 Cache 的配置是通过 MPU 来设置的,通常只用到下几种方式。

Cache 相关操作的函数在 cmsis/include/core_cm7.h 头文件中声明从函数名中可以知道,包括四种 cache 操作:enable、disable、clean 和 invalidate。


当然还有三个不常用的函数:

void SCB_InvalidateDCache_by_Addr(uint32_t *addr, int32_t dsize);

void SCB_CleanDCache_by_Addr(uint32_t *addr, int32_t dsize);

void SCB_CleanInvalidateDCache_by_Addr(uint32_t *addr, int32_t dsize);

下面我们来看一下这些函数。

SCB_EnableICache() 

使能指令I-Cache,系统上电后优先初始化即可

SCB_DisableICache() 

禁止指令I-Cache。

SCB_InvalidateICache()

使 I-cache 无效,无效化Invalid是将Cache Line标记为无效,即删除操作。

SCB_EnableDCache()

此函数使能数据D-Cache,系统上电后优先初始化即可

SCB_DisableDCache()

禁止数据D-Cache。

SCB_InvalidateDCache()

使 D-Cache 无效,无效化Invalid是将Cache Line标记为无效,即删除操作。

SCB_CleanDCache()

Clean 清空所有的 cache-line,即将 dirty 的 cache-line 全部写到 cache line 对应的真实的物理地址中

所谓的 drity 属性,即写操作时, 更新了相应的 cache-line,但是没有更新到真实的物理地址,而这个 clean 的动作, 就是将 cache 中的内容更新到真实的物理地址中。

SCB_CleanInvalidateDCache()

此函数是前面两个函数SCB_InvalidateDCache和SCB_CleanDCache的二合一。将Cache Line中标记为dirty的数据写入到相应的存储区后,再将Cache Line标记为无效,表示删除。这样Cache空间就都腾出来了,可以加载新的数据。

SCB_InvalidateDCache_by_Addr()

根据地址信息无效其对应的 cache-line。

SCB_CleanDCache_by_Addr()

根据地址信息 clean 其对应的 cache-line。

SCB_CleanInvalidateDCache_by_Addr()

根据地址信息 clean 并 invalidate 其对应的 cache-line。

一共就这么多,大部分都是对D-Cache的操作,正常使用的时候,直接调用函数进行初始化就行

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

但是,在STM32H7—高速缓存Cache(一) 中我们提到了Cache的一致性问题,比方说DMA操作等引起的一致性错误等

1.CPU写数据到内存

当CPU有写物理内存的指令时,CPU 会先去更新相应的 cache-line(Write-back 策略)缓存,在没有 clean 的情况下,会导致其对应的实际物理内存中的数据并没有被更新,如果这个时候有其它的 Host(如 DMA)访问这段内存时,就会出现问题(由于实际物理内存并未被更新,和 D-cache 中的不一致),这就是所谓的 cache 一致性的问题。

2.CPU从内存读取数据

第二种情况是 DMA 更新了某段物理内存(DMA 和 cache 直接没有直接通道),而这个时候CPU 再读取这段内存的时候,由于相对应地址的 cache-line 已经被缓存了,导致CPU 读到的是 cache-line 中的数据,而非被 DMA 更新过的实际物理内存的数据。

为了防止这种问题,保证数据的一致性,我们设置了 D Cache 的强制透写功能(Write Through)

强制透写(Write Through): CPU 每次操作 Cache 里面的数据,同时也会更新到 SRAM 里面,不需要再发送clean操作,保证D Cache 和 SRAM 里面数据一致。


需要将SCB->CACR寄存器的第一位置1 就可以开启强制透写

SCB->CACR|=1<<2;   //强制D-Cache透写

那也就得到了Cache的初始化流程:

//使能CPU的L1-Cache
void Cache_Enable(void)

    SCB_EnableICache();//使能I-Cache
    SCB_EnableDCache();//使能D-Cache   
	SCB->CACR|=1<<2;   //强制D-Cache透写,如不开启,实际使用中可能遇到各种问题	



这样带来的好处就是可以保证D Cache 和SRAM里面数据的一致性,坏处就是会损失一定的性能(每次都要回写数据),如果大家想自己控制 D Cache 数据的回写,以获得最佳性能,则可以关闭 D Cache 透写模式

以上是关于STM32H7---高速缓存Cache的主要内容,如果未能解决你的问题,请参考以下文章

STM32H7---高速缓存Cache

STM32H7---高速缓存Cache

BSP视频教程STM32H7视频教程第13期:系统讲解Cortex-M7内核MPU和Cache,理解通透(2022-04-17)

BSP视频教程STM32H7视频教程第14期:超干●货,MPU和Cache实战,一张图了解所有经典配置案例,争取人人都可以玩溜(2022-05-08)

STM32H7B0 HAL库中关于DMA的注意事项以及DCMI调试遇到的问题及解决方法

STM32H7B0 HAL库中关于DMA的注意事项以及DCMI调试遇到的问题及解决方法