你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【实战经验】STM32F7 MPU Cache浅析  

[复制链接]
zero99 发布时间:2017-3-3 14:54
前言
) w5 ~* g9 d) L/ m( w  c) D本文会从结构,原理以及应用方面对MPU和Cache进行分析,主要目的是希望读者对Cache有基本的了解,在具体的实际应用中,使用带有一级cache的MCU时,避免常见的错误。
8 h) D  t! U2 W2 {* b  h; H* B! w7 u# C3 `2 W+ [. u+ V/ i, Q4 C
Cache介绍  S# y. k% }* A/ z! H, l
- e" I* C* x1 C! l$ z8 V( k
Cache及其原理
, t0 c' f- P& p0 w) r- TCache,高速缓存,一般指的是L1 cache,即和Core紧耦合的,从STM32F7系列开始,
" b7 r8 D" E5 _% q1 \基于ARM cortex-M7内核,增加了对L1 Cache的支持。  K+ Q$ |) }: e8 P( ?" ^
21.jpg
2 C9 a' y+ k) w2 T从这张图片可以看出来,无论是指令Cache(I-cache)还是数据Cache(D-cache),一旦使能之后,就分别与Core的prefetch unit(I-cache)和load-store unit(D-cache)相连,以D-cache为例,因为2 I" X* {$ Y$ A. w! U+ ]/ F0 J+ @
直接与LSU相连,访问速度会比直接访问SRAM或外部RAM快很多,只要保证cache有足够高的命中率(由cache策略保证),尽量少的cache miss,读/写的速度会有比较大的提高。3 K0 x6 |( \2 z( K+ S+ K) q+ J

6 M8 B- {$ s! y9 G, s结构及策略( A: ]4 `0 C: n- C  \
同样这里以D-cache为例,看一下D-cache的构成:
; }# J( v+ @1 x) S6 G
22.jpg ' D0 ?6 Q/ K! X  I. h
包括Address和cache-line,Address表明其地址,对应一条包含32bytes的cache-line:; D8 |% {) j1 J. y8 U3 z
读数据时,当地址命中时即cache-hit,便可以直接从cache line中取出相应的数据,反之,当遍历了address都没有找到,就会产生cache-miss,这时便会从实际的内存单元(如SRAM)中取出相应的数据,并更新到某一条cache-line中并修改相应的cache-line信息;: M. E9 b! \8 S
写数据时,就有点不同了,包括write-through策略和write-back策略,当使用write-though策略时,更新cache-line的同时,同样会更新其对应的实际物理地址的区域,当采用write-back策略时,更cache-line的同时,并不是马上去更新其对应的实际物理地址的内容,而是在其认为合适或者所有的cache-line都dirty的时候才会去更新,当然,也可以通过软件让其强制更新,即clean的动作,这一块会在后面的cache一致性问题上也会有体现;
! }5 O( e1 F2 v, E( o4 K同样,对于为什么将cache拆分为2-way或是4-way,这和cache自身的策略如查找算法等相关,由于本文侧重讨论cache的应用相关问题,所以关于cache本身的策略这里不再详述。
# Q+ h' s1 D4 [6 u! |& }2 `3 B  `7 w! ?) e
Cache及MPU属性/ P. A) R* c  k
这里需要注意的是,cache一般是配合MPU(memory protection unit)一起使用的,首先需要通过MPU配置相应memory的属性(normal, strongly-ordered, device, XN etc.),如下表所示:/ u- g, [# [$ o$ U4 ^2 x' k/ b
23.jpg : Z" ~1 V, k- o
选取几个有特点的作为示例:
% ^% n1 A; J- r3 U0~0x1FFF_FFFF: flash空间,属性为normal,cache的属性为Write-through,即更新cache的同时,将数据同时写入相应的物理地址空间; Y! v. V9 R" t6 m$ x* u9 S$ }
0x2000_0000~0x3FFF_FFFF: SRAM空间,属性为normal,cache的属性为write-back,即仅更新cache,在合适的时候(由cache策略决定或者软件强制更新)将数据更新到相应的SRAM空间3 Z; I6 K: D$ \2 v
0x4000_0000~0x5FFFF_FFFF: 芯片内部的外设空间,属性为device,这一版是外设寄存器所处的位置,对其读写的过程中不会经过cache8 `. z! A& e' c8 K  c9 y% o

9 Y& d( e9 j, y; g9 TXN的意思是Execute-Never,其含义为如果相应的地址空间是XN,是绝不允许执行代码的。  Q; m* @6 M' @' {! H
& ?2 K: A  }) U. |0 v8 B" N
Cache相关函数及作用7 Y* d5 p3 E: t  O
这里以core_cm7.h里对cache封装的函数为例
1 s! }" f2 p! k6 z0 y(C:\Program Files (x86)\IAR Systems\Embedded Workbench 7.2\arm\CMSIS\Include) 1 H- |( V; N0 Z
SCB_EnableDCache- r9 [* I8 k7 B$ y" B2 M
## 使能D-cache
1 f% G/ ~, P8 h  y1 T- }3 }; S1 J% A" f- S
SCB_DisableDCache
7 H! O* Q. Z8 i1 s## 禁用D-cache
) l: Z' B0 h8 j1 @* t( P
# v( u& X! p1 {: @/ s* `3 ^3 b+ t: a
SCB_EnableICache
. a( Q% G2 c2 l) R% I## 使能I-cache
5 p2 u$ g& T; H# k: D
: w. K, Z8 C( ?; ]: _% Z3 aSCB_DisableICache
# X3 o6 J2 W3 E, C5 i## 禁用I-cache
3 D: p+ c- k  L1 O! ?' t0 h) v/ h: O- ]  Z6 _6 A
SCB_CleanDCache : E7 i& c$ ~  c% u7 q6 d8 @
## Clean所有的cache-line,即将dirty的cache-line全部写到cache line对应的真实的物理地址中 所谓的drity属性,即写操作时,更新了相应的cache-line,但是没有更新到真实的物理地址, 而这个clean的动作,就是将cache中的内容更新到真实的物理地址中
! P7 j( t4 y/ a3 n' J8 l5 T( z1 }3 I
SCB_CleanDCache_by_Addr
7 Y- X1 I1 Z" g/ C4 U8 U' Y  m## 根据地址信息clean其对应的cache-line

  H. s4 M* U5 v2 M( C" W* e
! Z$ q$ q3 S, g7 W4 [+ X4 w/ Y1 OSCB_InvalidateDCache 6 U7 y- o7 e, \- s
## 无效D-cache,D-cache被invalidate之后,当有Host(如core,DMA等)读取数据时,会忽略相应的cache-line中的内容(因为被validate了),从真实的物理地址中去获取相应的数据; c- i# `3 P& M+ o
: a5 R: w$ y: V* }2 n
SCB_InvalidateDCache_by_Addr
8 y" i7 S- W- D# g$ q* x2 L## 根据地址信息无效其对应的cache-line

3 B/ m4 C; p. G- d
) }# o9 B6 h8 X; S) {Cache一致性问题
$ r8 Y' n2 x! d+ z  {所谓的Cache一致性问题,主要指的是由于D-cache存在时,表现在有多个Host(典型的如MCU的core,DMA等)访问同一块内存时,由于数据会缓存在D-cache中而没有更新实际的物理内存。3 ?- F, y' ?8 E: f
第一种情况是当有写物理内存的指令时,core会先去更新相应的cache-line(Write-back策略),在没有clean的情况下,会导致其对应的实际物理内存中的数据并没有被更新,如果这个时候有其它的Host(如DMA)访问这段内存时,就会出现问题(由于实际物理内存并未被更新,和D-cache中的不一致),这就是所谓的cache一致性的问题!1 n8 w$ f7 o) h7 S& D( p: }
7 x2 w3 c2 i% m0 R: G: `: b+ I3 }
第二种情况是DMA更新了某段物理内存(DMA和cache直接没有直接通道),而这个时候Core再读取这段内存的时候,由于相对应地址的cache-line没有被invalidate,导致Core读到的是cache-line中的数据,而非被DMA更新过的实际物理内存的数据,下面这张图比较清晰的展示了上述两个过程:. e" v0 Q; \* B/ W# L
 ●第一种情况+ h( x. ~0 P9 g& ]5 O
24.jpg - q' _+ r! `* w* x4 Y

