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

【经验分享】STM32H7的Cache与Buffer

[复制链接]
STMCU小助手 发布时间:2021-12-26 17:22
STM32H7的Cache与Buffer
: V' @* v* G8 f  mTCM和Cache的区别

) q2 C! H3 T" p; v…使用lwip用到了mpu,对于内存管理产生了很多的疑问,需要统一解决一下,不然用起来总有些不安。
' k3 `9 R+ _, V$ X1 v! j3 q8 g8 ~! Q
STM32H7使用的内存不是连续的,而是被划分为多段。
! I+ L1 Z8 u! e7 Q2 {* w, W$ y
% d. s- s; J( A1 p& J# U. g- R
  1. MEMORY
    8 q" Z) }6 |3 @- h+ I; c
  2. {
      N# E& k4 H& r  K7 \
  3.         DTCMRAM (xrw)     : ORIGIN = 0x20000000, LENGTH = 128K //高速段,cpu独享/ Q9 z: k8 B) s, @' \
  4.         RAM_D1 (xrw)      : ORIGIN = 0x24000000, LENGTH = 512K/ Q( P" f9 X2 p; g
  5.         RAM_D2 (xrw)      : ORIGIN = 0x30000000, LENGTH = 288K
    / T/ E- b+ R3 L( ^
  6.         RAM_D3 (xrw)      : ORIGIN = 0x38000000, LENGTH = 64K! U; ^# O  ^: O- ?8 h% [) F# o
  7.         ITCMRAM (xrw)     : ORIGIN = 0x00000000, LENGTH = 64K //高速段,cpu独享" H2 m8 i4 G& A  |# Q
  8.         FLASH (rx)        : ORIGIN = 0x8000000, LENGTH = 128K
    ' o* a  H) N" h9 L8 V
  9. }
复制代码

0 w1 B; J* P: k, TTCM内存段是和CPU同频率的,不需要也不能用Cache。用好TCM的优先级应该排在用好Cache的前面。7 N/ z$ }% _, P! b9 ?9 X
Cache处于核心里面,作为低速内存加速器使用,获得增益最大的是位于AXI总线上的比如内部Flash、内部SRAM、通过FMC或者QSPI控制器连接的外部sram。Cache使得低速Sram获取与高速TCM差不多的速度。使用Cache加速很有意义,不然400M的cpu变200M,相当于H7变F4,选择H7的cpu将变得没有意义。
* w# z( j- p5 V" S7 t% _6 |: A$ `9 O2 }/ |
20201019190212727.png

/ S& ?- H( I& r% R
. h6 ]! U3 P$ I) J6 `内存类型% y+ z2 m& }  i! R1 z3 J
内存类型分为Normal以及Device和Strongly-ordered,
; _4 F( l! h* ^+ ?/ h/ _, U2 I7 i0 b( V
I5LW_ZQ_SY3W%I@][7RY56T.png

" F, k: p* o7 e8 D- K9 Q- R! z
4 J$ f( O% f. S
20201019190230823.png

9 x* y, p+ ?! ?- p% i2 ^1 @* S4 N; u! r# [
- v* r' t. F7 L3 o3 M
Write-buffer是什么?7 w) M$ v3 p- ^) U: \$ q
Device和Strongly-Ordered类型时候提到了write-buffer,它属于cpu核心,cache经常与write-buffer一起使用,使用writer-buffer的目的是将处理器和cache从较慢的对主存的写操作中脱离出来。! [# [3 Z; K# s) a
Write buffer可以缓存8个word的数据和4个独立的地址,可以enable或者disable使用ARM核心控制寄存器 W的bit3。同时还要受到内存管理页表的一个bit控制,所以使用Write-Buffer,MMU必须已经使能(控制寄存器的bit0)。MMU-Memory Management Unit* w; H& v( X2 D; q, B6 V6 q4 x
通常情况下的配置都是主内存允许bufferable,但是I/O 空间 unbufferable
: |; X  r# h' K* i8 M当CPU执行一个写操作时,根据配置情况执行写入操作。6 ]6 c, [: t$ o2 s! {6 b0 W5 r

# E8 W* t6 S5 w6 E2 b( ]+ C

; s2 |: B. E+ ]4 V2 j! f) ^6 R- ?( b# l9 s; @
20201019190300772.png
9 [1 V8 m9 s" d2 F/ U% q
, s2 v1 D& I) T: ?3 n- Z( I8 h0 c( g
如果程序中使用DMB and DSB,处理器会等到write-buffer内指令完成,再进行后续指令操作,如果过程中发生中断,中断返回后继续write-buffer清空等待。
5 x, T  s- [# U) {1 A0 p. N* s9 |% U: f' C+ ~2 i' J, D
DMB或者DSB被称为 显式限制操作 explicit barrier。+ ?# s9 o/ E: U/ @1 n  f2 B! Z
2 {; L, k5 C! H4 o+ S, W  i
20201019190244953.png

) g  H8 p% B  b3 z( ]9 K" A( [1 d2 @7 E2 g, Q- r9 d
Memory Attrabute
2 i/ n1 ]! i( f; O7 fNormal模式下可以设定的几种
" g1 u7 \+ e: e) I4 u2 {5 H3 P) n3 k# h+ V, K6 ?* d/ S- Q2 W+ g, c# O1 k# O
UXF0GF8D%6@3RQT%LAI76.png
( R4 \5 x  @9 t5 @( b. f8 [

$ g0 R# s2 e! j1 a  o+ W7 N) vShareable属性% e. G& }5 z% K  o; n0 m1 G
共享属性设计的意义在于,多个bus master读写情况下需要cache保持同步,对于CortexM7,只有L1-Cache,如果设置了Shared相当于non-cacheable。% i& {+ q9 B. s8 E/ W6 u- n

2 f! x! F8 J$ P/ Q6 X
20201019190314464.png

/ @; I, `. P& B, s1 p+ w  Z2 }- s' m- c0 G, @
内核操作函数
! V6 i9 V' d; r- r$ t+ C内核操作函数包含以下几种,主要包含两种操作:clean和invalidate。, `$ N2 V8 i2 c8 y6 R6 m
clean:将cache中的信息写到sram,相当于用cache信息覆盖sram;
+ M3 d, X  x: L, {, d9 binvalidate:使cache失效,相当于用sram信息覆盖cache;
. t; C# L$ J& G9 A% V二者为相反的操作。4 g$ `9 S; f1 R+ |4 N
' K! r$ j, C- S8 r7 ~
2020101919032876.png

& r" X; N" W- f; x; g) G9 F) [, F, H& T" g* R1 @' T0 C
20201019190336970.png

* d: q/ K- v6 l
. m: y) F  @: R& h6 V; V* c9 n/ y5 g* U' Q6 L6 f0 \, m" Q
内存对齐问题
& g6 z, ?/ N  ?- X& c/ u' L/ F使用cache时,dma的buffer必须32byte对齐,不然可能会出现问题。比如下面的情况:
7 U4 H1 N! S9 k5 H' u) z
* h& N2 O! Y# f5 l! V! D) E
  1. typedef struct" @% I- @1 t+ w: e* q
  2. {
    $ f; G, z7 _4 ]
  3.     __attribute__ ((aligned (32))) uint8_t rx_buffer[BUFFER_SIZE];//用于buffer
    ; v: N1 l, H! g0 [
  4.     bool rx_xfer_done;                                     //用于记录dma已经被正确传输' ?5 r9 g# u/ r- e# N4 C8 }* N# |
  5. }st_dma_xfer
    9 P/ O& X& Z- J) ^$ w; {) n! Y5 K( z

  6. 9 O% \! P. _  s/ \5 ]* t
  7. void XDMAC_Handler(void)
    5 E& t0 }, Q' s% V2 A
  8. {
      c" b# d9 a$ p0 X) a, ^3 e
  9.     uint32_t dma_status;
    6 I: \$ O8 t4 W7 y* V$ P  n5 B
  10.     dma_status = xdmac_channel_get_interrupt_status(XDMAC, XDMA_CH_RX);' q5 m. W  P1 ^/ ~8 `
  11.     if (dma_status & XDMAC_CIS_BIS)% P4 y3 L+ z. r; A0 b
  12.     {
    3 p, b. g; P7 ]5 I9 C) x  ^) Q
  13.       g_st_dma_xfer.rx_xfer_done = true;: M$ b' ]* H; R0 C+ c8 |
  14.       SCB_InvalidateDCache_by_Addr((uint32_t*)g_st_dma_xfer.rx_buffer, DMA_TRANSFER_SIZE);4 h/ Z4 w1 [6 z0 i$ u3 `) q* t
  15.     }5 z: J: h& q1 e2 `  ]
  16. }
