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

【经验分享】STM32F7 MPU笔记

[复制链接]
STMCU小助手 发布时间:2021-12-12 21:00
MPU(内存保护单元)$ i( R  t- k$ C% @! x# {
1. 前言7 u; a; F  ^0 D2 c# P0 `
在跟项目过程中,使用的F7和H7两个芯片,在用FSMC和FPGA通信时,由于其CACHE的原因,导致数据一直出错,后来通过加入MPU顺利解决此问题。因此,去学习了一下MPU,在此记录下学习的笔记,可能有理解错误的地方,欢迎指出。
: E8 v0 f' s7 q: H参考:/ o! q- J3 O: I2 v
STM32F7中文参考手册.pdf7 S3 a6 v1 E# j: }" c( d
STM32F7编程手册.pdf
4 R& R6 |8 r; I4 W+ lSTM32 MPU说明.pdf
! \& V3 ^' g5 A% NCortex M3权威指南(中文).pdf" c4 }# P9 e* s/ g9 `4 v" ~
STM32F7开发指南-寄存器版本_V1.0.pdf+ ~2 F6 E5 y1 _, t5 U$ ~- M: C+ e
7 p1 x$ s  P- L9 b8 R7 p
2. 操作模式和特权级别% M7 F$ f" u$ v1 s5 k
详情------Cortex M3权威指南(中文).pdf-----chpt024 g5 E3 l! `" S5 V) R! H% a, E
. d; `- p/ S& @
2.1操作模式
6 u) U- G/ Q6 t! oHandler模式:异常服务相关的代码
$ t. ?  M4 D- g, d4 k, p' Q' c线程模式:普通应用相关的代码- D, z: f* N9 l! T  f
个人理解是如中断服务程序的代码与正常执行的代码。- q, ?# ~; j; I9 x; H6 F0 o' w

