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

【经验分享】STM32F7 MPU笔记

[复制链接]
STMCU小助手 发布时间:2021-12-12 21:00
MPU(内存保护单元)
1 \& N) d* Y- \7 I# y1. 前言
) A. X6 I# R: v  f在跟项目过程中,使用的F7和H7两个芯片,在用FSMC和FPGA通信时,由于其CACHE的原因,导致数据一直出错,后来通过加入MPU顺利解决此问题。因此,去学习了一下MPU,在此记录下学习的笔记,可能有理解错误的地方,欢迎指出。  L4 a8 X! }9 l7 D2 r1 V, p- d7 C
参考:' y$ i6 [  a: j7 Q% G
STM32F7中文参考手册.pdf
( W/ N3 n* P: t( m5 O7 {) SSTM32F7编程手册.pdf
+ x; o' l7 I! L" {4 i1 g% O, CSTM32 MPU说明.pdf
5 n: A, ^& e1 A5 G5 w9 _6 \Cortex M3权威指南(中文).pdf) B' o: e, K5 t: ]* H& F% \& U/ Q
STM32F7开发指南-寄存器版本_V1.0.pdf
6 C9 N7 L: T$ g1 [: G* |9 N
1 A" s6 {5 p3 e$ `, p2. 操作模式和特权级别6 ^) w( e) _$ o) S9 A, N- B
详情------Cortex M3权威指南(中文).pdf-----chpt021 y- S1 u+ D* W2 m( _2 x' ^, @
* N+ @& I7 Z1 T
2.1操作模式6 ], t0 B. a- p/ {$ p4 c
Handler模式:异常服务相关的代码" W; y- q/ r- L5 g% p
线程模式:普通应用相关的代码
9 Q: G4 J8 J4 |个人理解是如中断服务程序的代码与正常执行的代码。
# _2 L1 s0 E* I, o5 e: R7 A! k; P) m# _- F
2.2 特权级别
% X9 l& t1 |4 [5 q! g8 V* e分:a.特权级 b.用户级
% T; B. C" C9 d# t$ z- Y区别在于对存储器的访问权限不同,特权级相当于管理员权限,除了MPU限制的区域外其他都可以访问,而并不是所有区域都对用户级开放。
* R+ ^1 I5 v, M5 R! x- x% w/ q' ?, P3 T. R" }! a
2.3 联系' r' p" k, @: m
20191228150751310.png

( o: e* ^# @% r$ a: V( l, ^
7 R9 U8 E2 f( v, T, J正常执行的应用程序代码,对特权级和用户级开放;但是异常代码如中断服务程序,仅能对特权级开放。
2 n6 H3 N2 `( r5 ?# M
  E7 f; o( t+ f
20191228150918107.png
. P' |; Q- n) N6 D9 w# \8 B  p! ]
0 s! t* ?( \$ ]3 S
如图:当产生异常时要去执行异常代码,执行完成返回到断点。而无论在用户级还是特权级线程模式下,即使是用户级,在进入handler代码时也会暂时被提升到特权级模式,因为handler模式不能被用户级访问。
: E4 P6 l2 |. S! J3 T* |特权级可任意访问,包括切换到用户级,仅需要修改CONTROL寄存器即可。
2 z4 s& Y# h7 x0 B9 k4 u9 p但是用户级切换到特权级不同,需要先申诉(执行SVC指令,触发该异常,进入异常服务代码),由于异常服务代码中是特权级模式,因此可以任意修改CONTROL寄存器,这样才能将用户级----转换---->特权级。
6 a2 I; o: ?5 J# o  W: k  ^4 M% l1 |$ n( _; c7 R0 M+ @3 r
3. MPU$ e) M7 M. g1 o4 K8 z, F2 ~+ ?
Memory Protect Uint-----内存保护单元) V1 T2 C# I' X7 E( q9 b( B' l: p
4 d6 S) w- ^6 r
3.1 作用
, B$ w. [/ C/ L5 v4 v1 q参考了以上的PDF,大致说了以下的作用。9 ^5 n) y% \2 U0 j" \" ]- ?# t
) T" ]; v9 E: U/ a% u; f3 \4 _' @
20191228154605163.png
% X0 C, Z. H% W$ B# I! g

# A$ F, S6 l2 z' p. g5 B4 i- g其实更多给我的理解是:通过MPU对存储器的某些区域进行属性设置,设置其对特权级/用户级开放,可读可写/只读/只写、禁止访问、全访问、支持/禁止CACHE、缓冲等等的属性,通过MPU管理存储器,不至于某块内存被非法访问、数据破坏、CACHE等等。8 S1 w" z; P8 H4 f+ M3 |& `% e, l
( U0 [8 b8 M8 h' w
3.2 REGION(区)
: g" X/ k4 {5 {9 ?6 hSTM32F7支持8个区,也就是说,MPU控制器通过8个区来管理存储器。- h- I: W2 I( V) H  p" H" s
如果8个区不够,每个区都可以再细分为8个子区。大概理解图如下
  m8 ]6 }1 \6 ], L! M6 M
) ]& T$ n$ V" A; l0 L( L8 ]
2019122815582658.png
# z; Z6 p" W0 E# j+ N

3 a' u0 H5 M1 W7 v; r4 p/ p. g5 S3 z背景区, s; Y: l& c9 j8 k! v' C  T
背景区,即没有被设置到MPU管理区的其他所有地址,背景区只能被特权级访问。否则出现MemManage异常,如果开了MemManage,会进入MemManage中断服务程序。  [0 h, b& k9 e  V; I& n
& W3 ]0 r9 |5 T: \- ^; g# h
3.3 MPU寄存器
, H6 J" }' ?& U6 v% U
M3权威指南中的MPU寄存器% y0 y: I" c% U: R  U9 ?

- F/ v& m; v, t. N& s; u
20191230094650359.png

, ~7 I# X- }( _; d9 @3 X! V5 [9 c9 }2 j  R% H) g' m
原子教程中的寄存器
+ d! c, j$ R! {# `% V3 b- q; U+ K0 l2 H0 @' M* }
20191230094823372.png
! F3 O) p. m0 w) h. J0 E9 I
$ {0 [$ ?9 d5 H7 U2 C
M7 MPU手册
! L! m. e6 y# e/ A/ F5 J6 |: k" X; u! M: {
20191230100630574.png

! p9 h* l  {( }/ ~$ F0 A  P7 ^0 @6 @+ J- w6 c- ~" k
MDK工程中MPU控制器的寄存器* \. T5 C; S* [
5 l+ p0 Z9 L+ m7 ~
20191230094954114.png

, s8 P  N2 p9 B$ l
# v) ]/ f# c8 Y' x" R& I# a其中* C/ M" r! I" W- A$ S$ \
  1. #if (__MPU_PRESENT == 1U)8 ^% I4 ?  F! P2 m
  2.   #define MPU_BASE          (SCS_BASE +  0x0D90UL)                    /*!< Memory Protection Unit */
    4 I" m. {0 F# b" h9 Y2 s
  3.   #define MPU               ((MPU_Type       *)     MPU_BASE      )   /*!< Memory Protection Unit */
    & M! {, H7 l$ Z$ H( H0 V
  4. #endif5 w* ]5 h) o1 Q7 C7 I3 k

  5. + J/ p' c0 M/ I" @9 D- O) m
  6. 0 l, b0 w1 \7 ?! K2 L" r* n( k
  7. #define SCS_BASE            (0xE000E000UL)                            /*!< System Control Space Base Address */
复制代码

# K% ]( s. Y7 K. ]  |可以看出MPU指向0xE000ED90,并结合MPU_Type类型,可以推算出,其每个寄存器的地址,都和M3权威手册中的寄存器对得上,因此放心操作。
1 `% O4 H; g7 u& V5 N5 o$ @) @& h# E1 o: x6 H
MPU 控制寄存器(CTRL)4 q, ], ^4 _- l) a

9 }2 ^& l( `: J0 F4 i) K; n
20191230100816571.png

# A* K! H/ e0 A% R1 P. _: V+ F/ e6 g1 s8 j
仅三个位有效
, o6 A3 l, A% H) ?4 v) t7 [6 t, }PRIVDEFENA:配置为1,特权级能访问背景区,用户级不行,而配置为0,仅能访问REGION区,其他都会出错,包括属于背景区的区域。
$ ~7 M: I' |: VHFNMIENA:用于在NM1或者FAULT中断关闭MPU
. w7 w: t3 J2 j3 U0 [& r; j. rENABLE:使能5 L2 t% p; {0 L( B* i4 Q# j

9 O( ]* Z: K8 E& e4 q. ^% N, ^' H编号寄存器(RNR)

8 l' Z* d" f6 J  ~* w2 H% m% Y
' ?8 r7 h' H8 E: T. w
20191230101328822.png

1 J( i  N- j6 w+ N2 a; R+ U" F% x$ [& {9 H; z. u0 F) t
配置每个区时要先写该寄存器,MPU控制器就知道在配置哪个区。比如要配置REGION 1,需要向RNR寄存器写入一个1;配置好后需要配置REGION5,仍向RNR写入5。
4 A5 N, S* B  O( W- i" W' E& h1 R2 \' d6 {# k# \
MPU 基地址寄存器(RBAR)  I- U1 m3 c7 \& q6 J
# ?) U, j$ W  u1 Q5 {
20191230101535603.png
* c- |5 S3 B) N6 U
, m9 Z$ O8 m2 b
一般不适用VALID位和REGION位,这两位的意思是覆盖RNR里面的值,也就是这两个的值才是我们正在配置的REGION,RNR不生效。
1 H; {2 t4 ?. T$ d! {
0 i! W9 S* X0 N4 b# D" AADDR:配置MPU某个REGION管理的存储器的基地址,要求是----需要该地址需要是REGION大小的整数倍,比如REGION1设置为64K,那么ADDR的值需要如0X0001 0000、0X0002 0000等,0X0001000065536/102464K刚刚好8 m& g0 A, ]' Z4 B, X6 {
0 x: c$ G9 ^4 f9 r: w. ?; U7 a$ W6 ]
MPU 区域属性和容量寄存器(RASR)
! l) }" ?5 H9 ?8 @( C/ `! Y0 a( S6 A& J5 E+ x0 o
20191230103223269.png

- X9 o9 X( n9 r6 p; B) w2 t1 @* p" b% N9 Q
XN:设置的REGION区管理范围是否允许取指
* u" Y$ _- }" I7 YAP:基本是6种形式。: F: s, I/ X2 ?+ Q5 c/ U4 }) F6 Z* A

% w) G1 X/ f/ C# N2 Y
20191230103426788.png

$ C8 q- Y/ P9 d, Z7 d) r/ r
# Q( w, {' K/ ]分别是:全禁止(任何级别不可读写),只特权可读可写,用户级不可写,任何级别可读可写,只特权只读,只读。/ ^+ E5 e: N* o. ]  W& z
TXE,C,B,S# `' L* I* T  Y! y7 y

" p: ?9 n5 ]. m" k3 ^
20191230103747475.png
- c1 b6 q  w. T' t, O6 c6 E, Q6 _

! x9 `6 e% _, F4 x6 Q- d6 L
20191230103850819.png

2 n" u' f1 o8 }0 H/ i& y
" P% O- W8 o$ j+ E; {" N, z7 `其中:" g' k$ O$ u, y7 Q1 W
强序-------------按照程序一条指令一条指令顺序执行。0 N: G5 z4 I$ U6 W& f8 ~. l) s$ J
共享------------一块内存可同时被多个设备访问,比如两个DMA同时访问某个区域。
, r4 X! P$ E4 K1 c, ]  f缓冲------------类似有个缓冲器,但是要考虑是否有数据缓冲的阈值,未验证。6 o8 f$ Z% Y( D: x
缓存-----------CACHE,有命中和MISS,可能造成数据不一致,但是效率较快。
5 A2 [! B0 [; i写回-----------CPU更新到CACHE,仅当需要丢弃时CPU将数据更新到主存,期间数据不一致。2 r0 I0 J* t7 V* I
写通-----------CPU更新数据时,CACHE和主存都更新。
, H% }3 k" [/ g, N# E; [) O
0 V) n- B0 |/ q) Q- @# M注意
6 k, y# y) R; f+ S6 qM3权威指南中,P195,需要SHCSR使能MEM中断。
% i) P% P* s' |+ T* ?# F0 K  |( d" \6 w: r. f
20191230105312512.png
! W1 w) u* F: a/ V5 K8 o
/ r& U5 W. A4 n3 h& c; G  H7 F6 d
3.3 相关代码