复制代码
9 T8 Z" U) k! o  A5 J% A
0 t6 E. O2 n% Z! \3 J( ~
如果DMA的buffer只有16字节,DMA读取操作后,DMA控制器将接收到的数据写到了sram里面,然后进入DMA接收中断函数,cpu把成功读取的标识bool变量写为true,实际上写操作只是写在D-Cache里面,暂时没有写到sram。% A' c% C+ k& l! C/ R0 I/ W

" Z# a% S" t: d7 {9 N- j" N
20201019190359602.png

) i' s( \, {' ~% @9 R: c) |" Y
1 ~3 q8 ^/ P, G; e: M: i6 ]如果此时cpu需要读取dma内容,需要对Dcache进行invalid操作,32个字节将一起更新,bool变量旧值0将覆盖新值1。cpu读不到中断函数写的bool变量信息。* k( Q. d5 h0 v% M1 S
1 V  A7 j* U7 l
20201019190409891.png
1 w1 p* S2 N7 A  j: s! d8 t2 q) O! ]

" X$ }- ^( N/ a# n5 H可见:
( W# u+ ~- z6 [7 _) yclean操作或者Invalidate操作都可能丢东西,使用上需要注意。经验是如果一段内存用来写dma外设,就不要读它,保证随时都可以clean;同样如果一段内存用来接收DMA外设传入信息,就不要用cpu写它,保证随时都可以invalidate。4 Y5 Y/ q# A; V+ [4 R8 V! a$ }

5 T  ]8 o$ p/ s
2020101919042042.png

0 r6 S" p4 l) p' g; q' q) w: D5 ?: v& c- M

, Z0 n  ^$ ~/ [4 h% \7 b3 v9 B, Z: R
收藏 评论0 发布时间:2021-12-26 17:22

举报

0个回答
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版