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

【实战经验】STM32F7 MPU Cache浅析  

[复制链接]
zero99 发布时间:2017-3-3 14:54
前言$ n7 H2 E0 |( S) z' e( z
本文会从结构,原理以及应用方面对MPU和Cache进行分析,主要目的是希望读者对Cache有基本的了解,在具体的实际应用中,使用带有一级cache的MCU时,避免常见的错误。, [( Y8 C. C# l+ [! P: ~
1 {! y8 W) L& L
Cache介绍+ k3 t2 B+ V  U, k% d
. Z; P9 U! }8 }( x
Cache及其原理( h& A0 E- J  @, \9 ^9 A5 k$ ]
Cache,高速缓存,一般指的是L1 cache,即和Core紧耦合的,从STM32F7系列开始,7 t3 E  F+ d- E/ [& a# X" Y3 y4 o
基于ARM cortex-M7内核,增加了对L1 Cache的支持。! T3 a) \4 h# h" l; \0 j
21.jpg 8 J- h. e- y7 @+ t- A& B& M; A+ i5 p
从这张图片可以看出来,无论是指令Cache(I-cache)还是数据Cache(D-cache),一旦使能之后,就分别与Core的prefetch unit(I-cache)和load-store unit(D-cache)相连,以D-cache为例,因为
, v# T7 z& W8 B直接与LSU相连,访问速度会比直接访问SRAM或外部RAM快很多,只要保证cache有足够高的命中率(由cache策略保证),尽量少的cache miss,读/写的速度会有比较大的提高。
. u, h# K2 u# V* _7 v) i- O, g! e9 ^. u( o
结构及策略
6 _7 t1 U6 U4 q4 _  e9 u! s2 E同样这里以D-cache为例,看一下D-cache的构成:" W6 Z+ V# i. w* ?# Z1 B0 y. H! f
22.jpg . z9 P7 `, @4 S! \1 c! W
包括Address和cache-line,Address表明其地址,对应一条包含32bytes的cache-line:/ |2 |4 u, o9 |% r* p
读数据时,当地址命中时即cache-hit,便可以直接从cache line中取出相应的数据,反之,当遍历了address都没有找到,就会产生cache-miss,这时便会从实际的内存单元(如SRAM)中取出相应的数据,并更新到某一条cache-line中并修改相应的cache-line信息;) f7 v# j2 V% U
写数据时,就有点不同了,包括write-through策略和write-back策略,当使用write-though策略时,更新cache-line的同时,同样会更新其对应的实际物理地址的区域,当采用write-back策略时,更cache-line的同时,并不是马上去更新其对应的实际物理地址的内容,而是在其认为合适或者所有的cache-line都dirty的时候才会去更新,当然,也可以通过软件让其强制更新,即clean的动作,这一块会在后面的cache一致性问题上也会有体现;
; s, B# \: p- @5 y4 u同样,对于为什么将cache拆分为2-way或是4-way,这和cache自身的策略如查找算法等相关,由于本文侧重讨论cache的应用相关问题,所以关于cache本身的策略这里不再详述。
( ^0 S; X! j" U' b8 Y4 t1 _1 Y; |% f" w6 T6 j0 O
Cache及MPU属性2 ?2 |# T7 U9 V: L( }$ \
这里需要注意的是,cache一般是配合MPU(memory protection unit)一起使用的,首先需要通过MPU配置相应memory的属性(normal, strongly-ordered, device, XN etc.),如下表所示:
* r3 U% B: h7 X
23.jpg 5 R. g8 U" W# J( g
选取几个有特点的作为示例:
+ {' h6 P! h# i$ H7 x! q! m2 g* S0~0x1FFF_FFFF: flash空间,属性为normal,cache的属性为Write-through,即更新cache的同时,将数据同时写入相应的物理地址空间8 ]2 }) s4 m! A1 D
0x2000_0000~0x3FFF_FFFF: SRAM空间,属性为normal,cache的属性为write-back,即仅更新cache,在合适的时候(由cache策略决定或者软件强制更新)将数据更新到相应的SRAM空间1 W/ n" x0 c  q, q
0x4000_0000~0x5FFFF_FFFF: 芯片内部的外设空间,属性为device,这一版是外设寄存器所处的位置,对其读写的过程中不会经过cache; L7 T& \* F/ y; B

) a; X. P% w" O- C  ^, V  ?3 uXN的意思是Execute-Never,其含义为如果相应的地址空间是XN,是绝不允许执行代码的。
: B" [, |* v8 h! l' Z9 ~
+ ?" s2 N" C6 }4 A; z! LCache相关函数及作用
4 \! h8 r1 z2 G" ?5 E" {- A这里以core_cm7.h里对cache封装的函数为例
7 G4 P' v8 E/ S& u$ g( V0 g( F' x(C:\Program Files (x86)\IAR Systems\Embedded Workbench 7.2\arm\CMSIS\Include) " Q1 V! O+ R, j2 b, c
SCB_EnableDCache9 Y# d1 k; @3 z; _! P$ i: `0 y
## 使能D-cache
6 i7 U, a1 Z$ n9 j
8 e; F+ b8 i+ j9 c3 YSCB_DisableDCache
% R, X; K' u4 |3 i## 禁用D-cache

0 M& z7 d. Q: U' r% B% X3 x
' t$ [+ R# Q1 z, L. USCB_EnableICache1 J. L1 z4 L/ T- v
## 使能I-cache4 K( n( I% h: I* O2 {! Z+ i

8 z# X% _# G# OSCB_DisableICache
) v1 G  n( \4 K: N4 H## 禁用I-cache
  E4 g* l+ g- `! ?. }0 n7 Z; h$ W4 x8 I- l
SCB_CleanDCache / ^! f. O( E: ~# p4 w# V7 |* O
## Clean所有的cache-line,即将dirty的cache-line全部写到cache line对应的真实的物理地址中 所谓的drity属性,即写操作时,更新了相应的cache-line,但是没有更新到真实的物理地址, 而这个clean的动作,就是将cache中的内容更新到真实的物理地址中
6 F. j; e% x9 y- V9 ]0 p* j0 T6 b4 E; H- A' }. \
SCB_CleanDCache_by_Addr
# t% r! ]3 V0 `9 y: l2 c% h## 根据地址信息clean其对应的cache-line

$ _: b9 P# O- A, i' J8 U# C4 J
% L0 g! n2 J6 @( GSCB_InvalidateDCache
7 n4 Y- Q/ r  J- s$ t8 Y* s/ H/ @## 无效D-cache,D-cache被invalidate之后,当有Host(如core,DMA等)读取数据时,会忽略相应的cache-line中的内容(因为被validate了),从真实的物理地址中去获取相应的数据
% b9 a8 z6 X* ]3 m2 F) B- F, k0 i- r3 O
SCB_InvalidateDCache_by_Addr / h) Z7 ?" T) j- A( [
## 根据地址信息无效其对应的cache-line

