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

【经验分享】STM32H7的Cache与Buffer

[复制链接]
STMCU小助手 发布时间:2021-12-26 17:22
STM32H7的Cache与Buffer
  j( z  T+ `: Q7 OTCM和Cache的区别
4 E/ s$ y; o  ^% k% g, ^( A7 \2 a
…使用lwip用到了mpu,对于内存管理产生了很多的疑问,需要统一解决一下,不然用起来总有些不安。
) V( c' }/ d4 K$ ?6 q
- J7 T7 z/ R& j$ FSTM32H7使用的内存不是连续的,而是被划分为多段。
: K+ C6 `+ K+ ^/ z
5 ]' I  f% S' J
  1. MEMORY
    : D0 J) j# B$ R" R: C$ `5 B* p
  2. {! D) ]7 _! f8 I' s. @% ]
  3.         DTCMRAM (xrw)     : ORIGIN = 0x20000000, LENGTH = 128K //高速段,cpu独享
    / U  b) X- z' W7 X# Q) ~  C  N/ `
  4.         RAM_D1 (xrw)      : ORIGIN = 0x24000000, LENGTH = 512K
    5 F7 b5 S) G; Y
  5.         RAM_D2 (xrw)      : ORIGIN = 0x30000000, LENGTH = 288K
    # S( o3 G/ I, B2 {# v- h
  6.         RAM_D3 (xrw)      : ORIGIN = 0x38000000, LENGTH = 64K
    9 M' d6 D/ r5 S: z8 P2 V
  7.         ITCMRAM (xrw)     : ORIGIN = 0x00000000, LENGTH = 64K //高速段,cpu独享# g* H. x6 C* g5 F' o" A
  8.         FLASH (rx)        : ORIGIN = 0x8000000, LENGTH = 128K
    # a: t, j! ?# U3 p- h; X# T
  9. }
复制代码

" w' V+ G3 [9 j. V( ]2 O* PTCM内存段是和CPU同频率的,不需要也不能用Cache。用好TCM的优先级应该排在用好Cache的前面。6 ]; a; [4 y; ]: A$ X) H
Cache处于核心里面,作为低速内存加速器使用,获得增益最大的是位于AXI总线上的比如内部Flash、内部SRAM、通过FMC或者QSPI控制器连接的外部sram。Cache使得低速Sram获取与高速TCM差不多的速度。使用Cache加速很有意义,不然400M的cpu变200M,相当于H7变F4,选择H7的cpu将变得没有意义。# P4 u% W7 p- v* R4 |& R( \
" ]+ g! X- y! ]$ M0 I& a3 M
20201019190212727.png
" h) w% _8 r. M7 a# q- |

5 e. p% ^! w2 Q# w内存类型
5 P9 L, y2 p9 t. o内存类型分为Normal以及Device和Strongly-ordered,
. ?0 l  t$ H! K( h7 G* i
I5LW_ZQ_SY3W%I@][7RY56T.png

4 K: J& N: T; l2 s8 c
% d% ?' @' I. r* u; u7 i
20201019190230823.png

1 v) c+ w) I# z  U6 Q1 `/ t* x, `( E% u* c

