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

【经验分享】STM32H7的Cache与Buffer

[复制链接]
STMCU小助手 发布时间:2021-12-26 17:22
STM32H7的Cache与Buffer
; a5 H# e. F; b0 @TCM和Cache的区别
3 Y" p! J& C' B( Z& `) |
…使用lwip用到了mpu,对于内存管理产生了很多的疑问,需要统一解决一下,不然用起来总有些不安。
' Y5 e# x" T$ ~" l4 x
( d8 b8 B$ S- E! m  g& K! `/ p2 KSTM32H7使用的内存不是连续的,而是被划分为多段。" S& m) w; b$ e/ `3 k! h
7 }6 l' f8 r/ p
  1. MEMORY
    8 X# I3 m0 {4 s) s: A3 {' a6 m
  2. {. T- ^% Z' D# ?2 A
  3.         DTCMRAM (xrw)     : ORIGIN = 0x20000000, LENGTH = 128K //高速段,cpu独享
    9 A2 u9 n$ K: f) r
  4.         RAM_D1 (xrw)      : ORIGIN = 0x24000000, LENGTH = 512K
    $ p" ]# q& g$ G# T( [1 G
  5.         RAM_D2 (xrw)      : ORIGIN = 0x30000000, LENGTH = 288K# e; v. _' P# `# Z+ ^/ a! N% t# m
  6.         RAM_D3 (xrw)      : ORIGIN = 0x38000000, LENGTH = 64K
      r# {# _3 T% C" o2 D- k
  7.         ITCMRAM (xrw)     : ORIGIN = 0x00000000, LENGTH = 64K //高速段,cpu独享
    6 x* g' @% H6 ]  t
  8.         FLASH (rx)        : ORIGIN = 0x8000000, LENGTH = 128K# \) ?4 X% _6 J4 e6 L6 [7 k6 `
  9. }
复制代码

: b# L6 T! R0 v: ^) Q  ?4 rTCM内存段是和CPU同频率的,不需要也不能用Cache。用好TCM的优先级应该排在用好Cache的前面。! }  t) `, |$ ]
Cache处于核心里面,作为低速内存加速器使用,获得增益最大的是位于AXI总线上的比如内部Flash、内部SRAM、通过FMC或者QSPI控制器连接的外部sram。Cache使得低速Sram获取与高速TCM差不多的速度。使用Cache加速很有意义,不然400M的cpu变200M,相当于H7变F4,选择H7的cpu将变得没有意义。1 o! g% A' i; k  F- v

3 V2 n3 I* ]5 y: Z# X
20201019190212727.png

