STM32H7-MPU
- g) u. R b$ z一、MPU的作用
5 Y0 i( L$ ~/ E0 q0 c( w防止不受信用的应用程序访问受保护的内存区域
! G& {4 ~- y3 [防止用户应用程序破坏操作系统使用的数据) X/ [ Y, u% k }. ]
通过阻止任务访问其他任务的数据区
* ^6 l4 Z* j) a5 O$ G7 I3 D* a允许将内存区域定义为只读,以便保护重要数据。
7 d7 U X' P6 x2 W/ D, P检测意外的内存访问
* S4 T0 P4 M5 b/ p. g简单来说,就是内存保护、外设保护和代码访问保护。
& s% l" l" r, b+ Z
, ?/ ~2 N: ~/ a2 A* d二、MPU的功能实现3 t3 G8 E# R; i( |8 g% r {
MPU可以配置保护16个内存区域,每个区域都是独立配置的。每个区域的最小要求是32字节,同时每个区域还可以配置为8个子区域,通过寄存器对应的bit来使能。
9 h% h8 a6 X- b1 b/ K+ c: Z5 ?' u+ v2 C7 B4 r
MPU可配置的16个内存区的序号范围是0-15,还有一个默认区(背景区)序号为-1,这些内存区可以重叠以及嵌套——序号为15的优先级最高、背景区的优先级最低。例如下图,共有七个内存区:一个背景区+序号为0-5的内存区。内存区4和内存区0、1有重叠部分,则重叠部分按照内存区4的配置规则执行;内存区5被完全包含在内存区3里面,则这部分内存区的配置按照内存区5的配置规则进行。
+ f8 ^0 ^% m! v$ M6 h6 K* s; b, k* t7 C3 w% p
) h5 u5 D& \; z; v& C$ K+ s/ ~+ y% @
& F0 ?3 D- [1 E) R7 z9 v
三、MPU常用的寄存器(RASR寄存器和控制寄存器)1 b1 s; ]+ S( m; S: f9 d
+ Z- B! p# c+ z6 I
, l$ d: L8 p8 x
/ ?2 R& ^& _* r4 Y" [. w6 ?
XN位:表示是否使能指令的提取
$ e' ^+ V* P" o9 i1 M) P( Y; WXN=0:使能指令提取,即这块内存可以执行程序代码
) I# R( L2 m0 N% x* TXN=1:禁止指令提取,机这块内存禁止执行程序代码
( @2 E* W; U% w& lAP位:设置指定区域的访问权限类型
% g7 ]+ a6 @, ~, g# ~$ h0 C- c
) Q! O! L- r) K6 o: F6 k, A' l U1 T5 d2 p- a
5 K7 l7 y: K+ ?0 M' L' G8 QTEX、C、B、S位:用于配置Cache的策略
M8 q- \4 h- C3 X+ M5 h% t
0 a- u3 a% h4 z$ c' m2 d" J# PC位:用于使能或者禁止Cache3 p$ W U. J3 M1 J1 ]
B位:用于配合C位实现Cache下是否使用缓冲: {- Y! R+ Y3 J* D* x2 \
S位:用于解决多总线或者多核访问的共享问题: l2 q3 ~- x0 T }$ i% }5 e2 W. x1 `
' X* H a% n0 i) E
7 O' x3 q3 M+ R/ ~
% |$ v9 J4 c7 g% X- _3 J y0 h |& l4 p+ @
5 W2 `+ b, I! o0 o* k
read/write-through/back/allocate的区别:
" @) l7 l+ C; Q$ Q, Y- ~
9 A, L% S* B [一、CPU读Cache8 k1 \$ j; ^) O, x' L V) R
" {9 M2 z( N6 t. Q3 E$ j; g0 ~Read through:直接从内存区读取数据
- U, i/ h; |# {6 e% {. T mRead allocate:先把数据读取到Cache中,再从Cache中读取数据 a& Z& U4 z# R; G& h3 E0 Q
二、CPU写Cache
7 y4 P0 U+ A7 J- J( }: @7 E5 d4 X/ x! q j1 _8 R4 C
若hit命中,有两种处理方式:
: W, T4 w1 R5 }; K6 e1 ~$ u1 Y h. c
Write-through:在数据更新时,把数据同时写入Cache和存储区
; O. A+ N9 ^& J) |- J& p操作简单,但是写入速度慢
) B6 e( d& U" g8 ^/ J- P+ gWrite-back:只有在数据被替换出缓存时,被修改的缓存数据才会被写到后端存储。8 \& i7 C0 \0 j' G$ g
写入速度快,但是一旦更新后的数据未被写入时出现断电,则数据无法找回8 K4 u' H0 O8 q2 I1 K
若miss,有两种处理方式:4 ?/ w6 P& I( M9 T) E2 F/ v
* z4 D4 M8 Y$ x) J- X, t4 V5 L2 RWrite allocate:先把要写的数据载入到Cache中,写Cache,然后再通过flush的方式写入到内存中。
4 L+ [9 ^& y: H6 k# ?! BNo-write allocate:并不将写入位置读入缓存,直接把要写的数据写入到内存中。
5 t5 Q3 W0 g' R! b4 p/ Q: o% q什么叫hit/miss:
i3 [8 F, n! g0 G/ L一、读操作
, J& u$ n$ t5 |7 ^如果CPU要读取的SRAM区数据在Cache中已经加载好,这就叫读命 中(Cache hit),如果Cache里面没有怎么办,这就是所谓的读Cache Miss。
! `# ]' [7 I& R' d. t% y( U( g$ T8 Z" h% g# k
二、写操作
! T1 u$ Z2 r0 B) n1 C如果CPU要写的SRAM区数据在Cache中已经开辟了对应的区域(专业词汇叫Cache Line,以32字节为单位),这就叫写命中(Cache hit),如果Cache里面没有开辟对应的区域怎么办,这就是所谓的写Cache Miss。
( e9 U, R& Z- i+ |
0 u! ~2 O! e: f* h4 \. |( J PSRD位:用于控制内存区的子区域,一共有8bit,一个bit控制一个子区域,一般都开启
/ ?$ |7 l m" l. q4 T' | J% ?SIZE位:配置保护的内存的大小
0 m" _/ G$ [- m: |9 I }: J# g4 d$ b$ q
+ S5 R0 t5 g4 |
四、MPU的HAL库配置函数! w7 e3 K" B0 [$ M% f w- x
HAL_MPU_Disable:配置前要禁止MPU
3 v) G0 [8 R. K& T; O5 \, SHAL_MPU_Enable:使能/ N: ~9 z* r% t- @6 D: O
一般使用参数MPU_PRIVILEGED_DEFAULT) A' x! o' b3 K. z* @4 {' `/ E
HAL_MPU_ConfigRegion:配置MPU
8 T6 B+ F9 T" C& f) E5 s- static void MPU_Config( void )
# f- y9 |& b+ ~1 Q6 Q1 l5 B; E! X - {
; Z, o, G3 t: p4 e% \$ {, Z2 R0 w - MPU_Region_InitTypeDef MPU_InitStruct;' z- y( u) a9 K' g/ O: ^
- ) I9 Q' z# f, s G E
- /* 禁止 MPU */4 J& j8 A, {: x ~3 w6 g5 g
- HAL_MPU_Disable();
' G |9 w/ P! }9 B5 k5 F3 q - /* 配置 AXI SRAM 的 MPU 属性为 Write back, Read allocate Write allocate */
- e% d$ R9 ?0 b6 [. ~# A
# h- a% V; a, K6 c: [- //使能MPU& |& D: V2 w' y
- MPU_InitStruct.Enable = MPU_REGION_ENABLE;
$ b: B3 Y0 d, c - //指定MPU保护的内存起始地址,注意要和下面的大小进行对齐" T+ E* I% L+ H" `$ H! n+ s4 i
- MPU_InitStruct.BaseAddress = 0x24000000;: R$ k1 B7 \7 w+ b) x( H# S3 L
- //配置保护的内存大小
0 g$ f& O' L0 _$ [# w - MPU_InitStruct.Size = MPU_REGION_SIZE_512KB;
9 @4 b+ I- H1 y5 l5 l# v - //配置区域访问权限类型6 i) c0 B% Z2 o0 A4 w
- MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
. w1 L. ?% Y4 o" n# m# Z - //在开启Cache下是否使用缓冲
' o t) Y) `9 P% D) n3 X - MPU_InitSt ruct.IsBufferable = MPU_ACCESS_BUFFERABLE;* k6 z$ k! M5 A% y X% c
- //是否开启Cache. b S- H' j: w- p, e% v
- MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE;
. R& |& D+ ^7 d - //是否开启共享
, Q. Q' R0 a' g" m; W - MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;. ?# x2 d' X K9 C0 Z( f4 R& ~8 X
- MPU_InitStruct.Number = MPU_REGION_NUMBER0;4 @: R) @; C9 t2 J; w7 K; ~7 m" K
- //配置缓存的策略* S% o$ M9 L: V8 V. G( ?* v" Q
- MPU_InitStruct.TypeExtField = M PU_TEX_LEVEL1;
1 W2 F5 p8 R4 B2 Z* i2 B - //是否开启子区域2 t2 B( [- p$ \& E7 M7 f/ e1 F
- MPU_InitStruct.SubRegionDisable = 0x00;
% J2 v2 ]6 K. s5 G: Z+ |# f$ C - //指定指令访问状态% Z/ q2 U' S- V4 ~* j
- MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;8 K; m, a# E6 }2 A! M0 N/ m
- HAL_MPU_ConfigRegion(&MPU_InitStruct);
% @% X0 M. h" R! S6 ^ T - # r( M! O/ @" |# U( w
- HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);: p) j8 K# \, B& ]3 d
- }
6 f% T$ W I# g1 `, J N5 E( n, S `
1 T; A$ L, C; q. \) r
复制代码
6 K0 \7 `; z# P
; K5 h8 w2 h, a4 N: m8 U' F |