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

【经验分享】STM32H7的Cache与Buffer

[复制链接]
STMCU小助手 发布时间:2021-12-26 17:22
STM32H7的Cache与Buffer
. Q: v1 a+ G) E9 r- CTCM和Cache的区别
2 Q& ~  R, Y4 u: j' @1 {5 I
…使用lwip用到了mpu,对于内存管理产生了很多的疑问,需要统一解决一下,不然用起来总有些不安。( Y4 J6 G! w6 w- n

) P, `0 y8 @2 \1 f. t3 W0 b3 KSTM32H7使用的内存不是连续的,而是被划分为多段。" Y3 v5 x, J2 y' s1 z5 g/ P
0 G2 E9 @+ E% r6 X4 t( F- ^
  1. MEMORY
    / s( s7 Q+ x. z" g5 a0 @/ C
  2. {
    : G( [1 t. P( m0 A  ?9 q
  3.         DTCMRAM (xrw)     : ORIGIN = 0x20000000, LENGTH = 128K //高速段,cpu独享! h3 f" Q6 t6 @# ?. G
  4.         RAM_D1 (xrw)      : ORIGIN = 0x24000000, LENGTH = 512K
    / h8 e6 ~- {" {* b" o8 P
  5.         RAM_D2 (xrw)      : ORIGIN = 0x30000000, LENGTH = 288K" x+ k  @! D' k, \( M& D7 v
  6.         RAM_D3 (xrw)      : ORIGIN = 0x38000000, LENGTH = 64K
    % L7 l! s$ b0 J& u% P3 c7 t1 c
  7.         ITCMRAM (xrw)     : ORIGIN = 0x00000000, LENGTH = 64K //高速段,cpu独享8 B' i% @6 W1 I, r7 h9 c7 i: S
  8.         FLASH (rx)        : ORIGIN = 0x8000000, LENGTH = 128K
    7 J- n% `' v( r8 I( J* \2 Q
  9. }
复制代码