% o2 b" Q. R; R: |Write-buffer是什么?2 k7 I1 _  I# n$ Y+ F5 `9 F
Device和Strongly-Ordered类型时候提到了write-buffer,它属于cpu核心,cache经常与write-buffer一起使用,使用writer-buffer的目的是将处理器和cache从较慢的对主存的写操作中脱离出来。0 S4 o: [- v, t# ]
Write buffer可以缓存8个word的数据和4个独立的地址,可以enable或者disable使用ARM核心控制寄存器 W的bit3。同时还要受到内存管理页表的一个bit控制,所以使用Write-Buffer,MMU必须已经使能(控制寄存器的bit0)。MMU-Memory Management Unit
- c8 g  o9 f; ]/ w5 P; [- ?通常情况下的配置都是主内存允许bufferable,但是I/O 空间 unbufferable
1 T  f) k3 f, u7 e+ T- z当CPU执行一个写操作时,根据配置情况执行写入操作。
3 i: e! Q  T* f. r. \  a; p3 I+ s. r( b6 {& w

+ B  u3 h* k. Y5 C. B
( Q  i3 [( P# B9 E& w$ q0 m1 N: J" B
20201019190300772.png

2 o  O) `5 ~( g/ b0 S0 ]5 v6 ~! ]. w% t$ b% |. o
如果程序中使用DMB and DSB,处理器会等到write-buffer内指令完成,再进行后续指令操作,如果过程中发生中断,中断返回后继续write-buffer清空等待。
- x; z5 y" I9 X3 R3 n* g) _
; n! N. D" V# L# L; ]2 qDMB或者DSB被称为 显式限制操作 explicit barrier。
3 s% x0 R+ D2 M4 j. L8 H5 y' h1 ~; h' l/ \' G8 I: @* F( b
20201019190244953.png
- m! p# \9 W! `& p8 s" W  O

4 q$ b9 X, W% |! @; X8 u& y# gMemory Attrabute
) S: B$ A# r/ R8 P5 Z$ hNormal模式下可以设定的几种; x1 ?" q; p% v
- l8 y, p6 n- i! _! J
UXF0GF8D%6@3RQT%LAI76.png
9 k, P! c  x% m6 I4 u5 \

. M  G* P& ~! x/ _( rShareable属性: k6 ]& U# @8 r, z2 v2 }
共享属性设计的意义在于,多个bus master读写情况下需要cache保持同步,对于CortexM7,只有L1-Cache,如果设置了Shared相当于non-cacheable。& G# Q4 s' J1 \3 P

, a8 c5 Y, W5 j; G+ y; S
20201019190314464.png
' M& }! l4 ]8 J6 ^/ R

  q, V  Y+ n7 Z5 P$ D' E内核操作函数" I# p' V* G3 i3 ?, F, I
内核操作函数包含以下几种,主要包含两种操作:clean和invalidate。
$ }" _& `  [% A; b7 eclean:将cache中的信息写到sram,相当于用cache信息覆盖sram;+ {9 H6 C2 ]3 _8 \
invalidate:使cache失效,相当于用sram信息覆盖cache;
9 U/ ]5 ^0 Q, f- a7 z二者为相反的操作。
5 e+ r# U4 g; i+ F- \
( Z( [1 O  B  ]
2020101919032876.png
& U% H: p; o: q% c1 D4 P
% d% t1 ]' T. w- k
20201019190336970.png

- i: {$ `4 d# G8 j* t1 ?) B& n' G! m) v* Q% l

1 f# _1 t1 w' ^- r内存对齐问题( \0 d1 P& B$ Z8 @4 X4 ]3 n# u
使用cache时,dma的buffer必须32byte对齐,不然可能会出现问题。比如下面的情况:: S* ~5 D- p3 {+ B! P2 G7 \
2 f" I, e7 D0 P% h
  1. typedef struct4 C+ u3 i4 M" I2 x* v- {7 m) s- H
  2. {, T% S2 Z, t, N8 w; p
  3.     __attribute__ ((aligned (32))) uint8_t rx_buffer[BUFFER_SIZE];//用于buffer3 t1 c# ^) E# A6 S$ P
  4.     bool rx_xfer_done;                                     //用于记录dma已经被正确传输
    6 s) E9 ~5 J) S$ p6 d  J, a
  5. }st_dma_xfer
    0 Z% d2 q$ S6 m5 n: w

  6. 5 G% L, O5 V0 C4 h/ f% M- L
  7. void XDMAC_Handler(void)4 M- {9 u# U+ v; L: I6 @- a. D- i9 ^
  8. {
    ! J/ E: Q- Q0 N+ O3 w
  9.     uint32_t dma_status;
      w; ~9 V9 T+ C* g
  10.     dma_status = xdmac_channel_get_interrupt_status(XDMAC, XDMA_CH_RX);
    3 ^- X# m7 R' t9 ^( a# y) D; T
  11.     if (dma_status & XDMAC_CIS_BIS)
    7 l+ C9 c2 a$ D
  12.     {5 Y' R& {4 T( L9 m$ t- q
  13.       g_st_dma_xfer.rx_xfer_done = true;; f7 N' H$ ]# w9 A
  14.       SCB_InvalidateDCache_by_Addr((uint32_t*)g_st_dma_xfer.rx_buffer, DMA_TRANSFER_SIZE);$ }" y* X# B3 j' T' e- u
  15.     }! ^/ t" B  x: i0 ?" F7 E& Y" @1 O/ D- b
  16. }
复制代码

5 J6 y4 `4 f2 @( ^: V: [6 s6 o  O0 G
如果DMA的buffer只有16字节,DMA读取操作后,DMA控制器将接收到的数据写到了sram里面,然后进入DMA接收中断函数,cpu把成功读取的标识bool变量写为true,实际上写操作只是写在D-Cache里面,暂时没有写到sram。' g8 b! }  E. i1 d% [

% g1 Q, t0 x$ k4 c; ^* Y5 ^
20201019190359602.png
7 I; p: W! ]) t5 O( Y8 j

! `1 G, t1 O3 O6 t, m1 U如果此时cpu需要读取dma内容,需要对Dcache进行invalid操作,32个字节将一起更新,bool变量旧值0将覆盖新值1。cpu读不到中断函数写的bool变量信息。
5 t' h" z4 X5 e. \; n
- Q6 `6 O* l; v
20201019190409891.png

* u5 ?2 U; Q# k9 R/ R, k) N- t# `2 p$ E0 B
可见:( j1 q$ }* ?7 O* \8 P
clean操作或者Invalidate操作都可能丢东西,使用上需要注意。经验是如果一段内存用来写dma外设,就不要读它,保证随时都可以clean;同样如果一段内存用来接收DMA外设传入信息,就不要用cpu写它,保证随时都可以invalidate。
( l7 Q# d- g2 G9 Q6 P( x' Z5 Z& h+ X5 r2 ?6 i
2020101919042042.png
/ w4 T+ S1 V* \) g0 G
, o  j) f1 M/ ~
* U; U; A9 z6 v0 D
收藏 评论0 发布时间:2021-12-26 17:22

举报

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