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

【经验分享】STM32H7的Cache与Buffer

[复制链接]
STMCU小助手 发布时间:2021-12-26 17:22
STM32H7的Cache与Buffer
$ f: u9 Z: g1 k/ J! n7 O8 l+ b4 dTCM和Cache的区别

8 d$ H5 J. |6 l6 p# [6 B* f…使用lwip用到了mpu,对于内存管理产生了很多的疑问,需要统一解决一下,不然用起来总有些不安。
3 R4 w# S  d  w" ]& s0 ^1 l& z
0 Y( {/ i: _( Y4 `+ K9 kSTM32H7使用的内存不是连续的,而是被划分为多段。* \- m# J; r/ C* M' C, g$ E" p$ z

" l2 T' U, \) p1 @
  1. MEMORY9 E3 ?* ~1 I# M' R0 P/ m% E1 o1 c
  2. {
    ! g3 a0 {, T% \; Y3 a
  3.         DTCMRAM (xrw)     : ORIGIN = 0x20000000, LENGTH = 128K //高速段,cpu独享
    % s8 {+ m( \3 D
  4.         RAM_D1 (xrw)      : ORIGIN = 0x24000000, LENGTH = 512K0 h5 i! B3 `6 }5 ~6 u: g' G
  5.         RAM_D2 (xrw)      : ORIGIN = 0x30000000, LENGTH = 288K
    + D* v$ w* ]8 S
  6.         RAM_D3 (xrw)      : ORIGIN = 0x38000000, LENGTH = 64K- K  K0 A' `) V0 E
  7.         ITCMRAM (xrw)     : ORIGIN = 0x00000000, LENGTH = 64K //高速段,cpu独享% T3 D- l; _2 g8 y, k
  8.         FLASH (rx)        : ORIGIN = 0x8000000, LENGTH = 128K: a6 h2 |( w3 H6 W
  9. }
复制代码
" \! w6 r( y/ e4 g+ A& ?( j
TCM内存段是和CPU同频率的,不需要也不能用Cache。用好TCM的优先级应该排在用好Cache的前面。
8 r; [  V5 b" }4 j. u1 J4 F6 YCache处于核心里面,作为低速内存加速器使用,获得增益最大的是位于AXI总线上的比如内部Flash、内部SRAM、通过FMC或者QSPI控制器连接的外部sram。Cache使得低速Sram获取与高速TCM差不多的速度。使用Cache加速很有意义,不然400M的cpu变200M,相当于H7变F4,选择H7的cpu将变得没有意义。* d/ z6 p# E8 K0 _$ B" j3 L
* D  G8 n2 f( R0 o$ G
20201019190212727.png

1 `# M- ]' S- A& s0 c1 p# W, Z4 \3 |
内存类型7 m- b  O1 P& G
内存类型分为Normal以及Device和Strongly-ordered,: N' x( {( ~( o8 a' p
I5LW_ZQ_SY3W%I@][7RY56T.png

  H" C" J  W9 a) f) v" ^( G: e, ^( a/ _) y
20201019190230823.png

. `4 G( g3 g. V  ^! r% _' ]9 b4 u4 `1 L/ o. x  o9 [& t( s8 p
! y1 e* \$ f* G# C/ ]
Write-buffer是什么?
6 s# E- R) H- j0 ^$ ~! }Device和Strongly-Ordered类型时候提到了write-buffer,它属于cpu核心,cache经常与write-buffer一起使用,使用writer-buffer的目的是将处理器和cache从较慢的对主存的写操作中脱离出来。: K/ c" |( ?& c0 m. Q  a2 w7 x
Write buffer可以缓存8个word的数据和4个独立的地址,可以enable或者disable使用ARM核心控制寄存器 W的bit3。同时还要受到内存管理页表的一个bit控制,所以使用Write-Buffer,MMU必须已经使能(控制寄存器的bit0)。MMU-Memory Management Unit6 k. m$ J: a  _! h& J, s$ E
通常情况下的配置都是主内存允许bufferable,但是I/O 空间 unbufferable
% N( A* S1 w$ y' E当CPU执行一个写操作时,根据配置情况执行写入操作。
% K, k5 Z! f; e  R) c2 i1 @
0 e1 a1 v: y4 }3 P# Z# F

2 @" R0 j$ s4 d$ F! f8 m
# [2 U6 b2 c, Q  n5 {2 q9 v
20201019190300772.png
9 j% W: A) w. n+ E0 t
8 D2 p( D2 [" \0 _" ?5 I
如果程序中使用DMB and DSB,处理器会等到write-buffer内指令完成,再进行后续指令操作,如果过程中发生中断,中断返回后继续write-buffer清空等待。
& H* w* Z) J' W
0 N8 ?  d% \4 j$ Y* lDMB或者DSB被称为 显式限制操作 explicit barrier。3 p# F. x# c6 f! }/ ]/ j
. d9 `: k- @# g1 d3 |
20201019190244953.png

. K6 l1 F  T$ p; b: _$ _1 t" a# [) u% ]5 _+ a
Memory Attrabute% q  T- Z* N% n9 G
Normal模式下可以设定的几种
* |4 L' I+ O  l, P/ c) _3 ]
" n( b$ {4 l8 D7 e
UXF0GF8D%6@3RQT%LAI76.png
1 O' J; S: w' v8 w6 {2 B% v* ?
2 D8 S. `; t/ _; E
Shareable属性
; d1 g/ F, i+ d0 F' V共享属性设计的意义在于,多个bus master读写情况下需要cache保持同步,对于CortexM7,只有L1-Cache,如果设置了Shared相当于non-cacheable。1 K/ B  B# \" S  h. F7 }* Y+ j
. [  h  e: D. Y* B; b1 s! @; ]
20201019190314464.png

: Q7 l9 p3 A  h8 E2 F: u. ?; L$ B
8 Q% E; l/ `* z% r内核操作函数
, e/ m# [1 V& i" Y; Y内核操作函数包含以下几种,主要包含两种操作:clean和invalidate。
$ B* ]' X) o! f/ E+ jclean:将cache中的信息写到sram,相当于用cache信息覆盖sram;
2 b0 q, K" u! [; u( Minvalidate:使cache失效,相当于用sram信息覆盖cache;
& R0 Q. B# ~0 N) V2 d' {. \' m二者为相反的操作。
& d( Z! Q. \, `; n5 i9 P7 B+ z0 f! _1 q! \. S. ~
2020101919032876.png
& \" e2 o2 S3 @; k
7 j9 g' t8 V4 i6 [/ {
20201019190336970.png
, b1 y9 i6 B2 W1 A+ G) h
* f8 l% w- Y" k0 N: |) z) i

  T+ G1 b' X9 I( V) W+ y4 d内存对齐问题
' N9 m* z% @. y5 q, {9 {使用cache时,dma的buffer必须32byte对齐,不然可能会出现问题。比如下面的情况:
8 p, Y; {5 ?( s3 ^4 M) t0 z0 A! l7 M  G5 b1 E; g3 o8 C
  1. typedef struct  ?: b# X5 u6 K6 F- y
  2. {
    - x3 d4 K6 o+ ~+ z! \: h% W* r
  3.     __attribute__ ((aligned (32))) uint8_t rx_buffer[BUFFER_SIZE];//用于buffer
    % p0 a) n- ^. |: _" K% i0 ~
  4.     bool rx_xfer_done;                                     //用于记录dma已经被正确传输1 O. E; l1 O. a2 ?  b  Q$ }
  5. }st_dma_xfer
    " p7 m4 S7 C7 f2 D! R4 {
  6. * J2 d" f: o( z* E6 o5 \4 x2 K
  7. void XDMAC_Handler(void)
    2 r( k! J+ H+ [4 f
  8. {
    $ o! k  K* S6 ^5 k" ?  H
  9.     uint32_t dma_status;
    ; _6 G5 l- x2 m4 O9 u. m, N
  10.     dma_status = xdmac_channel_get_interrupt_status(XDMAC, XDMA_CH_RX);. {7 A+ i( Z% b& U+ N$ Y$ v
  11.     if (dma_status & XDMAC_CIS_BIS)
    . g0 M/ j; u$ W" W  E
  12.     {
    + E; N3 z; g) s; _* t$ c
  13.       g_st_dma_xfer.rx_xfer_done = true;% r1 N' A, B; [% V5 k3 u5 x! F0 N
  14.       SCB_InvalidateDCache_by_Addr((uint32_t*)g_st_dma_xfer.rx_buffer, DMA_TRANSFER_SIZE);
    1 U  @: N) d: x8 I( j' ^4 {
  15.     }
    4 ]; P$ [6 K! S! I. {, u  W" ]2 Y
  16. }
复制代码

. M& @7 H& y( |
& e9 `: \. V  J, |8 D" ~( {* S如果DMA的buffer只有16字节,DMA读取操作后,DMA控制器将接收到的数据写到了sram里面,然后进入DMA接收中断函数,cpu把成功读取的标识bool变量写为true,实际上写操作只是写在D-Cache里面,暂时没有写到sram。5 U0 A! R+ Q4 N
8 L1 @' I2 ^2 h
20201019190359602.png

2 F7 K- [1 \1 {! ^" M
' q# |: x+ j  x+ ~2 N如果此时cpu需要读取dma内容,需要对Dcache进行invalid操作,32个字节将一起更新,bool变量旧值0将覆盖新值1。cpu读不到中断函数写的bool变量信息。: c! d2 S& H7 R: n

* t# W; F. I( J8 y& {/ e
20201019190409891.png
0 j+ _' q. J$ a: f! P/ Q8 i

2 Z. P" w, s8 j7 t4 a; o* J3 |可见:
9 v# P* [0 }4 W1 {1 `4 n+ Y1 o/ x: lclean操作或者Invalidate操作都可能丢东西,使用上需要注意。经验是如果一段内存用来写dma外设,就不要读它,保证随时都可以clean;同样如果一段内存用来接收DMA外设传入信息,就不要用cpu写它,保证随时都可以invalidate。* ~& \; E$ [+ H, v3 L6 g

5 h6 Y, j* q$ w4 a1 ?! R
2020101919042042.png
  G- y( `& C1 \4 s; {( [

* ]$ l, A8 T* I3 E6 S6 K0 v( @6 _  f7 v0 R* A
收藏 评论0 发布时间:2021-12-26 17:22

举报

0个回答

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32Cube扩展软件包
意法半导体边缘AI套件
ST - 理想汽车豪华SUV案例
ST意法半导体智能家居案例
STM32 ARM Cortex 32位微控制器
关注我们
st-img 微信公众号
st-img 手机版