STMCU小助手
发布时间:2021-12-18 17:42
|
一、Cache1 e+ ^6 x2 W9 m' U 5 T6 i4 q2 ]4 @* C0 P5 `7 N/ Z- _ 1、介绍 Cache又分数据缓存D-Cache和指令缓冲I-Cache,STM32H7的数据缓存和指令缓存大小都是16KB。STM32H7主频是400MHz,除了TCM和Cache以400MHz工作,其它AXI SRAM,SRAM1,SRAM2等都是以200MHz工作。数据缓存D-Cache就是解决CPU加速访问SRAM。 5 t7 J4 X7 h+ l7 Y 如果每次CPU要读写SRAM区的数据,都能够在Cache里面进行,自然是最好的,实现了200MHz到400MHz的飞跃,实际是做不到的,因为数据Cache只有16KB大小,总有用完的时候。; `0 p/ m% W0 k7 B8 G5 W 2、操作,分为读操作和写操作 读操作: 如果CPU要读取的SRAM区数据在Cache中已经加载好,这就叫读命中(Cache hit),如果Cache里面没有怎么办,这就是所谓的读Cache Miss。 ; @- j+ d+ l6 @ v& \) z+ I 写操作: 如果CPU要写的SRAM区数据在Cache中已经开辟了对应的区域(专业词汇叫Cache Line,以32字节为单位),这就叫写命中(Cache hit),如果Cache里面没有开辟对应的区域怎么办,这就是所谓的写Cache Miss。 : e' z8 p2 D/ E1 E 3、H7支持的Cache策略,共4种& Q( U/ n' c) j* F4 { % w k+ y. d9 m
<回写:如果Cache中有,写数据只写到Cache,不写到RAM。> <透写:如果Cache中有,写数据也要同时写到Cache和RAM。> " ^8 ~: R# `& p <write allocate:写数据时,如果Cache中没有,那么就要在Cache中开辟一个空间,把数据写入Cache,同时把RAM中的相邻数据加载进来填充Cache。>+ M- i" k: P2 o. v6 [4 E: P- z <no write allocate:写数据时,如果Cache中没有,那么把数据直接写入RAM。>7 H' k5 L1 m9 T8 F % m1 c, v3 Z' o1 a4 R# \ <read allocate:读数据时,如果Cache中没有,那么就要在Cache中开辟一个空间,把数据从RAM中加载进来,后续的读操作,就可以直接从Cache中读取了。> 8 c* ]) o9 H; j: E. k <no read allocate:读数据时,如果Cache中没有,那么直接从RAM中读。> ) M1 D1 h$ P7 V( p% n. O5 L- A: p 4、风险. f8 _( {# f K$ }
( q# A( ^* y; U 从上面的图就看出来使用Cache的风险,因为DMA是直接与SRAM交换数据的,而CPU与SRAM之间隔了一个Cache,如果DMA更新了某个数据到SRAM,CPU要去访问,而恰好Cache中有,那么CPU就不会去SRAM中拿,就会拿到Cache中已经过时的数据。因此使用了DMA的内存区要配置为无Cache或者拿数据前清一次Cache。1 T& u- |; G7 G1 D 4 J$ J, m4 ]( x" ]8 G7 J9 l& c+ c 5、相关函数! T4 d. t1 \& G' T& |: I! M i 5 B0 U* c6 m1 S0 C: o2 l SCB_EnableICache(void) :用于使能指令Cache,系统上电后优先初始化即可。; O. V( L' S5 ]8 P SCB_DisableICache(void) :用于禁止指令Cache。 6 }. u. Y. L f3 X SCB_InvalidateICache(void) :用于将指令Cache无效化,无效化的意思是将Cache Line标记为无效,等同于删除操作。这样Cache空间就都腾出来了,可以加载新的指令。7 V* W4 }2 W' [& r 6 \; R% ~- h( L! @; ~4 m SCB_EnableDCache(void) :用于使能数据Cache,系统上电后优先初始化即可。 ; b# z6 H9 g3 L! U SCB_DisableDCache(void) :用于禁止数据Cache。 SCB_InvalidateDCache(void) :用于将数据Cache无效化,无效化的意思是将Cache Line标记为无效,等同于删除操作。这样Cache空间就都腾出来了,可以加载新的数据。4 w. ~* H6 F( B# k SCB_CleanDCache(void):用于将数据Cache清除,清除的意思是将Cache Line中标记为dirty的数据写入到相应的存储区。 ; P' W* n4 x/ O( I, Q- V SCB_CleanInvalidateDCache(void) :此函数是前面两个函数SCB_InvalidateDCache和SCB_CleanDCache的二合一。将Cache Line中标记为dirty的数据写入到相应的存储区后,再将Cache Line标记为无效,表示删除。这样Cache空间就都腾出来了,可以加载新的数据。# n5 \. e0 E( i, B SCB_InvalidateDCache_by_Addr(uint32_t *addr,int32_t dsize):可以指定地址和存储区大小,地址要32字节对齐,大小要是32字节的整数倍。用于将数据Cache无效化,无效化的意思是将Cache Line标记为无效,等同于删除操作。这样Cache空间就都腾出来了,可以加载新的数据。. s3 ^: B. G; W- L- y) M( A! a5 M SCB_CleanDCache_by_Addr(uint32_t *addr,int32_t dsize):可以指定地址和存储区大小,地址要32字节对齐,大小要是32字节的整数倍。用于将数据Cache清除,清除的意思是将Cache Line中标记为dirty的数据写入到相应的存储区。# h8 I) ]& l0 j8 w3 l2 t2 C: y ! x1 ^6 v$ b7 l; @7 T% F; s SCB_CleanInvalidateDCache_by_Addr(uint32_t *addr,int32_t dsize):可以指定地址和存储区大小,地址要32字节对齐,大小要是32字节的整数倍。将Cache Line中标记为dirty的数据写入到相应的存储区后,再将Cache Line标记为无效,表示删除。这样Cache空间就都腾出来了,可以加载新的数据。; G1 @! r+ D5 a* v8 i9 d, O! ~ # n3 E0 |' a6 ~1 T! R- ~8 Z* N k N3 i8 d* v3 D. ] 二、MPU, n7 d) `+ t' V7 Z 1、作用 " E# w9 [* ^6 d* Q. E D 防止不受信任的应用程序访问受保护的内存区域; 防止用户应用程序破坏操作系统使用的数据;通过阻止任务访问其它任务的数据区;允许将内存区域定义为只读,以便保护重要数据;检测意外的内存访问。 简单的说就是内存保护、外设保护和代码访问保护。 2、MPU可以配置的三种内存类型* r8 p% [; J0 y; ]. c 1)、Normal memory CPU以最高效的方式加载和存储字节、半字和字,对于这种内存区,CPU的加载或存储不一定要按照程序列出的顺序执行。 2)、Device memory: m1 R+ G* b. ^8 l( M : d7 N+ W6 H X1 A$ a; o; F% Y 对于这种类型的内存区,加载和存储要严格按照次序进行,这样是为了确保寄存器按照正确顺序设置。; s# ?: f" h( U3 J7 ^, Z3 J , A, [& c8 l' k8 {6 q& a 3)、Strongly ordered memory 程序完全按照代码顺序执行,CPU需要等待当前的加载/存储指令执行完毕后才执行下一条指令。这样会导致性能下降。 3、MPU的使用1 y6 {6 u6 L4 M3 ]/ o0 a, g8 V U, f MPU可以配置保护16个内存区域(这16个内存域是独立配置的),每个区域最小要求256字节,每个区域还可以配置为8个子区域。由于子区域一般都相同大小,这样每个子区域的大小就是32字节,正好跟Cache的Cache Line大小一样。2 O( J% T- N4 b2 o0 P& q# Q: { \ , X; P4 J2 V5 V/ {* a0 u( {" S 使用时把一段连续的内存区配置为一个MPU保护区域,然后再配置这个MPU保护区域的特性。比如128KB的DTCM、64KB的SRAM4、32MB的SDRAM。MPU保护区域的特性使用MPU_RASR寄存器来配置,描述如下:& o' r8 Q, O( X; l" \1 Q ! ?5 F. F/ h: J. i1 Z
1)、XN:用于控制这个MPU保护区域能否执行程序代码。6 r4 F% `4 a6 ]7 |2 z0 t 2)、AP:用于控制这个MPU保护区域的特权级和非特权级的读写访问权限。 T1 t5 P, d- l5 o7 J6 a; |
3 u& L Z( E. P' W$ a8 ] 3)、TEX、C、B、S:H7支持4种Cache策略,这几位就是用来控制这个MPU保护区域使用哪一种。 $ Y0 x2 R; [) O6 S: Z8 w
S位用于解决多总线或者多核访问的共享问题,一般不要开启。 4)、SRD:这个位用于控制内存区的子区域 ,使用的是bit[15:8],共计8个bit,一个bit控制一个子区域, 0表示使能此子区域, 1表示禁止。一般情况下,取值0x00,表示8个子区域都使能。6 s6 m, g) I$ Z$ C; Q 0 I- h6 r8 q2 X& e4 _* u7 r5 k1 G" } 5)、SIZE:配置这个MPU保护区域的大小。) }+ \% q( Q$ c 三、HAL配置例程
四、其他 7 h) k9 K( W9 G5 y' W6 r 值得一提的是,LTDC也是直接从RAM拿数据的,如果你使用了GUI(比如EMWIN),你的显示数据可能会暂存在Cache,而LTDC直接从RAM拿数据,就可能造成画面撕裂、重影、斑点之类的问题。解决方法是,把显存设置成透写。1 z! p6 u- T3 D+ S 3 g/ A( S# y6 T! k7 I) k 从下面的图可以看到,Cache是在M7那个框里面的。而框外面的外设都可以直接与RAM交换数据,因此使用外设操作数据时都要考虑一下Cache的影响,不然异常可能难以预料。 # K" v2 b1 E4 S0 v8 L
4 x& ?+ q/ c" {2 D- @ 8 H _/ S; U6 c& R( W0 S, F$ s# } |
【STM32H735G-DK测评】lvgl移植
【STM32H735G-DK 测评】STM32H735G-DK External Loder 编译和测试
【福利三:逢7发帖赢大礼】使用MPU6050模块、img_dsc、img_btn机制实现一些简单有趣的动画效果
【福利三:逢7发帖赢大礼】使用arc弧形拉条控件控制PWM舵机及使用SPI3接口操作NRF24L01模块进行无线通信
【福利三:逢7发帖赢大礼】调试nucleo-WBA65RI工程测试样板的一些心得
【福利三:逢7发帖赢大礼】lv_timer和BME680实现温度、湿度、气压数据读取
【福利三:逢7发帖赢大礼】成功利用STM32H743VI片内SRAM12和DTCM空间(完全胜利)
【福利三:逢7发帖赢大礼】想要充分利用STM32H743VI片内的RAM空间(但并不顺利)
【福利三:逢7发帖赢大礼】使用惠勤致远STM32H743VI开发板+ST7796并口彩屏移植LVGL9.5并分享一些额外内容
【 逢7发帖赢大礼】7、TouchGFX中实现云彩流动效果
微信公众号
手机版