- S4 r" Y# E' W/ n ●第二种情况
" z6 |7 y( H- ?' r; o* u
25.jpg
" l) v& ^5 I0 Q- J/ T下面以一个实例来分析cache一致性问题,展示的是上面的第一种情况,如下图所示:
. M( b% F, ^. a0 g' H+ h
26.jpg 6 ?! D. p" [% G3 ?  K
先看一下这个例程数据的传输流程和路径:
  W( o0 v. o& S$ R! d+ y3 U● SRAM1_Buffer先全部写入0x55
9 \4 E8 a; x# i$ v, M●Core将Flash中的Const_Buffer写入SRAM1_Buffer(这里会先经过d-cache)
. t4 k: n" X1 P/ R7 S* j* J9 Y: }● 配置DMA,将SRAM1_Buffer中的数据通过DMA写入另一段内存DTCM_Buffer
) y. ^+ A# a) l( X& Y2 _● 比较DTCM_Buffer中的数据和Flash中的Const_Buffer数据,看是否一致! n; x/ W8 u% g9 X8 T3 v
  v1 [) i$ P/ k! C7 B
代码示例如下:  * F6 Q3 C1 Y1 e3 D  {2 Y
●MPU对memory的配置 - - - - step1; ~/ u9 L0 K" F# B
27.jpg
8 ^' c# N" T: A  O重点介绍一下高亮部分的配置:
1 y# S) A" Y, ^5 F% D● BaseAddress为要配置的存储空间的起始地址;
2 C0 |1 q$ Z; h: t$ ]! z! J( W● Size为要配置的存储空间的大小& B( b* d, K4 [4 }/ i
● IsCacheable表明这段存储空间是否可以cache
7 A4 `8 i& x$ W4 c( i$ G● IsBufferable表明使能cache之后,策略是write-through还是write-back(bufferable)
0 @/ I) R" Z. A+ {* i6 K0 T, X这里需要特别注意的1点:配置的BaseAddress需要被Size整除,以上述配置为例,即0x20010000除以256K需要是整数!
; ]' L0 X9 i3 z& f: I) r( ~# T; P( z2 N' \' y) r
● 使能Cache - - - - step2
% S; B3 e9 C6 F$ l7 @
28.png   i+ Q3 o: N% T: o8 y
% ~+ F: v1 p2 e8 b
●  初始化SRAM1_Buffer为0x55 - - - - step3 ( L9 k$ m3 i- Z) Y% h0 l
   ● Copy Flash中的Const_Buffer到SRAM1_Buffer - - - - step4
# `5 @9 }5 n2 X* i   ● 配置DMA,将SRAM1_Buffer写入DTCM_Buffer - - - - step5
3 H; `! q$ @% i8 Z5 N" C4 V/ y   ● 比较DTCM_Buffer和Const_Buffer,看是否一致 - - - - step6
; k( k7 z; q, z9 y/ Y从结果上看,最后一步比较的结果并不一致,原因比较简单,由于设定的WB策略,所以在step4的时候,数据会暂存在D-cache当中,并没有更新到SRAM1_Buffer,所以当SRAM1_Buffer被DMA拷到DTCM_Buffer中的时候,有一部分可能还是初始值,导致最终的比较不一样,而解决的方法有以下几个:0 k% M0 P: ]- o# ~8 }; y
1. MPU配置的代码,将属性改为MPU_ACCESS_BUFFERABLE,即使用write-though策略: e/ d% ~! @! z' N6 J" k, [! r
2. 通过cache控制寄存器,将所有cacheable的空间全部强制write-though
2 i3 K2 q$ o4 l& h9 E
29.jpg ( S$ Y5 o5 n: n/ }
001.png
2 r! l! y" c3 \: ]
2 [6 z) i* P4 n3. 将dirty cache-line更新到真实的物理地址中
1 n: V, ?  f: k; ystep5操作之前,先调用SCB_CleanDCacheSCB_CleanDCache_by_Addr将相应cache-line中的数据写入SRAM1_Buffer,就解决了这个问题!0 K  L3 [* F, [% S( J0 I
& Z0 b3 k1 g& d) R6 t
这是最常用的方法,在实际的开发过程中,为了提高性能,一般都会使能cache,同时将其配置为WB策略,这就需要开发者在使用时特别小心!同样如之前的第二种情况,需要先调用SCB_InvalidateDCacheSCB_InvalidateDCache_by_Addr去Invalidate相应的cache-line,这样当core在读取时,会忽略D-cache中的内容,去真实的物理地址读取对应的数据!

8 W+ Q. W: \5 ~7 H5 f! B  c" l& }- c1 c, y5 l  Z/ {
" g! n9 D! Y0 E# q. d
' c4 `( V: C3 I( g1 K' V5 u
文档下载8 }  P/ C/ R, a' L/ q7 c5 u
+ o. }8 W& A* J  {
更多实战经验7 Y) Z& L8 N8 l9 Y* D  d- K: j

评分

参与人数 1 ST金币 +10 收起 理由
MrJiu + 10 支持原理讲解!!!!

查看全部评分

1 收藏 11 评论19 发布时间:2017-3-3 14:54

举报

19个回答
xzrsh 回答时间:2019-8-16 12:23:32
这个是有问题的。 Cacheable = 1 且 Bufferable = 1 是 WBWA。
. y! S. x- v: w4 o9 e3 Q! N" u2 ~8 R& f* \
另外,执行 SCB_InvalidateDCache或SCB_InvalidateDCache_by_Addr 的时候会调用“__DSB();   __ISB();”这两个操作,即等待当前数据cache操作由指令完成,彻底打断了当前CPU的执行节奏(清空指令cache)。假如当前DMA从外设读取了10字节数据到SRAM中,在DMA中断里更新接收计数器为10(这个计数器操作是CPU完成的,将写入到cache中),如果中断后调用了InvalidateDCache,会导致计数器的写操作无效,因为写cache操作已经完成了,其策略是WB,它写入的是Cache,并没有写入到物理存储器中。当下次CPU要读取这个计数器值时,仍从Cache中读取,发现这个地址已经被Invalidate了,那么要从SRAM中读,结果是0。
Dandjinh 回答时间:2017-3-13 10:21:50
1. MPU配置的代码,将属性改为MPU_ACCESS_BUFFERABLE,即使用write-though策略
这里确定是BUFFERABLE是write-through?我怎么觉得是write-back呢?
zero99 回答时间:2017-3-7 15:40:18
donatello1996 发表于 2017-3-4 11:41$ N" W# w& @; {' a* A
学习了,支持小破!
. `$ L6 ?9 }% W
野火_firege 回答时间:2017-3-3 14:59:01
学习了
zero99 回答时间:2017-3-3 15:05:23
野火_firege 发表于 2017-3-3 14:59- h; Y5 a; x) F' v$ L
学习了

" B4 k, C' ~" o, H火哥好
野火_firege 回答时间:2017-3-3 15:53:36
zero99 发表于 2017-3-3 15:05+ X( e3 L2 W6 t& S0 f+ v" @* N9 l$ V
火哥好

* c* ]& b9 T6 L2 X* g& b6 n* S管理员好
Paderboy 回答时间:2017-3-3 16:07:57
学习来了。。。
Stm32McuLover 回答时间:2017-3-3 17:52:19
  h# J5 d  ~& _) ~; |; c
学习了
zoomdy 回答时间:2017-3-3 21:12:49
收藏,学习再学习
斜阳 回答时间:2017-3-4 08:48:55
学习学习
epochal 回答时间:2017-3-4 09:24:23
学学!
五哥1 回答时间:2017-3-4 09:38:17
这让人想起inter芯片的发展历程
donatello1996 回答时间:2017-3-4 11:41:28
学习了,支持小破!
zbber 回答时间:2017-3-4 22:04:28
学习学习,感恩无私的分享与奉献
4 a! \. }4 [' b% `4 B/ E2 h
jcx0324 回答时间:2017-3-6 08:59:13
好文章,学习了
ddllxxrr 回答时间:2017-3-6 09:15:29
写地不错,学习了
lorosir 回答时间:2017-3-6 09:56:34
收藏起来,将来用
12下一页

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版