一、Cache # M3 Z+ G( g+ L 1、介绍 5 M$ D ]7 _* I2 ]: M Cache又分数据缓存D-Cache和指令缓冲I-Cache,STM32H7的数据缓存和指令缓存大小都是16KB。STM32H7主频是400MHz,除了TCM和Cache以400MHz工作,其它AXI SRAM,SRAM1,SRAM2等都是以200MHz工作。数据缓存D-Cache就是解决CPU加速访问SRAM。 ^% v( D0 p1 C- k 5 `9 Q2 N$ Q6 p( A% o# C/ U 如果每次CPU要读写SRAM区的数据,都能够在Cache里面进行,自然是最好的,实现了200MHz到400MHz的飞跃,实际是做不到的,因为数据Cache只有16KB大小,总有用完的时候。% Y: \! r+ l3 a0 K' Q 2、操作,分为读操作和写操作 8 v+ _8 Q; v: @2 \' } 读操作: 如果CPU要读取的SRAM区数据在Cache中已经加载好,这就叫读命中(Cache hit),如果Cache里面没有怎么办,这就是所谓的读Cache Miss。 4 k# ^( _ d+ g 写操作: 如果CPU要写的SRAM区数据在Cache中已经开辟了对应的区域(专业词汇叫Cache Line,以32字节为单位),这就叫写命中(Cache hit),如果Cache里面没有开辟对应的区域怎么办,这就是所谓的写Cache Miss。: k/ h% Q2 _+ t8 c3 P $ v) e- ]( s# e1 o8 `8 y 3、H7支持的Cache策略,共4种 <回写:如果Cache中有,写数据只写到Cache,不写到RAM。> 7 W& A* N5 u: A0 q2 S <透写:如果Cache中有,写数据也要同时写到Cache和RAM。> <write allocate:写数据时,如果Cache中没有,那么就要在Cache中开辟一个空间,把数据写入Cache,同时把RAM中的相邻数据加载进来填充Cache。> <no write allocate:写数据时,如果Cache中没有,那么把数据直接写入RAM。>- Y3 x7 W% ]% \$ ` <read allocate:读数据时,如果Cache中没有,那么就要在Cache中开辟一个空间,把数据从RAM中加载进来,后续的读操作,就可以直接从Cache中读取了。> <no read allocate:读数据时,如果Cache中没有,那么直接从RAM中读。>7 h2 F6 q! x; V C2 l- ~1 d 4、风险$ l1 w+ q6 K0 ^5 @) K " F J3 e0 |" x* J8 i' g; ` 从上面的图就看出来使用Cache的风险,因为DMA是直接与SRAM交换数据的,而CPU与SRAM之间隔了一个Cache,如果DMA更新了某个数据到SRAM,CPU要去访问,而恰好Cache中有,那么CPU就不会去SRAM中拿,就会拿到Cache中已经过时的数据。因此使用了DMA的内存区要配置为无Cache或者拿数据前清一次Cache。 5、相关函数 SCB_EnableICache(void) :用于使能指令Cache,系统上电后优先初始化即可。 SCB_DisableICache(void) :用于禁止指令Cache。 SCB_InvalidateICache(void) :用于将指令Cache无效化,无效化的意思是将Cache Line标记为无效,等同于删除操作。这样Cache空间就都腾出来了,可以加载新的指令。 ~6 W5 {4 o" e$ Y* z) h' p % o8 q6 p# G' I7 E SCB_EnableDCache(void) :用于使能数据Cache,系统上电后优先初始化即可。( `. t# c4 ~; f 9 O# ~4 K* n7 G; Z0 y SCB_DisableDCache(void) :用于禁止数据Cache。! q% P" ^3 r2 s2 B- C7 E , E) e. |; m) [! q( ]' _/ f C; H SCB_InvalidateDCache(void) :用于将数据Cache无效化,无效化的意思是将Cache Line标记为无效,等同于删除操作。这样Cache空间就都腾出来了,可以加载新的数据。& ^/ c6 K) f3 g4 J; g% g% v& D 2 Y' N' @( i$ g& v* D1 s% ] SCB_CleanDCache(void):用于将数据Cache清除,清除的意思是将Cache Line中标记为dirty的数据写入到相应的存储区。 + }$ n% O; C; E5 m5 R SCB_CleanInvalidateDCache(void) :此函数是前面两个函数SCB_InvalidateDCache和SCB_CleanDCache的二合一。将Cache Line中标记为dirty的数据写入到相应的存储区后,再将Cache Line标记为无效,表示删除。这样Cache空间就都腾出来了,可以加载新的数据。7 U9 P9 m |3 ~- [3 a9 |% ]5 x( e1 v 7 ~- `- x6 x5 Y/ G: c" F) P SCB_InvalidateDCache_by_Addr(uint32_t *addr,int32_t dsize):可以指定地址和存储区大小,地址要32字节对齐,大小要是32字节的整数倍。用于将数据Cache无效化,无效化的意思是将Cache Line标记为无效,等同于删除操作。这样Cache空间就都腾出来了,可以加载新的数据。 + A1 q& O/ ^, b SCB_CleanDCache_by_Addr(uint32_t *addr,int32_t dsize):可以指定地址和存储区大小,地址要32字节对齐,大小要是32字节的整数倍。用于将数据Cache清除,清除的意思是将Cache Line中标记为dirty的数据写入到相应的存储区。6 |% m- I6 s' M+ Z3 a5 a 3 p& D! N+ R) D/ v: A SCB_CleanInvalidateDCache_by_Addr(uint32_t *addr,int32_t dsize):可以指定地址和存储区大小,地址要32字节对齐,大小要是32字节的整数倍。将Cache Line中标记为dirty的数据写入到相应的存储区后,再将Cache Line标记为无效,表示删除。这样Cache空间就都腾出来了,可以加载新的数据。! n3 T$ C) e- V+ R* }- y1 Z8 j - {0 P' ?4 m; A * ?. W5 \+ w0 u9 O: [. p ; r4 N% n: s5 I 二、MPU" U' k+ n/ V9 F) } P8 F5 \ % [6 y8 l) _0 ]# M+ ` 1、作用 防止不受信任的应用程序访问受保护的内存区域; 防止用户应用程序破坏操作系统使用的数据;通过阻止任务访问其它任务的数据区;允许将内存区域定义为只读,以便保护重要数据;检测意外的内存访问。 简单的说就是内存保护、外设保护和代码访问保护。( R$ X) B3 k& `5 f1 P$ w: w1 u3 b 2、MPU可以配置的三种内存类型 * s8 ~1 y( w( N! W7 A 1)、Normal memory / ]2 q- w! b/ M8 Q4 u: e/ y+ @ CPU以最高效的方式加载和存储字节、半字和字,对于这种内存区,CPU的加载或存储不一定要按照程序列出的顺序执行。 " x' g. b( V& \4 \1 V# L$ L 2)、Device memory 对于这种类型的内存区,加载和存储要严格按照次序进行,这样是为了确保寄存器按照正确顺序设置。 3)、Strongly ordered memory 程序完全按照代码顺序执行,CPU需要等待当前的加载/存储指令执行完毕后才执行下一条指令。这样会导致性能下降。 ( ~8 ~0 Q: }+ v/ W# }' j2 [/ G# T) g 3、MPU的使用 MPU可以配置保护16个内存区域(这16个内存域是独立配置的),每个区域最小要求256字节,每个区域还可以配置为8个子区域。由于子区域一般都相同大小,这样每个子区域的大小就是32字节,正好跟Cache的Cache Line大小一样。 + f2 Z& z- x0 j" g, j 使用时把一段连续的内存区配置为一个MPU保护区域,然后再配置这个MPU保护区域的特性。比如128KB的DTCM、64KB的SRAM4、32MB的SDRAM。MPU保护区域的特性使用MPU_RASR寄存器来配置,描述如下: 1)、XN:用于控制这个MPU保护区域能否执行程序代码。, O: X8 G: O: U2 M+ ~7 K ; C' U7 C$ E* ?& i8 A3 x- x+ q3 ] 2)、AP:用于控制这个MPU保护区域的特权级和非特权级的读写访问权限。0 v- O9 W% v' m5 B ; C- H; k. i$ H% E. h 3)、TEX、C、B、S:H7支持4种Cache策略,这几位就是用来控制这个MPU保护区域使用哪一种。2 I" D: }5 r. R) Y 4 _* o) R$ ~; ` S位用于解决多总线或者多核访问的共享问题,一般不要开启。 & a5 {3 y8 E8 u 4)、SRD:这个位用于控制内存区的子区域 ,使用的是bit[15:8],共计8个bit,一个bit控制一个子区域, 0表示使能此子区域, 1表示禁止。一般情况下,取值0x00,表示8个子区域都使能。 0 J- ?9 m. v+ R9 H0 h: N& X 5)、SIZE:配置这个MPU保护区域的大小。 1 S R' S1 y+ }( i0 x 三、HAL配置例程& _: X/ \$ L; @0 [ $ p( x) }- }# X& U* G
四、其他 值得一提的是,LTDC也是直接从RAM拿数据的,如果你使用了GUI(比如EMWIN),你的显示数据可能会暂存在Cache,而LTDC直接从RAM拿数据,就可能造成画面撕裂、重影、斑点之类的问题。解决方法是,把显存设置成透写。 2 e* B$ F% J0 g& p6 k 从下面的图可以看到,Cache是在M7那个框里面的。而框外面的外设都可以直接与RAM交换数据,因此使用外设操作数据时都要考虑一下Cache的影响,不然异常可能难以预料。 4 l; q3 W( ?: F* Q |
【经验分享】STM32_H7_ADC
STM32H7R/S高性能MCU:安全性,大存储和优异图显赋能更多应用创新
Stm32H7XX GCC下分散加载实现
【银杏科技ARM+FPGA双核心应用】STM32H7系列10——ADC
DIY-STM32H750核心板
[nucleo-H7A3ZI-Q]1-点亮一个皮皮灯
DIY-STM32H743核心板
【银杏科技ARM+FPGA双核心应用】STM32H7系列57——MDK_FLM
1月10日有奖直播 | 基于STM32 的CODESYS智能自动化解决方案
STM32的CAN FD位定时设置注意事项