6 X0 Z$ O- b* {, k初始化,将SRAM 0X20002000设置为128字节,不可共享/缓冲/CACHE,且只能特权级读
+ i" r' }9 t! G( T8 q0 A  j! L- o8 b. _% U, `
  1. /**************************2 ~$ g5 l/ Q& t$ _0 F# q8 h. E
  2.         名称:STM32F7_MPU_INIT
    : Y6 l! c" N8 |( L  ]. ]5 J
  3.         功能:MPU初始化' B$ S2 P7 ~% A# e/ H+ f, i# z
  4.         参数:无
    ' J3 P" ~, F& k' n$ p6 J' K
  5.         返回值:无
    ( {& k7 F; r0 a7 c" }
  6. ***************************
    # C. K+ u) b5 s" D" b- |- R
  7. */
    % v* u" f" C+ G1 i' f
  8. void STM32F7_MPU_INIT(void)7 b& c, n' z! J2 i4 ?
  9. {
    8 E( ^; f3 l! c; i
  10.                 u8 i = 0;8 p: J# D' L, l& m5 T3 Y! E
  11.                 u32 rasr = 0;
    ' J+ g3 C, W& n, S( H+ c
  12.                 ; L' J# t$ Z& D9 g1 ]" B7 H
  13.                 STM32F7_MPU_DISABLE();                // 关闭MPU        
    ! S  o2 e# f# Z7 S8 o, U
  14.                 //MPU->CTRL &= ~(1<<2);                        // 背景区) P, L% M- W, F( J; Q  ?1 Z
  15.                 MPU->CTRL |= (1<<2);                        // 背景区1 l( K4 E/ T6 P$ l& R0 B9 V
  16.                 MPU->CTRL &= ~(1<<1);                        // 不强制除能MPU  S" P! U9 J* R$ f4 E$ E, r8 e7 U
  17.                 MPU->RNR &= ~(0X7<<0);                // 配置哪个区,只有低3位有效5 v% |5 V! z* z
  18.                 MPU->RNR |= ((0)&(0X7));        // 使用1区3 R0 r/ {8 `( ?( q. |/ z/ ]7 V
  19.                 MPU->RASR=0;                                                        // RASR清0; z6 m' q3 b' d) a, c5 u* {+ ~+ `
  20.                 MPU->RBAR&=~(0X1F);                                // 不认可region位# \% E; z* u( V# P
  21.                 MPU->RBAR|=0X20002000;                // 地址0x20020000
    6 |  Z( n# }' |% }& v) a  v
  22.                 rasr &= ~(1<<28);                        // XN : 1禁止取指  0允许取指6 E* c4 E5 N) k3 W
  23.                 //rasr |= (1<<28);                        // XN : 1禁止取指  0允许取指. }1 i8 F# B5 r! `
  24.                 rasr &= ~(0X7<<24);        // AP:101只读! A1 Q7 f6 T; [; l- B  z4 h& w
  25.                 rasr |= (5<<24);. _7 s" H: Y% F) w
  26.                 rasr &= ~(0X7<<19);        // TEX:001  C:0 B:0  S:0  片内外不可缓存型内存6 R. _: O1 }! n6 b$ R9 j0 b
  27.                 //rasr |= (1<<19);1 n& Y) ]$ h' Y/ }
  28.                 rasr &= ~(7<<16);; S) y( ?- S* Y  G
  29.                 //rasr |= (1<<16);8 O' h# [' N+ q3 C$ W2 Q. `5 n
  30.                 rasr &= ~(8<<8);                        // 不使用子区域
    7 B8 [0 A% p3 k4 I" @4 _, i- {
  31.                 rasr &= ~(0X1F<<1);        // 64K = 2^(15+1)
    , B1 R, D  B* W; j
  32.                 rasr |= (6<<1);- F" z* P: M6 M- Z# p* G
  33.                 rasr|= (1<<0);                        // 使能该区8 M6 D  W3 i/ H% }' z$ }  w3 j
  34.                 MPU->RASR = rasr;
    1 S8 W2 a! B: h3 t) ^  Z
  35.                 // 使能MPU
    8 Z4 w4 V- K! T
  36.                 SCB->SHCSR|=1<<16;                //使能MemManage5 X* |' g, b& k8 x
  37.                 MPU->CTRL |= (1<<0);
    9 I, ~0 t6 O9 x$ T' q4 t
  38. }
复制代码

2 f4 x* W& w% X; _8 r测试,写入一个值,即进入MEM中断
; D& C, q5 G! v% T( q  ~+ Q9 b# ~9 Z' J  B) H$ L, ?
  1. u32 mpu_test __attribute__((at(0X20002000)));3 v8 j  O3 F& x6 u- T3 |
  2. void MPU_Test(void)
    - @4 l" Q. o# @  O0 V7 d% i
  3. {, Q1 b4 A' `4 Y0 ^) A* l
  4.                 u8 key = 0;5 b# {  C, q3 n/ X
  5.                 key = KEY_Scan(1);
    * P! d& Z% J2 R* W
  6.                 if (key!=0)( s' W, Y; }3 @, W3 }. X6 W
  7.                 {/ D9 L  Y% k0 f9 f
  8.                                 mpu_test = 20;
    8 ]" ]: v" w% H; G9 Q. c
  9.                 }
    ! Y+ l" g2 K# D7 B
  10. }
    / Y, D! Y6 y. z
复制代码

6 Q# t3 g5 o3 ^1 ^8 S' C; a+ A% x6 |  V& t+ w" X+ k/ C
1 B" h. X3 [! @  V4 i
赞 收藏 评论0 发布时间:2021-12-12 21:00

举报

0个回答

所属标签

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版