* y) i6 }9 B: {( S( _% w0 O2 j+ T" h9 r: k. ?# P9 w  ]" x/ s
内存类型- o" ~( x! T+ G; F* R, J
内存类型分为Normal以及Device和Strongly-ordered,* C" C/ b& r3 P
I5LW_ZQ_SY3W%I@][7RY56T.png

5 p; i* A* C3 n% K2 Q
) m% S) ^5 G# f# D1 B8 x. T* q* u
20201019190230823.png

2 Q; v6 p4 D& s& l, V% o0 N4 a9 ^- i3 q. q
  i* \" C6 h+ s& h/ v4 ^
Write-buffer是什么?. X8 X& K3 e! \7 k
Device和Strongly-Ordered类型时候提到了write-buffer,它属于cpu核心,cache经常与write-buffer一起使用,使用writer-buffer的目的是将处理器和cache从较慢的对主存的写操作中脱离出来。: \/ ]6 X4 k7 X8 [' A7 R
Write buffer可以缓存8个word的数据和4个独立的地址,可以enable或者disable使用ARM核心控制寄存器 W的bit3。同时还要受到内存管理页表的一个bit控制,所以使用Write-Buffer,MMU必须已经使能(控制寄存器的bit0)。MMU-Memory Management Unit
/ p; B# t; t% t2 r( J8 z9 N& ^通常情况下的配置都是主内存允许bufferable,但是I/O 空间 unbufferable6 e2 a  z3 e7 w% S, x; U6 O0 ^+ K
当CPU执行一个写操作时,根据配置情况执行写入操作。
' G" g3 k0 o* |, s  t% ^
) s+ r9 `( O, H
0 Y$ O6 t! [, Q9 V0 U

4 p! e/ _' k' V$ q* Y# Y" C2 b
20201019190300772.png

/ V; ]! ~" L4 r1 l7 h  g
/ d4 v$ O. N% I1 a8 d4 \如果程序中使用DMB and DSB,处理器会等到write-buffer内指令完成,再进行后续指令操作,如果过程中发生中断,中断返回后继续write-buffer清空等待。
- X0 B1 D- v4 U# a; P/ i
  v! @) q5 Z( Y# Y3 ~( @# P2 xDMB或者DSB被称为 显式限制操作 explicit barrier。
% B* I5 w  r2 V* q/ H; f! ]. B. @& c
20201019190244953.png

- O6 s# L0 h! A0 K# N* C3 I% v
' u9 H. X$ a' [6 V9 SMemory Attrabute
4 U  z% k2 c4 L* fNormal模式下可以设定的几种
! U- M% }, }: h4 t
5 b" ?* v1 W8 S
UXF0GF8D%6@3RQT%LAI76.png
& {+ w) `+ l/ a: q" R) C1 e5 e% N
0 L- ?' Y/ D' |/ T+ y% r$ D- |, L
Shareable属性) E6 ]8 @; ?! T# g
共享属性设计的意义在于,多个bus master读写情况下需要cache保持同步,对于CortexM7,只有L1-Cache,如果设置了Shared相当于non-cacheable。
0 j8 v; H8 U; Y5 M% X* H4 W
! w. j4 b+ v5 w# m% ^8 o# v
20201019190314464.png
3 Z0 E5 u# B: B- R9 K4 z' ~
( ^* s1 r1 a( U5 `; J) N' {2 \
内核操作函数
* d( }" Z4 [7 D内核操作函数包含以下几种,主要包含两种操作:clean和invalidate。2 m9 |0 k/ U- w7 N
clean:将cache中的信息写到sram,相当于用cache信息覆盖sram;5 e% S2 C# ?! d: B. `. D" n* W1 G
invalidate:使cache失效,相当于用sram信息覆盖cache;
( v; {3 W5 L4 M# S* D& s二者为相反的操作。
% _4 y8 ~3 t2 Q9 q) u3 I. `+ y& j. }2 y
2020101919032876.png
4 k7 z  f0 k: `/ E9 K
7 G/ E. j! r  B: Q) R4 K  ^3 P
20201019190336970.png
' Z' y( E* d3 N
. k$ L% X4 {" P' y- C
3 }; w+ o5 c1 I; d1 }, g! i! C5 u
内存对齐问题. J% f2 S+ `/ b/ v' W' b3 {6 m% Q
使用cache时,dma的buffer必须32byte对齐,不然可能会出现问题。比如下面的情况:; e% L+ K& {' V- u  V! E
  R2 ?7 @9 _' a
  1. typedef struct
    + k" P% ~3 i9 ^
  2. {8 s7 r5 v/ n5 W1 l: z/ G3 E4 ?
  3.     __attribute__ ((aligned (32))) uint8_t rx_buffer[BUFFER_SIZE];//用于buffer4 k) {( C% L/ r! I. e
  4.     bool rx_xfer_done;                                     //用于记录dma已经被正确传输: w' N) O* k7 d% c" T( Z
  5. }st_dma_xfer% I+ u+ G% G+ Z. L2 U( m! @
  6. 7 N/ I" {, R# g0 c6 _9 E& ?( P
  7. void XDMAC_Handler(void)2 K: {& {) W) a! d. \# F
  8. {- h9 ^5 n2 m3 a# ^4 V! @" ~
  9.     uint32_t dma_status;
    ; O0 G, g: o& ^- e
  10.     dma_status = xdmac_channel_get_interrupt_status(XDMAC, XDMA_CH_RX);) I& k8 x: H; l8 H) @# x8 p$ c- p
  11.     if (dma_status & XDMAC_CIS_BIS)! X; ?: P. Y8 Z5 t5 H$ n0 `
  12.     {
    % q! u; u* u8 C4 e# ]% n
  13.       g_st_dma_xfer.rx_xfer_done = true;
    # O6 n, @8 v! b$ x3 \2 g
  14.       SCB_InvalidateDCache_by_Addr((uint32_t*)g_st_dma_xfer.rx_buffer, DMA_TRANSFER_SIZE);
    ) H- H" R; G$ g; _; c& a
  15.     }
    * h. e6 a, G' C
  16. }
复制代码
9 E$ a2 L% f; Z8 ?  c

  G/ c9 ^# Y* B/ |! U7 ~, ~如果DMA的buffer只有16字节,DMA读取操作后,DMA控制器将接收到的数据写到了sram里面,然后进入DMA接收中断函数,cpu把成功读取的标识bool变量写为true,实际上写操作只是写在D-Cache里面,暂时没有写到sram。
$ J: {4 m; o7 |2 c+ S7 ]) C9 T6 k9 }3 U0 _$ W1 `3 L% ]
20201019190359602.png

/ c/ U$ w/ u7 ~8 n! }0 A
3 l9 E7 y7 W0 h1 ~' M: c& F如果此时cpu需要读取dma内容,需要对Dcache进行invalid操作,32个字节将一起更新,bool变量旧值0将覆盖新值1。cpu读不到中断函数写的bool变量信息。$ {2 Z7 `- c5 I7 d/ D) n
4 Z: H/ i6 f3 G6 d" }- c5 [
20201019190409891.png
% P: e  z# R3 V3 z
+ d, x7 L1 y8 l/ q2 ?7 t, f8 m
可见:( x) `" [3 f% ?' d0 j- a6 g0 s
clean操作或者Invalidate操作都可能丢东西,使用上需要注意。经验是如果一段内存用来写dma外设,就不要读它,保证随时都可以clean;同样如果一段内存用来接收DMA外设传入信息,就不要用cpu写它,保证随时都可以invalidate。
1 h1 ?$ P( M; l0 B% z3 H& N8 f) h& k, B; F
2020101919042042.png
2 f& `+ a  g+ \! K/ s

! G. O% J' C) m- w% i  h3 F2 V7 B1 }" O
收藏 评论0 发布时间:2021-12-26 17:22

举报

0个回答

所属标签

相似分享

官网相关资源

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