0 t, p( b8 N8 _$ f" [2.2 特权级别
* t' b: j6 |; L/ ]  J% Y分:a.特权级 b.用户级
3 Q3 d6 s1 L( n9 u$ s- f区别在于对存储器的访问权限不同,特权级相当于管理员权限,除了MPU限制的区域外其他都可以访问,而并不是所有区域都对用户级开放。, n8 P8 r) M* y

3 N4 Z$ U; q: D: ~* @! E- R4 _9 s2.3 联系
& X# e0 G; f6 j* O& ]$ ?
20191228150751310.png
6 G3 [+ M$ m! y4 g; I* v

" U# ^) P+ w* P6 O: p) j& T正常执行的应用程序代码,对特权级和用户级开放;但是异常代码如中断服务程序,仅能对特权级开放。2 x6 f; _  t2 s1 H/ ^5 y" }2 u
$ k/ U% R: \0 T
20191228150918107.png
% R% w" l3 H5 a  y% q- J3 U" x
' t* d" }9 d- l. d0 D; l9 F
如图:当产生异常时要去执行异常代码,执行完成返回到断点。而无论在用户级还是特权级线程模式下,即使是用户级,在进入handler代码时也会暂时被提升到特权级模式,因为handler模式不能被用户级访问。
# b! q: T3 t  @3 o特权级可任意访问,包括切换到用户级,仅需要修改CONTROL寄存器即可。
2 R! ^" }) E1 U5 d$ J8 b但是用户级切换到特权级不同,需要先申诉(执行SVC指令,触发该异常,进入异常服务代码),由于异常服务代码中是特权级模式,因此可以任意修改CONTROL寄存器,这样才能将用户级----转换---->特权级。8 t3 J0 a0 m" E5 F% M4 U" u2 o  y% X
( _- R% J1 S7 j3 Q
3. MPU
/ z6 O( I- C$ K7 ]Memory Protect Uint-----内存保护单元; Z% A# Y+ W( l+ B9 @* f. @4 L
6 V0 Q9 [- B: F5 P
3.1 作用
" y* }* M( X3 [9 p. z参考了以上的PDF,大致说了以下的作用。! u( q3 l/ [4 |3 Q$ z2 f4 C1 U

( X) @$ S/ i6 `2 I) k1 @
20191228154605163.png

! o. n4 g/ S5 f# a3 _. d3 T8 l" T% j
其实更多给我的理解是:通过MPU对存储器的某些区域进行属性设置,设置其对特权级/用户级开放,可读可写/只读/只写、禁止访问、全访问、支持/禁止CACHE、缓冲等等的属性,通过MPU管理存储器,不至于某块内存被非法访问、数据破坏、CACHE等等。
5 I- S) v% D) V, {6 x& I6 L4 q. _+ y+ b+ a+ h
3.2 REGION(区)
" f( R) z9 ]; oSTM32F7支持8个区,也就是说,MPU控制器通过8个区来管理存储器。# ~0 k+ }/ p# B5 F# F9 E: z) G
如果8个区不够,每个区都可以再细分为8个子区。大概理解图如下
% |9 c0 k0 O5 c. g! x3 g% d3 C; f% l6 V
2019122815582658.png
3 M6 t/ a# J1 T: r/ r: E

+ L- N0 z' v3 r' T  A$ j背景区
9 W" y, A) C' j0 v- x背景区,即没有被设置到MPU管理区的其他所有地址,背景区只能被特权级访问。否则出现MemManage异常,如果开了MemManage,会进入MemManage中断服务程序。
- ]3 Q4 j# z3 M  k
) _  I. w2 `$ e3.3 MPU寄存器
2 K2 r9 c6 c( b* A/ [3 n
M3权威指南中的MPU寄存器, D* Q$ L$ k% @
* I, D! J# q/ Z4 p5 C! b
20191230094650359.png

" m0 O1 D( _: F* e2 A/ s* C) ~+ z+ v. E2 D2 F+ z" K6 ?
原子教程中的寄存器( x) {! i" m( _8 E% _
6 }8 t( F/ L; w
20191230094823372.png
$ ?, J2 @. S- G) H
9 w7 ]4 v  ^" {0 o) T; Y# \
M7 MPU手册
' w! ]' F; r. N3 \  Z
4 J* D: w/ g0 b/ W. p( H
20191230100630574.png
# U* q6 ?9 {  ?- z( p% a1 g
8 O& G* S4 e2 J! `
MDK工程中MPU控制器的寄存器
! Y1 i+ O* o: x' Y/ N) Q
! z1 K9 k9 ?0 p% q
20191230094954114.png

- C8 _, r7 e/ i; v) F9 ~
# P2 Z' l. s' u# {* W其中% u3 F/ l' W- ]1 M2 N! {( d5 K+ c0 C
  1. #if (__MPU_PRESENT == 1U)
    3 H' w+ x: o5 b7 i* x; |
  2.   #define MPU_BASE          (SCS_BASE +  0x0D90UL)                    /*!< Memory Protection Unit */
    6 u/ I9 ~( Z/ w3 O6 @. T  e
  3.   #define MPU               ((MPU_Type       *)     MPU_BASE      )   /*!< Memory Protection Unit */
    ( d" K' q6 \! e$ v9 W: p7 t
  4. #endif
    ( i* c5 p. {% M. U3 Q

  5. " s6 R; C& U+ ~- c4 N# D, M* |

  6. 4 I6 @# O# n' h& h: b! H7 ~
  7. #define SCS_BASE            (0xE000E000UL)                            /*!< System Control Space Base Address */
复制代码
3 Z4 l* E! W: J
可以看出MPU指向0xE000ED90,并结合MPU_Type类型,可以推算出,其每个寄存器的地址,都和M3权威手册中的寄存器对得上,因此放心操作。
) H3 \3 P; K' w3 d: F( S# v4 U) r/ _9 B' Z# P
MPU 控制寄存器(CTRL)
5 H; a# r6 q5 X+ w2 `0 K2 ^" U+ I. N" a+ E# @
20191230100816571.png
, H, A) P. ~9 X6 L1 _0 v: _

- [0 y/ P- {7 V; Y/ B5 c! A, z1 L仅三个位有效
4 L! C4 }- z4 Q( C. J4 f% A$ }5 yPRIVDEFENA:配置为1,特权级能访问背景区,用户级不行,而配置为0,仅能访问REGION区,其他都会出错,包括属于背景区的区域。2 U, H+ S' R1 W1 B. ~; s
HFNMIENA:用于在NM1或者FAULT中断关闭MPU& ]* _- @4 h8 A& e3 `$ p
ENABLE:使能( W0 y- v) a: S' N" E; B' _' u5 K
; h" Y; i! b7 A; a9 P6 e( k  |7 C" t- A
编号寄存器(RNR)

# a. U; r1 `* [
) I1 m) R, ~) B$ y( Q/ X+ c
20191230101328822.png
* e* H2 v% t7 S1 m( V
1 F. X, o6 a; a5 M7 {( w) ]( b
配置每个区时要先写该寄存器,MPU控制器就知道在配置哪个区。比如要配置REGION 1,需要向RNR寄存器写入一个1;配置好后需要配置REGION5,仍向RNR写入5。4 X/ N$ n/ Z  N  x

5 ~- A/ o. }: z! EMPU 基地址寄存器(RBAR)9 X0 S& \8 O6 I
+ X2 O4 c, U' `* a+ V
20191230101535603.png
2 k5 F/ p( j1 ]& y
& v; n% k' C& u/ H) b
一般不适用VALID位和REGION位,这两位的意思是覆盖RNR里面的值,也就是这两个的值才是我们正在配置的REGION,RNR不生效。. @9 ^# [% j% z* p7 J1 _5 D

0 m; u8 T6 \7 d: ^ADDR:配置MPU某个REGION管理的存储器的基地址,要求是----需要该地址需要是REGION大小的整数倍,比如REGION1设置为64K,那么ADDR的值需要如0X0001 0000、0X0002 0000等,0X0001000065536/102464K刚刚好
" O+ a& v2 K! i& V' V
) L/ T" A1 ~6 t4 F0 R' p# A2 xMPU 区域属性和容量寄存器(RASR)% i! G. W& R$ W  T

$ L1 ?, x4 ^, ^( H% l: g, V9 A
20191230103223269.png
0 W: e' [3 Z5 T! P' e/ c2 Z
+ p- {5 w$ {4 ?+ b9 z
XN:设置的REGION区管理范围是否允许取指
  \( [5 ?4 u. q' @% SAP:基本是6种形式。
; m" C, F) ~; p
, M4 V! {0 p9 I! W( F# X
20191230103426788.png
6 |5 C: E' W9 R

! H! I. {! {8 B: }& M8 c+ }分别是:全禁止(任何级别不可读写),只特权可读可写,用户级不可写,任何级别可读可写,只特权只读,只读。! \1 w7 m; p1 `7 Y
TXE,C,B,S
6 k2 g, s/ v- ]) Q& x- M; f6 w; B: \+ T# T
20191230103747475.png

( M6 S9 V4 H$ x, d! \% U6 g( |& _/ s' }# o: g
20191230103850819.png
' a- S5 J! i" @( T6 `9 n- t
+ }! t* b  ]( A
其中:% G* ?. u5 g+ d' }& C3 u4 b
强序-------------按照程序一条指令一条指令顺序执行。/ r2 Y$ a  O  F) T8 y$ [
共享------------一块内存可同时被多个设备访问,比如两个DMA同时访问某个区域。6 `1 t' x' I- Z8 s% ]
缓冲------------类似有个缓冲器,但是要考虑是否有数据缓冲的阈值,未验证。
; H9 ^1 x! j9 i+ v4 b8 _缓存-----------CACHE,有命中和MISS,可能造成数据不一致,但是效率较快。
2 t+ E4 g" K% l3 l# r写回-----------CPU更新到CACHE,仅当需要丢弃时CPU将数据更新到主存,期间数据不一致。
7 N0 `. \$ o3 |7 [写通-----------CPU更新数据时,CACHE和主存都更新。
: e3 _8 b/ T7 `' l
  L! h+ u* H- W* [注意$ J3 F1 R/ ~7 Q; m
M3权威指南中,P195,需要SHCSR使能MEM中断。
% T, T" e, z- @9 L8 l
1 T9 e! V* ~2 X6 u
20191230105312512.png
% ^; d; `* a) h+ ]1 f. i1 O+ \  J6 a

/ r* t& o0 }$ O! ?4 Y" _' g+ J3.3 相关代码
. x. q9 ~* G" x6 u. G0 V
初始化,将SRAM 0X20002000设置为128字节,不可共享/缓冲/CACHE,且只能特权级读, x- ?, [+ e$ }: E- d) N0 ]% X
4 q) ?8 |, h. }' K, s- r& ]9 y( a
  1. /**************************: _6 c9 U) s% z) V( u
  2.         名称:STM32F7_MPU_INIT
    5 {& M! Y# f: n" ]% V* Z* {' \
  3.         功能:MPU初始化* p6 X' Q" \0 W
  4.         参数:无
    - Q" e9 k/ `' A9 ~4 k5 ]
  5.         返回值:无! a. L/ c2 A  B  F% s
  6. ***************************
    / h- Y) E$ G" l# L; O# y; _
  7. */
    8 d+ s' f0 Y$ t; o3 t& n% W* w
  8. void STM32F7_MPU_INIT(void)
      C  u- D/ G# _2 p9 R
  9. {
    . f1 p, z( S4 G8 f
  10.                 u8 i = 0;
    5 V8 _. f! H6 f9 K
  11.                 u32 rasr = 0;7 n) Z) ^1 E8 c+ S" C& ~/ s
  12.                 8 x) Y9 |' ?% f2 d' @, h& T1 g' g
  13.                 STM32F7_MPU_DISABLE();                // 关闭MPU        2 f' M1 \, v/ `/ C2 G
  14.                 //MPU->CTRL &= ~(1<<2);                        // 背景区
    6 ?% S: `, c# a  ~4 `; k5 g
  15.                 MPU->CTRL |= (1<<2);                        // 背景区! m; S6 E9 _8 o5 h
  16.                 MPU->CTRL &= ~(1<<1);                        // 不强制除能MPU
    7 ~# G+ A$ S. G1 h! j( R
  17.                 MPU->RNR &= ~(0X7<<0);                // 配置哪个区,只有低3位有效
    6 ~, }  m. I8 e" `& t" Y4 ]8 d0 V( K: Q
  18.                 MPU->RNR |= ((0)&(0X7));        // 使用1区0 r0 w8 |9 x& ?- h" d; F
  19.                 MPU->RASR=0;                                                        // RASR清0
    3 L/ f' @: t; H
  20.                 MPU->RBAR&=~(0X1F);                                // 不认可region位# b; W1 F" i1 W- e7 r6 {7 y
  21.                 MPU->RBAR|=0X20002000;                // 地址0x200200009 w3 @9 O' }. Q
  22.                 rasr &= ~(1<<28);                        // XN : 1禁止取指  0允许取指
    & D$ I* `* s& j, [
  23.                 //rasr |= (1<<28);                        // XN : 1禁止取指  0允许取指& x& Y2 n/ t! N; m' |
  24.                 rasr &= ~(0X7<<24);        // AP:101只读
    ; G/ {! W9 [" }; l2 e. _3 R0 T
  25.                 rasr |= (5<<24);7 p" T( [# H) ~4 \
  26.                 rasr &= ~(0X7<<19);        // TEX:001  C:0 B:0  S:0  片内外不可缓存型内存
    ( F# m0 D3 ]# z6 H+ s/ r& ^0 e  G: W
  27.                 //rasr |= (1<<19);! z6 R6 r, {+ q6 I; q6 Z: D* i0 B
  28.                 rasr &= ~(7<<16);7 \: p+ P, ?+ W/ P# x: i
  29.                 //rasr |= (1<<16);
    0 A* J1 R0 N4 v: I* e
  30.                 rasr &= ~(8<<8);                        // 不使用子区域2 f5 j/ v% t% R# F4 q* U$ w
  31.                 rasr &= ~(0X1F<<1);        // 64K = 2^(15+1)
    * e/ h& c+ q" E5 n+ H4 K1 t
  32.                 rasr |= (6<<1);
      c% }2 _& M- r+ ~
  33.                 rasr|= (1<<0);                        // 使能该区/ D; L0 V# ~  r# P& o. V5 z
  34.                 MPU->RASR = rasr;
    2 _! c- ]. e0 |7 @. p+ @9 J& ?
  35.                 // 使能MPU! z0 @- }' R. j
  36.                 SCB->SHCSR|=1<<16;                //使能MemManage$ w8 V3 H) p4 G! b( W& E1 S
  37.                 MPU->CTRL |= (1<<0);7 ?8 `# q7 U% n* r
  38. }