; a7 @6 r6 `/ s$ `TCM内存段是和CPU同频率的,不需要也不能用Cache。用好TCM的优先级应该排在用好Cache的前面。; l1 M6 `: D- W  d$ ]  H
Cache处于核心里面,作为低速内存加速器使用,获得增益最大的是位于AXI总线上的比如内部Flash、内部SRAM、通过FMC或者QSPI控制器连接的外部sram。Cache使得低速Sram获取与高速TCM差不多的速度。使用Cache加速很有意义,不然400M的cpu变200M,相当于H7变F4,选择H7的cpu将变得没有意义。
, M0 \5 ~* ]0 {
8 m* R0 ~. T) Q- |3 W1 u* J) C
20201019190212727.png
9 [/ l% x6 m- s% I$ s6 T. F0 [- m

9 w, B' {/ N0 c) [; r内存类型0 P# y! @1 Q# t
内存类型分为Normal以及Device和Strongly-ordered,
$ l( u# e& H5 a9 ^) q6 C
I5LW_ZQ_SY3W%I@][7RY56T.png

# p* R3 r; ], w: C$ m1 W
  K! E- u( m3 X5 m
20201019190230823.png

$ N  \/ q8 Y. ~5 `% ^& w5 [6 _( s  d4 x! |8 I
# e7 }$ u# v$ G4 Z. u& H* i2 J
Write-buffer是什么?+ u: F/ E. Z; z$ h
Device和Strongly-Ordered类型时候提到了write-buffer,它属于cpu核心,cache经常与write-buffer一起使用,使用writer-buffer的目的是将处理器和cache从较慢的对主存的写操作中脱离出来。& j; d; W" W% A1 o. o4 n
Write buffer可以缓存8个word的数据和4个独立的地址,可以enable或者disable使用ARM核心控制寄存器 W的bit3。同时还要受到内存管理页表的一个bit控制,所以使用Write-Buffer,MMU必须已经使能(控制寄存器的bit0)。MMU-Memory Management Unit
* J- _7 c1 }& i7 f通常情况下的配置都是主内存允许bufferable,但是I/O 空间 unbufferable
/ _- {: ?! i, n: Y7 G当CPU执行一个写操作时,根据配置情况执行写入操作。: K1 w" C% Z( h4 ^  ^* i
3 h: j% m' l* z( o& y" }

* `- |+ b9 l* d8 h, A) m6 S8 B, `
20201019190300772.png
8 b( ]8 b" Q: [. U- d5 [9 f& L% |
8 ~- e; w0 @4 m+ Q; W! I, s
如果程序中使用DMB and DSB,处理器会等到write-buffer内指令完成,再进行后续指令操作,如果过程中发生中断,中断返回后继续write-buffer清空等待。! L. s2 n  [2 S: _2 a
) B+ X" ?, G* t( O, |
DMB或者DSB被称为 显式限制操作 explicit barrier。: E8 |  r) f% n7 O$ X

5 a7 Y, F% c* J& Y8 D
20201019190244953.png

. H' G9 U3 O9 w) s% Q# E/ e; I8 u. a- i2 G* R: c5 w
Memory Attrabute, h  F- E+ k( U5 U
Normal模式下可以设定的几种( z. ^9 d- i3 l4 a& X5 \
1 K0 @6 ?. _% w  ]8 l2 a
UXF0GF8D%6@3RQT%LAI76.png
* I! o# G# l; h6 y3 h# O; x- x' o
( t  G# q9 O" R% ?7 P4 B
Shareable属性! a% \0 `1 [. H% g* x
共享属性设计的意义在于,多个bus master读写情况下需要cache保持同步,对于CortexM7,只有L1-Cache,如果设置了Shared相当于non-cacheable。
0 Q! [) E  k0 E
  ^/ v0 J8 s( `! d! y, ~, U. A3 Z( H+ q
20201019190314464.png
9 u% Y: c( N% }% B' q

" u9 D9 B& {; q内核操作函数' v* S$ F5 _8 N6 e/ ]( D! t
内核操作函数包含以下几种,主要包含两种操作:clean和invalidate。
3 ]% `/ `! f# N: z4 M* u" {7 tclean:将cache中的信息写到sram,相当于用cache信息覆盖sram;! j) }0 n" c5 f6 Y& C% [- `4 p+ i
invalidate:使cache失效,相当于用sram信息覆盖cache;
8 L: n+ P9 x% l4 t: L( F二者为相反的操作。
% k* \! [) I& g" j, B. ?1 d/ L8 U: f5 P3 a2 R5 N% P3 `3 B5 ~) {3 v" L& r' @
2020101919032876.png

/ F) A) A3 [" x7 [( `0 R! K
% }# x. ]# ^1 Q: P
20201019190336970.png
- ~8 p" A: z: l% z( Z
9 U2 B1 r3 H4 q# M: O6 }

! n2 M1 z% P+ C# w$ C. ~# s2 b% z! h: X内存对齐问题
, Q1 C9 y# J5 k3 |; Z6 ]# z' L使用cache时,dma的buffer必须32byte对齐,不然可能会出现问题。比如下面的情况:
1 [7 o" [- W+ a& K+ `7 D3 i0 w: y' b. i
  1. typedef struct
    # m! g/ L- z% B8 N: t4 n
  2. {9 s1 L; n# n0 j# Q* M6 @
  3.     __attribute__ ((aligned (32))) uint8_t rx_buffer[BUFFER_SIZE];//用于buffer0 C. q& {: R7 r3 D% g' j8 s3 S5 @; |
  4.     bool rx_xfer_done;                                     //用于记录dma已经被正确传输
      T/ a4 {. N  V( w. Y) B1 E" N7 q3 x/ t9 A
  5. }st_dma_xfer
    . A' _9 a( N; T4 O0 K4 s) `

  6. , I# U' W9 G: X& }% A& {! M* `
  7. void XDMAC_Handler(void)
    ) T4 ~% T  e( i6 ^7 q8 j: I
  8. {  w% `( D5 E+ |$ |9 L& |, U3 m
  9.     uint32_t dma_status;6 N$ y4 g+ [# p9 L/ {& Z- ?
  10.     dma_status = xdmac_channel_get_interrupt_status(XDMAC, XDMA_CH_RX);
    - v# d# ?8 x- M
  11.     if (dma_status & XDMAC_CIS_BIS)
    , R6 W. S9 z* H
  12.     {6 t/ @8 Y$ V  _$ L0 I- O5 q
  13.       g_st_dma_xfer.rx_xfer_done = true;
    ) c( T* a- B! ^% a4 }/ T
  14.       SCB_InvalidateDCache_by_Addr((uint32_t*)g_st_dma_xfer.rx_buffer, DMA_TRANSFER_SIZE);
    2 Q1 _) H: {. W8 ?7 h6 S
  15.     }
    ( ~" _7 K3 v" I2 P" p
  16. }
复制代码

& l8 K4 u: {, N( M! D, v
0 {9 L5 A5 o! m0 j如果DMA的buffer只有16字节,DMA读取操作后,DMA控制器将接收到的数据写到了sram里面,然后进入DMA接收中断函数,cpu把成功读取的标识bool变量写为true,实际上写操作只是写在D-Cache里面,暂时没有写到sram。
$ ?4 B% y7 v" P/ Q' _" \" W3 C  Y0 k/ ?4 y. p
20201019190359602.png

  [8 f% u( e5 ]9 V% S/ b& |, S0 v! ]# @+ n; @
如果此时cpu需要读取dma内容,需要对Dcache进行invalid操作,32个字节将一起更新,bool变量旧值0将覆盖新值1。cpu读不到中断函数写的bool变量信息。( a+ s- t, h0 o$ S

5 Z4 H- G* X4 X; ]* n& l7 M) ]
20201019190409891.png
6 u: D1 T3 X9 f7 o/ X% x
7 m  q2 j* m; y9 `8 j
可见:$ K" |0 x& R% D5 b, \. B* ^; |
clean操作或者Invalidate操作都可能丢东西,使用上需要注意。经验是如果一段内存用来写dma外设,就不要读它,保证随时都可以clean;同样如果一段内存用来接收DMA外设传入信息,就不要用cpu写它,保证随时都可以invalidate。2 N$ P% y' {: Q4 t0 ?
& v9 B* M! ~/ [/ A) {2 J+ R/ a* H
2020101919042042.png

% b: W% T7 J7 e* i  d, x6 K- S' P( Y) K7 L7 v+ ?

( \0 \3 _) m, J; P$ S8 G
收藏 评论0 发布时间:2021-12-26 17:22

举报

0个回答

所属标签

相似分享

官网相关资源

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