admin 管理员组

文章数量: 887021


2023年12月19日发(作者:php广告系统源码)

STM32H7平台CACHE的使用

摘 要:本论文就STM32H7开发平台cache使用中数据一致性的问题展开讨论,并给出解决办法。本论文首先分析当前MCU和cache的时代背景以及应用技术的现状,说明了使用cache的必要性。其次简单介绍cache的分类、单位、命中、丢失、读操作分配、写操作分配等基本概念。最后给出避免数据不一致的解决方案,包括通过软件进行cache的维护、通过STM32CUBE配置使用内存保护单元和分散加载文件。

关键词:STM32H7;高速缓存;数据一致性;内存保护单元;分散加载文件

1 引言

随着科技和工艺的提升,MCU的主频不断提升,采用 ST 最新40nm工艺的

STM32H7 已经可以跑到 400 MHz 了。

虽然微控制器的频率大幅提高了,可是主存储器的存储周期却跟不上。由于短板效应,主存储器的速度将会严重制约整个系统的性能。而能提高存储器平均访问速度的高速缓冲存储器(Cache)便十分必要。

2Cache基本原理介绍

2.14-way set associative

Cortex-M7内核的L1 Cache 由多行内存区组成,每行有32字节,每行都配有一个地址标签。数据缓冲DCache是每4行为一组,称为 4-way set

associative。而指令缓冲区 ICache 是2行为一组,这样节省地址标签,不用每个行都标记一个地址。[1]

2.2 I-Cache 和 D-Cache

如果一个存储系统中指令预取时使用的 cache 和数据读写时使用的 cache

是各自独立的,这是称系统使用了独立的 cache,反之则为统一的 cache。

Cortex-M7 架构为我们配备了独立的高速指令缓存(I-Cache)和高速数据缓存(D-Cache)。

2.3 Cache line

Cache 与主存储器之间以块(cache line)为单位进行数据交换,Cache 在逻辑上被划分为若干 cache line,对应着一组存储器的位置,因此,Cache 与主存储器交换数据的最小粒度就是 cache line。

2.4 Cache Hit 和 Cache Miss

Cache命中(Cache Hit)——要访问的数据/指令已经存在缓存里;

Cache缺失(Cache Miss)——要访问的数据/指令不在缓存里;

如果发生 cache miss 并且 cache 未满,则在 cache 中发现一个位置,并把新的缓存数据存到这个位置。如果 cache 已满,则要通过 cache 替换策略进行 cache line 的替换,腾出空闲的位置后,再将新的缓存数据存到这个位置。

2.5 Read-allocate 和 Write-allocate

根据不同的分配方式,可以把 cache 分为读操作分配(Read-allocate)cache 和写操作分配(Write-allocate)cache。

对于读操作分配 cache,当进行数据写操作时,如果 cache 未命中,只是简单地将数据写入主存中。只有在数据读取时,才进行 cache 内容预取。

对于写操作分配 cache,当进行数据写操作时,如果 cache 未命中,cache

系统将会进行 cache 内容预取,从主存中将相应的块读取到 cache 中相应的位置,并执行写操作,把数据写入到 cache 中。

2.6 Write-back 和 Write-through

按 cache 中内容写回主存中的方式分类,可分为 Write-back 和 Write-through 两种方式。

Write-back(翻译为“写回”或“回写”)——写数据时,只更新缓存。

Write-through(翻译为“写通”、“透写”或“直写”)——写数据时同时更新缓存和二级存储。

3 DMA与Cache的数据冲突

3.1 数据冲突

为了提升效率,常用的另一种方式便是DMA(Direct Memory Access,直接存储器访问)。这种不需要经过MCU控制,设备与内存直接交互的方式极大提高了MCU效率,被广泛使用。

DMA和Cache都是提升MCU效率的可靠方法,但是同时使用两者可能会导致数据冲突,影响数据一致性。

3.1.1 DMA读取数据异常

如下图,内存中的数据已被提取到了Cache中,CPU向该地址写数据会先写到Cache中,内存里的数据保持不变,若此时DMA访问内存读取数据,会读取到旧的数据而非CPU新写入的数据,造成数据不一致。

