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

【经验分享】STM32H7的Cache与Buffer

[复制链接]
STMCU小助手 发布时间:2021-12-26 17:22
STM32H7的Cache与Buffer2 t: G$ r+ N4 \3 `$ P% [
TCM和Cache的区别

! {3 j, d' }4 K& g- J+ ]…使用lwip用到了mpu,对于内存管理产生了很多的疑问,需要统一解决一下,不然用起来总有些不安。$ z  e& c1 q+ g$ c4 P: z( J
, z" S0 t% s! D* j4 z( j( O; F) M8 O
STM32H7使用的内存不是连续的,而是被划分为多段。
# o- k0 f* _6 n3 ]8 o1 q; D" }$ O; g/ k7 N
  1. MEMORY
    . a- L3 Q& X0 p) ]
  2. {
    % K" I% u& j& f0 ?
  3.         DTCMRAM (xrw)     : ORIGIN = 0x20000000, LENGTH = 128K //高速段,cpu独享3 ?% [5 i; `$ g
  4.         RAM_D1 (xrw)      : ORIGIN = 0x24000000, LENGTH = 512K
    ; l, i4 Z* q" B9 F: x
  5.         RAM_D2 (xrw)      : ORIGIN = 0x30000000, LENGTH = 288K
    5 s% s5 R  I. O
  6.         RAM_D3 (xrw)      : ORIGIN = 0x38000000, LENGTH = 64K+ N% ]1 H& b3 j4 z% ^8 G8 B
  7.         ITCMRAM (xrw)     : ORIGIN = 0x00000000, LENGTH = 64K //高速段,cpu独享( ]' `* w. G0 t; q% ~
  8.         FLASH (rx)        : ORIGIN = 0x8000000, LENGTH = 128K
    $ b+ u, l) Y! j! B0 q, }4 f
  9. }
复制代码
& e: ~% A* X8 d1 C
TCM内存段是和CPU同频率的,不需要也不能用Cache。用好TCM的优先级应该排在用好Cache的前面。
3 h$ C; i4 q, l# X. V7 l" jCache处于核心里面,作为低速内存加速器使用,获得增益最大的是位于AXI总线上的比如内部Flash、内部SRAM、通过FMC或者QSPI控制器连接的外部sram。Cache使得低速Sram获取与高速TCM差不多的速度。使用Cache加速很有意义,不然400M的cpu变200M,相当于H7变F4,选择H7的cpu将变得没有意义。/ d2 q: r* _: {% G2 ~. y% L$ X

& S  J2 \' k  j! ^7 k9 O
20201019190212727.png

0 \& C: V( x7 s9 t  P% S
0 k* t9 W5 N5 G8 R内存类型) b$ O+ n  P* I, l0 x
内存类型分为Normal以及Device和Strongly-ordered,
! X! T9 D) ^: X* T4 M' C
I5LW_ZQ_SY3W%I@][7RY56T.png
# O/ [% O. E$ o! }0 I7 U7 L

/ \" J- x8 Z5 }! T' u' G
20201019190230823.png
8 B3 j! U  d/ P" A+ X
, f2 ^+ I# `( g9 r0 D5 i6 T

. T; U3 {$ w& }; |Write-buffer是什么?  u) N2 J/ _: G2 y0 T0 J
Device和Strongly-Ordered类型时候提到了write-buffer,它属于cpu核心,cache经常与write-buffer一起使用,使用writer-buffer的目的是将处理器和cache从较慢的对主存的写操作中脱离出来。
& b3 ~6 M; D6 R. GWrite buffer可以缓存8个word的数据和4个独立的地址,可以enable或者disable使用ARM核心控制寄存器 W的bit3。同时还要受到内存管理页表的一个bit控制,所以使用Write-Buffer,MMU必须已经使能(控制寄存器的bit0)。MMU-Memory Management Unit- O" ]- P" E  i, J! @% @
通常情况下的配置都是主内存允许bufferable,但是I/O 空间 unbufferable& W& K/ h' o/ Z
当CPU执行一个写操作时,根据配置情况执行写入操作。' V% n# n" F! @. c7 R
0 F% h, U" W& |