复制代码

; l( r' E$ y) l; V测试,写入一个值,即进入MEM中断  C5 X  g* g; y! S$ l
; X1 J2 t+ K" p% d! t) R
  1. u32 mpu_test __attribute__((at(0X20002000)));5 G  ^! A! h; M; L9 p4 ~0 t, U
  2. void MPU_Test(void)* j# U, g! w' d
  3. {2 C% e. p  F! Z5 H( x  d
  4.                 u8 key = 0;: t- M' D  C, `) [
  5.                 key = KEY_Scan(1);
    5 _! ^1 i. ~" N2 |+ X) [( L
  6.                 if (key!=0)
    / e9 _; s) k% a0 t- i; A9 l
  7.                 {; p$ P. B$ u9 G) b& c
  8.                                 mpu_test = 20;% U  r8 K3 N" ?2 ~) X/ \2 L
  9.                 }
    $ x0 f5 ~' w$ U8 ]# H
  10. }
    3 @) t9 k& j8 E
复制代码

5 i+ S% t1 s5 i" e6 R
0 v2 |/ l$ A  L1 ~; p0 x
9 I: W4 \  m& r4 d+ b  e5 ]
收藏 评论0 发布时间:2021-12-12 21:00

举报

0个回答

所属标签

相似技术帖

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