图1:DMA读取异常图

3.1.2 DMA写入数据异常

如下图,内存中的数据已被提取到了Cache中,DMA向该地址写数据,内存中的数据更新,而Cache中的数据保持不变,若此时CPU访问该地址读取数据,会读取到Cache中旧的数据而非DMA新写入的数据,造成数据不一致。

图2:DMA写入异常图

4Cache数据一致性解决办法

4.1 通过软件进行cache的维护

4.1.1 相关函数

函数描述如下:[3]

表1:CMSIS

Cache函数表

4.1.2 DMA读取冲突解决方法

方法一:不启动或关闭 D-Cache。

方法二:DMA 访问 SRAM1前先 Clean cache。

方法三:将所有 cacheable 的空间全部强制 Write-though。

4.1.3 DMA写入冲突解决方法

方法一:不启动或关闭 D-Cache。

方法二:Core访问SRAM前invalidate cache。

4.2 通过内存保护单元配置Cache

4.2.1 MPU简介

MPU 可以将 memory map内存映射区分为多个具有一定访问规则的区域,通过这些规则可以实现如下功能:[4]

防止不受信任的应用程序访问受保护的内存区域。

防止用户应用程序破坏操作系统使用的数据。

通过阻止任务访问其它任务的数据区。

允许将内存区域定义为只读,以便保护重要数据。

检测意外的内存访问。

4.2.2 MPU配置Cache

1.配置Non-cacheable

正常的读写操作,无Cache。

2.配置Write through,read allocate,no write allocate

写操作:更新内存,若Cache命中也更新Cache。

读操作:直接从Cache读取,若Cache未命中,则开辟新Cache。

3.配置Write back,read allocate,no write allocate

写操作:只更新Cache。

读操作:直接从Cache读取,若Cache未命中,则开辟新Cache。

4.配置Write back,read allocate,write allocate

写操作:只更新Cache,若Cache未命中,则开辟新Cache。

读操作:直接从Cache读取,若Cache未命中,则开辟新Cache。

4.2.3 DMA读取冲突解决方法

方法一:不启动或关闭 D-Cache。

方法二:将对应SRAM的配置为Write-though。

方法三:将对应SRAM的配置为Shareable。

4.2.4 DMA写入冲突解决方法

方法一:不启动或关闭 D-Cache。

方法二:将对应SRAM的配置为Shareable。

4.3 通过分散加载避免冲突

DMA和Cache造成数据不一致的前提是二者访问相同地址,那么便可以使用分散加载是两者无法访问同一地址,从根源上解决冲突。即DMA访问的地址Cache始终不访问,Cache访问的地址DMA始终不访问。

地址的划分方法可随需求自行决定,推荐的方式是根据内存特性进行划分,如D1域的AIX SRAM区,由于其数据宽度为64bit,能快速填装Cache块,更好的发挥Cache性能,故可以配置成Cache的访问内存;所有DMA都能访问的SRAM4区,可以配置成DMA的访问内存等等。而且可使用4.2节介绍的MPU进行内存配置。

内存分配时只需使用__attribute__()函数将变量指定放入对应内存即可。

5 结束语

MCU的价格有很大一部分取决于Cache的大小,若是不能很好发挥其性能便会造成不少的浪费,这也是即便解决数据一致性问题可能繁琐也不得不使用Cache的原因之一,Cache带来的性能提升值得这些付出。

而亡羊补牢不如防患于未然,提前配置好各自的内存区域,消泯冲突爆发的土壤,比使用代码实时维护要方便灵活的多。

参考文献:

[1] STM32F7 Cache Overview.

[2]

STMicroelectronics. Reference Manual STM32H7x3. 2017.

[3]

STMicroelectronics. STM32F7 Series and STM32H7 Series Cortex®-M7

processor. 2019.

[4]

STMicroelectronics. Programming manual STM32F7_H7 Series. 2017.

[5] STMicroelectronics. Managing memory protection unit (MPU) in STM32 MCUs.

2016.

[6] STMicroelectronics. Level 1 cache on STM32F7 Series and STM32H7 Series.

2018.

1


本文标签: 数据 内存 使用 访问 冲突