, n3 ]' Q/ u. O) p) @6 P
, ^4 a9 E8 G/ vCache一致性问题) r/ K* O2 t8 k$ F
所谓的Cache一致性问题,主要指的是由于D-cache存在时,表现在有多个Host(典型的如MCU的core,DMA等)访问同一块内存时,由于数据会缓存在D-cache中而没有更新实际的物理内存。8 H' M- _& L( U. q* y
第一种情况是当有写物理内存的指令时,core会先去更新相应的cache-line(Write-back策略),在没有clean的情况下,会导致其对应的实际物理内存中的数据并没有被更新,如果这个时候有其它的Host(如DMA)访问这段内存时,就会出现问题(由于实际物理内存并未被更新,和D-cache中的不一致),这就是所谓的cache一致性的问题!' a+ x/ v5 B9 |. l/ u

% F/ U# @3 L, I7 u, A! [第二种情况是DMA更新了某段物理内存(DMA和cache直接没有直接通道),而这个时候Core再读取这段内存的时候,由于相对应地址的cache-line没有被invalidate,导致Core读到的是cache-line中的数据,而非被DMA更新过的实际物理内存的数据,下面这张图比较清晰的展示了上述两个过程:9 X; ~, T* @5 h# H% O" d' L
 ●第一种情况
8 g, m, ^; K! K3 }( W4 }$ T
24.jpg # `# n. D# y& a& ^5 R  y+ L8 V$ g