' a, d; e# g" q/ D$ \+ l; V( ], e, g* `
20201019190300772.png
, _+ r$ ]! @& i5 i' _+ h7 J, x
0 |2 q, L2 {: c9 ]( k8 U* {
如果程序中使用DMB and DSB,处理器会等到write-buffer内指令完成,再进行后续指令操作,如果过程中发生中断,中断返回后继续write-buffer清空等待。3 o+ U5 ^0 B4 r9 F3 D* [5 O& g+ U! I

% H( J- h* F$ Y# y6 X7 m' aDMB或者DSB被称为 显式限制操作 explicit barrier。9 u% F" L# B+ v6 _+ t" x1 P, R

4 E8 I, H) l( H+ X% a2 O4 y
20201019190244953.png

3 h4 D9 V! E- W, E' q$ a1 O* ^% p
( S- H% P* O/ ^! M% m  @! bMemory Attrabute
; C5 W9 c( m5 @& C8 e8 p, CNormal模式下可以设定的几种
9 m" S, A6 _% R# M0 p5 O4 M( }! J- m0 h# x4 F3 _* E  q
UXF0GF8D%6@3RQT%LAI76.png
7 h' F' u' }2 R3 s: Z2 Z

  {- v) _  ]% S( P  P; WShareable属性# F; j% k  g  |- j3 B6 f( o
共享属性设计的意义在于,多个bus master读写情况下需要cache保持同步,对于CortexM7,只有L1-Cache,如果设置了Shared相当于non-cacheable。; u, s  N& f) ~. v

3 r( u" t1 g( Z7 ~5 A- s
20201019190314464.png

" S$ k6 V+ s' p& r2 k$ t* B7 P" P: ^4 l. _' w
内核操作函数
1 G. F4 l8 k" v内核操作函数包含以下几种,主要包含两种操作:clean和invalidate。- c* D. b4 {. S4 R- k$ _
clean:将cache中的信息写到sram,相当于用cache信息覆盖sram;$ y, V/ A0 V6 t) M* v( ?) J  e) S
invalidate:使cache失效,相当于用sram信息覆盖cache;& K! r$ u; V) y2 c  |! n+ x
二者为相反的操作。6 t/ Z5 ?0 ~0 U4 `& G
9 @& y7 V1 G) x
2020101919032876.png

/ d! m$ B' V0 z) w' T7 c0 x
' }# K; Q+ x# W9 Y8 J
20201019190336970.png
# i) g8 m/ {3 h) c
6 P  n4 N3 p2 Z/ G: a2 O; Z3 X
( |5 |' P7 X/ q1 @5 G
内存对齐问题  f1 w  I$ j8 J, A
使用cache时,dma的buffer必须32byte对齐,不然可能会出现问题。比如下面的情况:
/ W* A# X8 f$ R$ ^) o$ ?. Q
- ?1 L) v- p) }6 k
  1. typedef struct
    1 C* r6 a& s0 i& P
  2. {0 o2 }+ {% q  `5 Q7 ^; Q
  3.     __attribute__ ((aligned (32))) uint8_t rx_buffer[BUFFER_SIZE];//用于buffer
    6 F6 t; s2 g: O! d, f
  4.     bool rx_xfer_done;                                     //用于记录dma已经被正确传输1 ~: |, S/ I  f5 h$ K. {+ x. m
  5. }st_dma_xfer7 x6 x+ o4 I4 |6 Z" d! O& e
  6. # V. v) N& S3 j+ Q; H# _# F
  7. void XDMAC_Handler(void)3 A! z* j- }6 P3 u% k1 F- J! \
  8. {
    0 k. @2 e0 R! o
  9.     uint32_t dma_status;3 C/ l3 u+ U3 |* j' J4 a2 m6 p
  10.     dma_status = xdmac_channel_get_interrupt_status(XDMAC, XDMA_CH_RX);
    : m% G2 ]) |, w9 \/ L  T
  11.     if (dma_status & XDMAC_CIS_BIS)' K0 P% ^# m$ ]  b5 I2 X% W
  12.     {6 Y+ N! e- W) k' I% ]
  13.       g_st_dma_xfer.rx_xfer_done = true;
    & N$ v3 p+ \; n/ `! l
  14.       SCB_InvalidateDCache_by_Addr((uint32_t*)g_st_dma_xfer.rx_buffer, DMA_TRANSFER_SIZE);0 d& U; u* h. F8 |# E
  15.     }
    - D5 ?0 N: j% I' b' o+ L& ~. f: @8 o& K
  16. }
复制代码
! e/ y% f1 o- c; m& W

/ h: E9 c% @5 I2 r' M3 `如果DMA的buffer只有16字节,DMA读取操作后,DMA控制器将接收到的数据写到了sram里面,然后进入DMA接收中断函数,cpu把成功读取的标识bool变量写为true,实际上写操作只是写在D-Cache里面,暂时没有写到sram。7 S0 `4 l& [* w2 Y" p
) E4 h+ y* d% z6 S7 ]! i) e+ C
20201019190359602.png

0 k- G! _4 v! A+ R+ V4 J- w" Y6 |5 N2 k( H
如果此时cpu需要读取dma内容,需要对Dcache进行invalid操作,32个字节将一起更新,bool变量旧值0将覆盖新值1。cpu读不到中断函数写的bool变量信息。- g" C4 {& e& ~$ B

; G# `7 p4 V0 D. q9 N3 N
20201019190409891.png

/ P. k3 M' V; n0 j+ j7 j5 S, E9 `# |- i, x# T
可见:: x; a, p8 t/ J6 K  X# d  h
clean操作或者Invalidate操作都可能丢东西,使用上需要注意。经验是如果一段内存用来写dma外设,就不要读它,保证随时都可以clean;同样如果一段内存用来接收DMA外设传入信息,就不要用cpu写它,保证随时都可以invalidate。
2 e) ~' b0 M+ E) g# Y  S4 q3 H& a4 A
2020101919042042.png
7 K( ]& L) m. e# Y

; X  R8 \0 P! O. D; B/ U0 N, u% l7 b
% _# i- k6 y( h% V
收藏 评论0 发布时间:2021-12-26 17:22

举报

0个回答

所属标签

相似分享

官网相关资源

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