1 W5 H4 K  q6 z  `& p  N ●第二种情况+ I$ P& k" h( b9 G  \1 {) n
25.jpg
3 m# }( t! M$ I/ [* H* `" Y下面以一个实例来分析cache一致性问题,展示的是上面的第一种情况,如下图所示:
' C% o, |6 M- K8 X) ?- {* ]& `  Q
26.jpg
- @5 X  P2 n' J# f2 v先看一下这个例程数据的传输流程和路径:; O6 o2 Z$ {, k
● SRAM1_Buffer先全部写入0x559 ^- Y: X) G( n1 K% {* [
●Core将Flash中的Const_Buffer写入SRAM1_Buffer(这里会先经过d-cache)' j. }- P, D; Y8 M& {$ l. v' a
● 配置DMA,将SRAM1_Buffer中的数据通过DMA写入另一段内存DTCM_Buffer' Y. N5 X$ a- e' _0 ]% w0 T+ B
● 比较DTCM_Buffer中的数据和Flash中的Const_Buffer数据,看是否一致) G; q/ s* I" R# v

9 S9 o1 y$ ^: Q% h代码示例如下:  : V7 h) P3 @5 R: V! V
●MPU对memory的配置 - - - - step1
6 T6 [+ n& r* e/ A. I
27.jpg
8 e1 S! W; T' a2 V0 Y重点介绍一下高亮部分的配置:
: z- O* _) L0 T* x1 Q$ G● BaseAddress为要配置的存储空间的起始地址;' H4 v7 b3 M4 [6 k" {2 X
● Size为要配置的存储空间的大小
( ]8 N) P2 p7 B- s! C5 j4 I● IsCacheable表明这段存储空间是否可以cache
* Z9 D: ^4 q1 d0 q● IsBufferable表明使能cache之后,策略是write-through还是write-back(bufferable)6 m7 U0 J+ K9 z* t  M3 s
这里需要特别注意的1点:配置的BaseAddress需要被Size整除,以上述配置为例,即0x20010000除以256K需要是整数!( j& S7 i+ q9 s2 M! s8 l$ B

" x/ D! v# {% z* h● 使能Cache - - - - step2
8 ^8 f. l! g- o, r2 @2 l2 C
28.png ( p% ]! J! E  `0 o
5 I, X% c2 O) [) S( y% z' i6 W
●  初始化SRAM1_Buffer为0x55 - - - - step3
# Y* y/ Z& z# G3 B9 ~5 f. C1 a9 p  d   ● Copy Flash中的Const_Buffer到SRAM1_Buffer - - - - step4
* H. ^7 \+ B& v3 ]0 X5 c   ● 配置DMA,将SRAM1_Buffer写入DTCM_Buffer - - - - step5 + U/ {, I0 C6 o7 U2 m; o+ j
   ● 比较DTCM_Buffer和Const_Buffer,看是否一致 - - - - step6
0 u, `8 J2 s4 P' x从结果上看,最后一步比较的结果并不一致,原因比较简单,由于设定的WB策略,所以在step4的时候,数据会暂存在D-cache当中,并没有更新到SRAM1_Buffer,所以当SRAM1_Buffer被DMA拷到DTCM_Buffer中的时候,有一部分可能还是初始值,导致最终的比较不一样,而解决的方法有以下几个:/ U* |- y; X& v7 G) [1 g% ~& z
1. MPU配置的代码,将属性改为MPU_ACCESS_BUFFERABLE,即使用write-though策略
$ w$ m, P  E# }2. 通过cache控制寄存器,将所有cacheable的空间全部强制write-though1 N/ J8 E! i7 Y( R, ?! T: u
29.jpg 0 U" R: J1 |# q1 @
001.png
. v, w& f$ v7 o- B. @5 G' L! |! u: l+ d! V& O. ^: \+ T, q3 Q
3. 将dirty cache-line更新到真实的物理地址中
4 l4 X( c$ C9 l. ]% Lstep5操作之前,先调用SCB_CleanDCacheSCB_CleanDCache_by_Addr将相应cache-line中的数据写入SRAM1_Buffer,就解决了这个问题!' I% m$ D% o  V- L' d# t. r6 n: P
+ o/ M. M% Z8 I2 R5 S2 \  k+ x
这是最常用的方法,在实际的开发过程中,为了提高性能,一般都会使能cache,同时将其配置为WB策略,这就需要开发者在使用时特别小心!同样如之前的第二种情况,需要先调用SCB_InvalidateDCacheSCB_InvalidateDCache_by_Addr去Invalidate相应的cache-line,这样当core在读取时,会忽略D-cache中的内容,去真实的物理地址读取对应的数据!

0 G7 J/ b" C' u: S
8 z. B" \7 Q: w: r1 P7 v$ ?- E
# }. b8 n% a5 Y! r) ]
( W+ V& M* W. m5 e- z
文档下载, b/ v; a+ R& O, I5 u- K$ X

) K* K7 n# C6 U9 o0 p* h- U. U更多实战经验
4 p/ E9 O/ ]% \# Q% Z5 K

评分

参与人数 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。
$ g3 I3 {  N! ?% n
- o9 V4 l1 ^" _% _$ f( X- |/ e另外,执行 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& _  p, t5 X  `9 v5 v& _, f8 Q5 {
学习了,支持小破!
5 _& Y2 c; Y; _2 P' T
野火_firege 回答时间:2017-3-3 14:59:01
学习了
zero99 回答时间:2017-3-3 15:05:23
野火_firege 发表于 2017-3-3 14:59" o) F5 N( N" ~" h$ o
学习了
# F# g% A9 j4 z
火哥好
野火_firege 回答时间:2017-3-3 15:53:36
zero99 发表于 2017-3-3 15:05( r" u3 J, p& G# I$ w# ~- v
火哥好

0 p. d1 v9 J* h管理员好
Paderboy 回答时间:2017-3-3 16:07:57
学习来了。。。
Stm32McuLover 回答时间:2017-3-3 17:52:19
& u' T- q) z( J" W. x" P' _' K
学习了
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
学习学习,感恩无私的分享与奉献 9 d6 k# d6 |, u7 N- x, ]
jcx0324 回答时间:2017-3-6 08:59:13
好文章,学习了
ddllxxrr 回答时间:2017-3-6 09:15:29
写地不错,学习了
lorosir 回答时间:2017-3-6 09:56:34
收藏起来,将来用
12下一页
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版