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

【安富莱STM32F407之uCOS-III教程】第6章 内存保护单元MPU

[复制链接]
baiyongbin2009 发布时间:2014-12-19 18:09
本帖最后由 baiyongbin2009 于 2014-12-19 18:12 编辑
/ S& \* X/ H5 P, m
- O+ i$ H) \: L2 ?特别说明:
2 G; V, Z# K0 K1.  本教程是安富莱电子原创。% u$ n2 c1 M  T% s0 a
2.  安富莱STM32F407开发板资料已经全部开源,开源地址:地址链接
3 ?6 z/ Y+ x; e: T; O) r3.  当前共配套300多个实例,4套用户手册。

0 ?5 C( Z2 R* j5 J
第6章  内存保护单元MPU

! b$ z; M- m1 b+ v& ^
    本期教程带领大家学习内存保护单元MPU的使用,在前面的几期教程中曾多次的提到MPU的使用,MPU在RTOS的安全关键设计中也十分的重要,μCOS-III和μCOS-II就有配套的μC/OS-MPU,不过没有对外开源,对于想学习其源代码的人来说有点可惜,而FreeRTOS也支持MPU的配置,有兴趣的可以去学习了解。本期教程主要学习M4内核支持的MPU单元。
      6.1 MPU的介绍
  6.2 实验例程说明
  6.3 实验总结
6.1  MPU的介绍
    关于MPU的基础知识在Cortex-M3权威指南中文版的第14章有非常详细的介绍,或者看Cortex-M4权威指南英文版第11章。如果打算学习MPU,这两章一定要认真的看完。这个是下面几个MPU实验的基础,也是以后学习RTOS中关于MPU的基础。
6.2  实验例程说明
    一共为本期教程制作了3个例子,下面就跟大家详细讲解这3个例子。前两个工程都不需要添加额外的文件,将代码都放在了main.c文件中实现,第三个工程专门做了一个驱动文件,方便后面教程配套实验中调用。
6.1.png
( d) {' G( c6 k! }, u# }3 ?' v
6.2.1      实验一:MPU简易使用例子一
实验目的:
    1.学习MPU的配置
实验内容:
    1.初始化串口,LED和MPU
    2.主程序实现LED的闪烁
实验现象:
    请用USB转串口线连接PC机和开发板。PC机上运行SecureCRT软件,波特率设置为115200bps,无硬件流控。从PC机的软件界面观察程序执行结果(如果访问MPU范围之外的空间将出现下面现象):
6.2.png
7 X6 I' t8 n- P! h' P$ J2 K' s
    进入了硬件异常。
程序设计:
本程序主要分为两个部分:
  Ø  MPU的配置
  Ø  主程序
1.    MPU的配置
    MPU的配置相对比较容易,前提是一定要看权威指南上面对这个的介绍。
  1. /*) q# ?1 d/ a) ^6 F$ m
  2. *******************************************************************************************
    ; S; m0 ]# n" ^  `6 E- [' ~
  3. *    函 数 名: mpu_setup
    ; m2 o; M  }4 u
  4. *    功能说明: mpu配置' n& @5 E. ~+ }- F% s$ g, v
  5. *    形    参:无! J3 ^: |) O& E3 O+ A, F
  6. *    返 回 值: 无( P9 r- L- {( k/ Z& f% u9 L0 N. g/ L, S  d
  7. *******************************************************************************************
    1 Z8 |# P* O% K5 t6 r/ C
  8. */
    * b0 Z; X% A0 d* }- P
  9. static int mpu_setup(void)
      ]( p! y' R) I( _4 R3 M1 Y
  10. {
    & K, f# J0 f  i' V9 C2 E, ]
  11.      uint32_t i;
    . U8 `& i8 N+ d; P% a7 N, P6 b
  12.    
    : k! v5 z( R% T! a* c# y
  13.      uint32_t const mpu_cfg_rbar[4] =1 T. d3 S. C; C. i% f
  14.      {* h7 [- [$ c7 L& k8 A7 S6 r2 u' S! j
  15.          0x08000000,  // Flash0 A9 [( o& Q. v  g4 L0 i, W
  16.          0x20000000,  // SRAM
    ) H* g8 g% @3 N  h# e% p
  17.          GPIOF_BASE,  // GPIO F base address1 }4 n' h- |2 V" L) M' W: x
  18.          RCC_BASE     // Reset Clock CTRL base address
    , b( C/ x) \7 y' ^: U# ]
  19.      };
    ' C  n7 _  n& i+ w. x% M( a& E
  20.     ( y! d, n) F. C
  21.      uint32_t const mpu_cfg_rasr[4] =
    3 D* J1 H" w5 u! @0 h
  22.      {& h2 N0 f& y2 E6 U3 F5 m% L
  23.          (MPU_DEFS_RASR_SIZE_1MB       | MPU_DEFS_NORMAL_MEMORY_WT |3 z% \& a+ i, X8 G& o
  24.          MPU_DEFS_RASE_AP_FULL_ACCESS | MPU_RASR_ENABLE_Msk), // Flash. r% K, x  Q4 A$ J+ v% E' `
  25.          (MPU_DEFS_RASR_SIZE_128KB     | MPU_DEFS_NORMAL_MEMORY_WT |
    ! ]5 r6 V/ m7 q- ?( y% C! u. d
  26.          MPU_DEFS_RASE_AP_FULL_ACCESS | MPU_RASR_ENABLE_Msk), // SRAM# p: x2 B% t' a, f; X0 v
  27.          (MPU_DEFS_RASR_SIZE_1KB       | MPU_DEFS_SHARED_DEVICE    |# m" o  n( @" k+ B$ i
  28.          MPU_DEFS_RASE_AP_FULL_ACCESS | MPU_RASR_ENABLE_Msk), // GPIO D* p2 m5 m' \  G" H: Z0 x
  29.          (MPU_DEFS_RASR_SIZE_1KB       | MPU_DEFS_SHARED_DEVICE    |& ~6 I: h& _- R' j5 C
  30.          MPU_DEFS_RASE_AP_FULL_ACCESS | MPU_RASR_ENABLE_Msk)  // RCC* a* J7 q/ h6 b, l3 X
  31.      };8 h& @! x0 J) {; o
  32.    
      H- d3 W" X# A& K
  33.      /* 通过读取此寄存器的DREGION位值,够判断芯片中是否配了MPU */  [: }, j; h% i  u8 I1 |
  34.      if (MPU->TYPE==0)
    0 Z; E  o$ b  x& \
  35.     {( U( u/ U/ ~9 I- S# f& s, C
  36.          return 1;" w0 z6 P4 J: ?* C+ D
  37.      }   
    6 h) e$ \+ k; R: Z; }
  38.      __DMB();                 // Make sure outstanding transfers are done
    & y, A/ n" v( @% e* O1 ~
  39.    
    8 l6 q+ a- L3 M
  40.      /* 禁止MPU */
    4 @7 s9 l, Z0 e" ^, n9 l' u
  41.      MPU->CTRL = 0;
    2 _+ C. P/ Q1 O  C: n  d

  42. 9 U. l( ?" p- g7 _  L
  43.     /* 配置MPU的4个region */ * K* U, q: J2 g% F
  44.      for (i=0;i<4;i++)# k4 P/ J9 l# M" r+ _
  45.      {          3 W" N1 Z+ f. O# O  n
  46.          MPU->RNR  = i;                 // 选择配置那个region4 X0 |& g! K$ h6 H$ N5 g) D4 F* G
  47.          MPU->RBAR = mpu_cfg_rbar[i];   // 配置地址9 `! T; L6 L, p9 V4 ?: {! e
  48.          MPU->RASR = mpu_cfg_rasr[i];   // 配置属性和大小& t9 Z9 Z% Z% }* Z( {  L8 X9 Q+ ]
  49.      }
    : X+ p$ [# C- c" U
  50.    
    , }% ?0 {+ U/ A
  51.      /* 下面的配置,相当于禁止*/
    % U) M& V8 S( f! ?# D
  52.      for (i=4;i<8;i++)
    5 s) {5 g% J9 n5 |# l: [8 a  N' @
  53.      {
    . m& ?2 r4 \  T9 F
  54.          MPU->RNR  = i; & ^* [7 f, r. {, R. k
  55.          MPU->RBAR = 0;  ! X/ t5 C3 A5 Y! q( y4 K/ w& A9 J8 k
  56.          MPU->RASR = 0; . h. r( y' L# T# b3 {
  57.      }   
    ; X" P  B4 g: ^$ }/ V. j
  58. . z9 {' V% q! H1 R
  59.     /* 使能MPU */7 f6 l: _* t) e, X" b( w" b
  60.      MPU->CTRL = MPU_CTRL_ENABLE_Msk;2 {) I. _& M5 l# ]
  61.      __DSB();  // Ensure MPU settings take effects  S# e6 T: B1 S. ]$ P7 m0 J9 L
  62.      __ISB();  // Sequence instruction fetches using update settings5 H% M$ g+ \" M8 ^+ R0 ~9 j
  63. }
复制代码
2.    主程序
    主程序的功能也比较的简单,就是实现LED的闪烁。
  1. #define MPU_DEFS_RASR_SIZE_32B   (0x04 << MPU_RASR_SIZE_Pos)
    , s0 ^# P) H% K
  2. #define MPU_DEFS_RASR_SIZE_64B   (0x05 << MPU_RASR_SIZE_Pos)
    & v: a& H& u' `, ]( E! z
  3. #define MPU_DEFS_RASR_SIZE_128B  (0x06 << MPU_RASR_SIZE_Pos)
    ) X: A9 U7 e- M' Z
  4. #define MPU_DEFS_RASR_SIZE_256B  (0x07 << MPU_RASR_SIZE_Pos)# t* d) F: G5 z! n' f+ x
  5. #define MPU_DEFS_RASR_SIZE_512B  (0x08 << MPU_RASR_SIZE_Pos)% m) N! N8 G; a. g* N
  6. #define MPU_DEFS_RASR_SIZE_1KB   (0x09 << MPU_RASR_SIZE_Pos)$ G2 F4 j4 B, e  D0 t7 ]8 t
  7. #define MPU_DEFS_RASR_SIZE_2KB   (0x0A << MPU_RASR_SIZE_Pos)3 F4 q/ r$ ~- m+ o
  8. #define MPU_DEFS_RASR_SIZE_4KB   (0x0B << MPU_RASR_SIZE_Pos)4 b9 b+ k3 m" j' F6 `( J, R3 g& w
  9. #define MPU_DEFS_RASR_SIZE_8KB   (0x0C << MPU_RASR_SIZE_Pos)
    . }3 I9 l. ~+ }+ `
  10. #define MPU_DEFS_RASR_SIZE_16KB  (0x0D << MPU_RASR_SIZE_Pos)$ ^; ^# Z% E0 W8 c
  11. #define MPU_DEFS_RASR_SIZE_32KB  (0x0E << MPU_RASR_SIZE_Pos); |  z  e( |, v  w" L3 d
  12. #define MPU_DEFS_RASR_SIZE_64KB  (0x0F << MPU_RASR_SIZE_Pos)
    ' ~  n# I$ b( r+ ]9 `0 O
  13. #define MPU_DEFS_RASR_SIZE_128KB (0x10 << MPU_RASR_SIZE_Pos)
    / s# H% S  T  X- b$ V( ]
  14. #define MPU_DEFS_RASR_SIZE_256KB (0x11 << MPU_RASR_SIZE_Pos)  v; k. z$ A0 Q5 Y; A2 D
  15. #define MPU_DEFS_RASR_SIZE_512KB (0x12 << MPU_RASR_SIZE_Pos)% x0 }3 J, x( Y) ~
  16. #define MPU_DEFS_RASR_SIZE_1MB   (0x13 << MPU_RASR_SIZE_Pos)5 I1 X2 R$ H: o3 _' I
  17. #define MPU_DEFS_RASR_SIZE_2MB   (0x14 << MPU_RASR_SIZE_Pos)$ M; x9 `7 h6 H; B- h! |) b
  18. #define MPU_DEFS_RASR_SIZE_4MB   (0x15 << MPU_RASR_SIZE_Pos)2 a! o8 ^% k3 k1 {  \
  19. #define MPU_DEFS_RASR_SIZE_8MB   (0x16 << MPU_RASR_SIZE_Pos)
    % D% W2 W: W* S
  20. #define MPU_DEFS_RASR_SIZE_16MB  (0x17 << MPU_RASR_SIZE_Pos)
    . j7 G# d2 i+ @' E$ T
  21. #define MPU_DEFS_RASR_SIZE_32MB  (0x18 << MPU_RASR_SIZE_Pos)
    * O+ d' k8 ~/ J$ R) {5 J
  22. #define MPU_DEFS_RASR_SIZE_64MB  (0x19 << MPU_RASR_SIZE_Pos)
    / ?" `6 I0 }" R; s% a4 L: |" q5 [1 U
  23. #define MPU_DEFS_RASR_SIZE_128MB (0x1A << MPU_RASR_SIZE_Pos)3 O& [$ ^" C0 X, t
  24. #define MPU_DEFS_RASR_SIZE_256MB (0x1B << MPU_RASR_SIZE_Pos)
    * F) }0 D) x' O3 [" e
  25. #define MPU_DEFS_RASR_SIZE_512MB (0x1C << MPU_RASR_SIZE_Pos). k5 o' d! E$ z8 d
  26. #define MPU_DEFS_RASR_SIZE_1GB   (0x1D << MPU_RASR_SIZE_Pos)  m3 i( M( l/ n' @2 f
  27. #define MPU_DEFS_RASR_SIZE_2GB   (0x1E << MPU_RASR_SIZE_Pos)$ V  e& ]. X7 V2 d
  28. #define MPU_DEFS_RASR_SIZE_4GB   (0x1F << MPU_RASR_SIZE_Pos)
    " l  @; I/ v6 c& l8 G
  29. #define MPU_DEFS_RASE_AP_NO_ACCESS       (0x0 << MPU_RASR_AP_Pos)
    , Q1 S. @4 @* p. D! N
  30. #define MPU_DEFS_RASE_AP_PRIV_RW         (0x1 << MPU_RASR_AP_Pos)4 W& u' s) a& c8 o+ {" a0 e
  31. #define MPU_DEFS_RASE_AP_PRIV_RW_USER_RO (0x2 << MPU_RASR_AP_Pos)0 P7 d: s5 Z/ S# Y" A3 V
  32. #define MPU_DEFS_RASE_AP_FULL_ACCESS     (0x3 << MPU_RASR_AP_Pos)
    ' M+ h: \/ B; @6 p& _5 k
  33. #define MPU_DEFS_RASE_AP_PRIV_RO         (0x5 << MPU_RASR_AP_Pos)0 L+ H  H6 P6 E4 T) C& C0 D
  34. #define MPU_DEFS_RASE_AP_RO              (0x6 << MPU_RASR_AP_Pos)  o! x& r4 A) z" Y
  35. #define MPU_DEFS_NORMAL_MEMORY_WT        (MPU_RASR_C_Msk)8 V) H' c$ o2 E; o
  36. #define MPU_DEFS_NORMAL_MEMORY_WB        (MPU_RASR_C_Msk | MPU_RASR_B_Msk)
    $ m- [2 @; P( w/ x
  37. #define MPU_DEFS_NORMAL_SHARED_MEMORY_WT (MPU_RASR_C_Msk | MPU_RASR_S_Msk)# g, `9 l. o8 K
  38. #define MPU_DEFS_NORMAL_SHARED_MEMORY_WB (MPU_DEFS_NORMAL_MEMORY_WB | MPU_RASR_S_Msk)
    $ y3 Y  ^: U4 Q0 w% V; G% P0 T! O2 A
  39. #define MPU_DEFS_SHARED_DEVICE           (MPU_RASR_B_Msk | MPU_RASR_S_Msk)
    2 K4 O  j! g+ I1 V2 ?7 v/ p4 \
  40. #define MPU_DEFS_STRONGLY_ORDERED_DEVICE (0x0)
    2 n0 {$ h5 d' a% H" h

  41. # b2 V' R" u" ^; o* @3 r$ C
  42. #define LOOP_COUNT 0x3FFFFF  A# ~  O  j9 v, ^* w
  43.   I7 y- a" G4 R4 b3 ]" k
  44. /* 仅允许本文件内调用的函数声明 */& @" j7 ?6 t- p: s; P  L: {
  45. static void PrintfLogo(void);
    0 C3 A5 V7 \3 r- y* v
  46. static int mpu_setup(void);
    $ i: f9 J: p& C; W0 {& Z) _' K
  47. static void Delay(uint32_t nCount);! S5 ]6 w% N% d) ?# V1 O

  48. ' I0 H; j/ |% U+ {. I+ o4 z
  49. /*6 R$ B4 X' d/ x* C; j  z/ Z9 Q/ k
  50. *******************************************************************************************
    6 q1 l4 ~! b6 s+ ]
  51. *    函 数 名: main
    8 u1 S- W/ }* l; \8 d
  52. *    功能说明: c程序入口8 r4 D0 ^, c/ V- q% D; m* @, M
  53. *    形    参:无9 S* r) f* L. m$ K
  54. *    返 回 值: 错误代码(无需处理)
      A! B# O; _: D6 |+ s, w
  55. *******************************************************************************************
    * x6 Z1 w3 e: k$ \/ D
  56. */& t! R) v4 Z9 t! }9 i2 E; e
  57. int main(void)% C4 c. K  L6 A3 b* ]. h0 v
  58. {   : m( Z, Q4 N. q0 a' J
  59.      //(在Cortex-M3 r1p1中推荐使用, 在Cortex-M3 r2px 和 Cortex-M4中默认支持)/ y! p( S) Q! x5 v$ i: P: a
  60.      SCB->CCR |= SCB_CCR_STKALIGN_Msk;        // 使能堆栈的双字对齐模式
    " l8 o  {1 M) o! r; U
  61.     SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; // 使能 MemManage fault) ]4 l, W) y( s  U; _1 L
  62.    
    & P8 |/ w- }' L' i. R6 O
  63.      bsp_InitUart();
    , v, ]2 m3 u4 E7 L# Q) h# @
  64.      PrintfLogo();
    9 Y6 q1 x. ^& `  H
  65.      bsp_InitLed();         /* 初始LED指示灯端口 */
    4 Z) `3 b) m( Z) q5 \& t% d$ G* f
  66.      mpu_setup();
    1 o  W7 e# \2 P9 c4 k6 b7 {) q4 L
  67.    
    ; g/ V! a5 p( a, i0 D7 m. w
  68.      /* 进入主程序循环体 */
    8 O9 @( D8 Y2 j
  69.      while (1)5 N. E" L( p/ T3 N
  70.      {# Q% M. ?" J) o! _' R- ]. [! ~
  71.          bsp_LedToggle(1);
    . Q7 }  X, u6 @* J, ~( B
  72.          bsp_LedToggle(3);
    ; e) G, u' V, t, E7 x
  73.          Delay(LOOP_COUNT);
    ) U" w+ F7 C# P
  74.      }; D3 {# Q9 N) l, r% T( f) d9 g4 W% ?
  75. }
    " ?8 c! C. `1 V% y3 i
  76. 8 F; Q# a# W; g
  77. /*% U( O) m( |  H0 F9 J% s. t- F
  78. *******************************************************************************************, }/ d! R; A* L! m1 B, M# \9 h
  79. *    函 数 名: Delay
    ! }5 z+ u! t: L% }. R' u$ h: ]
  80. *    功能说明: nCount 延迟
    * H! C( I8 ~9 M% U
  81. *    形    参:无% M! I  v) S4 S0 O
  82. *    返 回 值: 无
    / v8 X- t6 ?( u
  83. *******************************************************************************************
    + J/ B8 B" \2 ^% e8 a
  84. */
    7 R8 V2 F! E! H2 E
  85. static void Delay(uint32_t nCount)
    % ?3 i6 F' u8 @/ L. A$ u
  86. {: e" R# ]+ r7 M5 _% o5 K6 P
  87.      while(nCount--)
    9 H# e: h2 @0 ^* X; }8 {
  88.      {
    1 c  R! F. f  s" }
  89.          __DSB();7 n3 F2 ^+ M# q* F# G6 s  K6 K
  90.      }  ^$ V/ ^9 r0 }, k
  91. }
复制代码

  J4 A- U: y6 Q/ |
赞 收藏 评论3 发布时间:2014-12-19 18:09

举报

3个回答
baiyongbin2009 回答时间:2014-12-19 18:14:45
6.2.2      实验二:MPU简易使用例子二
实验目的:
    1.学习MPU的配置
实验内容:
    1.初始化串口,LED和MPU
    2.主程序实现LED的闪烁
    3.这个例子和第一个例子基本相同,只是换了一种region的配置方法。
实验现象:
    请用USB转串口线连接PC机和开发板。PC机上运行SecureCRT软件,波特率设置为115200bps,无硬件流控。从PC机的软件界面观察程序执行结果(如果访问MPU范围之外的空间将出现下面现象):
6.3.png
                              
    进入了硬件异常。
程序设计:
本程序主要分为两个部分:
Ø  MPU的配置
Ø  主程序
1.    MPU的配置
    MPU的配置相对比较容易,前提是一定要看权威指南上面对这个的介绍。
  1. /*
    : z1 R* y& O. Y2 i5 P: V$ W
  2. *******************************************************************************************! t' V1 ]1 ?- I4 D7 C1 X) d/ q
  3. *    函 数 名: mpu_setup
    ' h. j7 V1 Q+ |
  4. *    功能说明: mpu配置
    ) J& E9 x, ]6 A+ o6 ^& O
  5. *    形    参:无
    5 H, u1 r! b( i$ l* d2 C
  6. *    返 回 值: 无
    9 `+ D: Y( R1 I7 z' T" ]5 [
  7. *******************************************************************************************
    & r) G& m, v4 W
  8. *// V0 F5 O( a; f1 Y4 ^" E/ H6 Y7 _, }
  9. static int mpu_setup(void)- l$ |, I% E6 t6 ^" H
  10. {
    0 T5 h$ g  M/ X3 h% j
  11.      uint32_t i;. _, t1 l+ M5 |
  12.    
      V8 u2 O7 k9 r) q6 ?/ j
  13.      uint32_t const mpu_cfg_rbar[4] =
      j! _# {5 ?/ W
  14.      {, z! p, O+ ?, d, l* o8 I" K; b
  15.            // Flash - region 0& C, C; c# w& s! W
  16.          (0x08000000 | MPU_RBAR_VALID_Msk | (MPU_RBAR_REGION_Msk & 0)),
    6 S, h. Z6 `# z' f) o# k6 X- I
  17.          // SRAM  - region 15 O/ A! I& i& R+ |
  18.          (0x20000000 | MPU_RBAR_VALID_Msk | (MPU_RBAR_REGION_Msk & 1)),5 f! `  ^5 \2 G! [
  19.          // GPIO D base address - region 25 B" x1 |/ n! M. {/ p$ @3 P
  20.          (GPIOF_BASE | MPU_RBAR_VALID_Msk | (MPU_RBAR_REGION_Msk & 2)),
    . O$ w7 S, \/ h
  21.          // Reset Clock CTRL base address - region 3
    7 F. B7 ~/ ^5 k7 t7 {1 _& e  ^
  22.          (RCC_BASE   | MPU_RBAR_VALID_Msk | (MPU_RBAR_REGION_Msk & 3))& i# u* g! L: K
  23.      };
    $ ]5 p; ?. _. w5 M
  24.    
    1 s* c( e% r* J7 g
  25.      uint32_t const mpu_cfg_rasr[4] =! U; h% u( l4 B$ b4 v
  26.      {
    8 |- \, N' c# T2 i% l
  27.          (MPU_DEFS_RASR_SIZE_1MB       | MPU_DEFS_NORMAL_MEMORY_WT |
    : t8 x7 N5 a# H# t, Y# o$ u7 R
  28.          MPU_DEFS_RASE_AP_FULL_ACCESS | MPU_RASR_ENABLE_Msk), // Flash
    % \( C* ?6 M7 d6 ]3 a
  29.          (MPU_DEFS_RASR_SIZE_128KB     | MPU_DEFS_NORMAL_MEMORY_WT |
    % Y; ~0 O# e9 G$ K
  30.          MPU_DEFS_RASE_AP_FULL_ACCESS | MPU_RASR_ENABLE_Msk), // SRAM
    / a8 s7 h" k: o1 n
  31.          (MPU_DEFS_RASR_SIZE_1KB       | MPU_DEFS_SHARED_DEVICE    |9 S0 R, v& v  @7 L: V
  32.          MPU_DEFS_RASE_AP_FULL_ACCESS | MPU_RASR_ENABLE_Msk), // GPIO D8 ~/ S4 j. s" h8 q- i
  33.          (MPU_DEFS_RASR_SIZE_1KB       | MPU_DEFS_SHARED_DEVICE    |
    1 s$ v' \9 \: ~% D4 I
  34.          MPU_DEFS_RASE_AP_FULL_ACCESS | MPU_RASR_ENABLE_Msk)  // RCC9 P% t5 \: x% K# L" `* p& Q% C
  35.      };
    # F* U0 k! q0 k. d* N
  36.    
    . g; I: v1 Z" }, x- ?: ~
  37.      /* 通过读取此寄存器的DREGION位值,够判断芯片中是否配了MPU */
    1 c0 j. M1 g' b
  38.      if (MPU->TYPE==0), M* f/ ~/ }! a4 x$ D! |
  39.     {
    " T7 N  Z; o3 ]+ W
  40.          return 1;
    " M, r& \1 L7 z# R: l/ I
  41.      }   
    # d% u: @* }4 ]' k  Q+ G
  42.      __DMB();                 // Make sure outstanding transfers are done" T! B$ G/ k/ t1 `$ b
  43.    
    # n( T. c5 \% q# F& W9 D1 o% M
  44.      /* 禁止MPU */+ \# h: k0 x7 J
  45.      MPU->CTRL = 0;   C2 U7 X5 j4 F% F# _; ~
  46. & m* T- M/ j! Z, A
  47.     /* 配置MPU的4个region */
    0 w; q  V: j9 V: y& H4 Q
  48.      for (i=0;i<4;i++)
    / U3 k+ v# K: k) d  v$ F# R
  49.      {         
    . z& O) o" U% ?: a5 b6 h; K1 t
  50.          MPU->RNR  = i;                 // 选择配置那个region
    5 t/ _/ Q# d3 H% E' \, v: V
  51.          MPU->RBAR = mpu_cfg_rbar[i];   // 配置地址* R8 p- _- P. \9 [" R
  52.          MPU->RASR = mpu_cfg_rasr[i];   // 配置属性和大小
    ; {% Q7 i0 P& Z& S7 @/ |* e
  53.      }  `! r; a0 }; u& \$ j; m
  54.     $ H, K( c9 R! `. [% ^
  55.      /* 下面的配置,相当于禁止其余的4个region */2 N+ G/ g; L! z+ g! K
  56.      for (i=4;i<8;i++)
    " T0 c: |0 q% |  |6 S
  57.      {
    . Z+ J/ t' O1 I( h7 m
  58.          MPU->RNR  = i;
    * X2 K- R* G5 c5 Y
  59.          MPU->RBAR = 0;  / J8 |! k" o9 e0 T/ ]
  60.          MPU->RASR = 0;
    ) l/ F9 E+ L/ `* u$ x$ l7 _+ m* R) S
  61.      }   
    - s2 D; A; @9 @- I7 G0 [
  62. 6 T5 M, n6 w" ?  U
  63.     /* 使能MPU */
    ; F3 R; p0 X. W( i' n
  64.      MPU->CTRL = MPU_CTRL_ENABLE_Msk;
    ' q% b, I5 l. K( q( ^$ d4 B
  65.      __DSB();  // Ensure MPU settings take effects$ m3 t3 `3 P1 `% }( g- L/ ]
  66.      __ISB();  // Sequence instruction fetches using update settings+ h" w1 b3 n+ h7 o. i& U
  67. }
复制代码
2.    主程序
    主程序的功能也比较的简单,就是实现LED的闪烁。
  1. #define MPU_DEFS_RASR_SIZE_32B   (0x04 << MPU_RASR_SIZE_Pos)
    $ o9 y0 Q. V* ]8 L* d" C
  2. #define MPU_DEFS_RASR_SIZE_64B   (0x05 << MPU_RASR_SIZE_Pos)" g. ^6 c" c) d, B  W$ o9 W# g* C
  3. #define MPU_DEFS_RASR_SIZE_128B  (0x06 << MPU_RASR_SIZE_Pos)
    " J* v3 V3 e7 o1 p3 Z9 D) ?
  4. #define MPU_DEFS_RASR_SIZE_256B  (0x07 << MPU_RASR_SIZE_Pos)' `9 U7 X/ b7 e* P- M. M5 G# x% z
  5. #define MPU_DEFS_RASR_SIZE_512B  (0x08 << MPU_RASR_SIZE_Pos)
    0 v, v! V9 h- \' \3 v, X2 E* K
  6. #define MPU_DEFS_RASR_SIZE_1KB   (0x09 << MPU_RASR_SIZE_Pos)4 g, l# e: h5 W' R2 Y
  7. #define MPU_DEFS_RASR_SIZE_2KB   (0x0A << MPU_RASR_SIZE_Pos)7 p5 ~' O) v. Q3 {
  8. #define MPU_DEFS_RASR_SIZE_4KB   (0x0B << MPU_RASR_SIZE_Pos)
    ! o' N2 J1 r& T& d  S
  9. #define MPU_DEFS_RASR_SIZE_8KB   (0x0C << MPU_RASR_SIZE_Pos)
    ; D  |& Z) o. ~) a
  10. #define MPU_DEFS_RASR_SIZE_16KB  (0x0D << MPU_RASR_SIZE_Pos)8 Q3 I1 M% _" K
  11. #define MPU_DEFS_RASR_SIZE_32KB  (0x0E << MPU_RASR_SIZE_Pos)+ }) M  i4 X' k+ i/ y5 k6 S
  12. #define MPU_DEFS_RASR_SIZE_64KB  (0x0F << MPU_RASR_SIZE_Pos)8 b$ [- S5 s! z& x% f" E
  13. #define MPU_DEFS_RASR_SIZE_128KB (0x10 << MPU_RASR_SIZE_Pos)& {3 L7 f! A: _5 y1 R  D5 ^$ f
  14. #define MPU_DEFS_RASR_SIZE_256KB (0x11 << MPU_RASR_SIZE_Pos)
    2 {$ U& U* A, s) h5 Z
  15. #define MPU_DEFS_RASR_SIZE_512KB (0x12 << MPU_RASR_SIZE_Pos)6 C( X6 @2 E+ E. `
  16. #define MPU_DEFS_RASR_SIZE_1MB   (0x13 << MPU_RASR_SIZE_Pos)) G( }9 s' g5 v
  17. #define MPU_DEFS_RASR_SIZE_2MB   (0x14 << MPU_RASR_SIZE_Pos)- F$ ^9 \/ b6 v
  18. #define MPU_DEFS_RASR_SIZE_4MB   (0x15 << MPU_RASR_SIZE_Pos). Z: {0 s) Z* `# f! |" x
  19. #define MPU_DEFS_RASR_SIZE_8MB   (0x16 << MPU_RASR_SIZE_Pos)
    % ~/ n5 f1 u: Q; N0 i0 E
  20. #define MPU_DEFS_RASR_SIZE_16MB  (0x17 << MPU_RASR_SIZE_Pos)
    1 m3 j# r: d6 m4 Z9 e. y
  21. #define MPU_DEFS_RASR_SIZE_32MB  (0x18 << MPU_RASR_SIZE_Pos)' t& }  I. |! L6 g3 H
  22. #define MPU_DEFS_RASR_SIZE_64MB  (0x19 << MPU_RASR_SIZE_Pos): y: Q" F' p: L& b  p1 b; D' w
  23. #define MPU_DEFS_RASR_SIZE_128MB (0x1A << MPU_RASR_SIZE_Pos)
    3 u, ^: D8 Z' J  A
  24. #define MPU_DEFS_RASR_SIZE_256MB (0x1B << MPU_RASR_SIZE_Pos)& o' S0 I) U( _, G
  25. #define MPU_DEFS_RASR_SIZE_512MB (0x1C << MPU_RASR_SIZE_Pos)
    8 \0 Y, X, ]- n
  26. #define MPU_DEFS_RASR_SIZE_1GB   (0x1D << MPU_RASR_SIZE_Pos)
    4 r/ v+ g: W' G. ], ?  L/ G  r# F6 l
  27. #define MPU_DEFS_RASR_SIZE_2GB   (0x1E << MPU_RASR_SIZE_Pos)% D1 Q! O$ k" t( N' K6 `
  28. #define MPU_DEFS_RASR_SIZE_4GB   (0x1F << MPU_RASR_SIZE_Pos)
      `' R/ ?, c. Q$ l& `
  29. #define MPU_DEFS_RASE_AP_NO_ACCESS       (0x0 << MPU_RASR_AP_Pos)
    ) h- I! _/ \$ ?0 s$ v+ h: r7 Y6 m
  30. #define MPU_DEFS_RASE_AP_PRIV_RW         (0x1 << MPU_RASR_AP_Pos)
    $ J$ r. l# F# p# `" G
  31. #define MPU_DEFS_RASE_AP_PRIV_RW_USER_RO (0x2 << MPU_RASR_AP_Pos)/ J$ x$ J6 ~0 q3 ]4 p' B
  32. #define MPU_DEFS_RASE_AP_FULL_ACCESS     (0x3 << MPU_RASR_AP_Pos); z' ?! B( M; |/ S
  33. #define MPU_DEFS_RASE_AP_PRIV_RO         (0x5 << MPU_RASR_AP_Pos)
    5 Q; ]% _0 j6 Q( |
  34. #define MPU_DEFS_RASE_AP_RO              (0x6 << MPU_RASR_AP_Pos)" {: I5 G7 E0 A5 R" [: h8 _6 a1 o  |
  35. #define MPU_DEFS_NORMAL_MEMORY_WT        (MPU_RASR_C_Msk)
    % y9 b; Z  p* L' q* l  h& i6 V/ O1 d
  36. #define MPU_DEFS_NORMAL_MEMORY_WB        (MPU_RASR_C_Msk | MPU_RASR_B_Msk)
    7 \" t+ G$ H  {, W/ C
  37. #define MPU_DEFS_NORMAL_SHARED_MEMORY_WT (MPU_RASR_C_Msk | MPU_RASR_S_Msk)1 l; \: P5 u* }0 _- I/ x
  38. #define MPU_DEFS_NORMAL_SHARED_MEMORY_WB (MPU_DEFS_NORMAL_MEMORY_WB | MPU_RASR_S_Msk)/ F$ m, O; }5 @
  39. #define MPU_DEFS_SHARED_DEVICE           (MPU_RASR_B_Msk | MPU_RASR_S_Msk)' p, e$ N  w3 C4 W, H
  40. #define MPU_DEFS_STRONGLY_ORDERED_DEVICE (0x0)* M8 y) O/ S* f6 F5 W

  41. 5 \4 ^# R! E, n2 p4 l8 E
  42. #define LOOP_COUNT 0x3FFFFF
    " n. y  q+ e* b3 Z

  43. % r5 }6 s: D2 t" F' r4 f$ U, w
  44. /* 仅允许本文件内调用的函数声明 */
    # d7 s9 ?' r/ V
  45. static void PrintfLogo(void);& e5 z1 v9 P: @5 T) ^
  46. static int mpu_setup(void);
    3 k% j* I2 k- f3 C
  47. static void Delay(uint32_t nCount);
    $ L) p) `/ }; y) s* {- l. f& ~

  48. 5 F. Q* T. U: @# ~0 S, e  |* T
  49. /*1 V: K' {$ Y3 P" B2 M. e
  50. *******************************************************************************************4 Z6 A$ T) e  y8 p
  51. *    函 数 名: main0 `/ `: h& q3 X0 Z, u" H5 t
  52. *    功能说明: c程序入口
    1 O. C% `; Q+ @. I$ c
  53. *    形    参:无
    ! U4 s4 _- {- s
  54. *    返 回 值: 错误代码(无需处理)) O. h7 M, X% Q& z8 n% @
  55. *******************************************************************************************% u4 z  K; A; B
  56. */
    & ]& u  T; s9 O1 t8 s* q
  57. int main(void)* J- |% C/ @  x2 o
  58. {   - w3 g, n: V1 G3 U
  59.      //(在Cortex-M3 r1p1中推荐使用, 在Cortex-M3 r2px 和 Cortex-M4中默认支持)
    7 n: \2 V/ _- u1 o
  60.      SCB->CCR |= SCB_CCR_STKALIGN_Msk;        // 使能堆栈的双字对齐模式; J1 M! N& y; z. o' W6 j& N
  61.     SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; // 使能 MemManage fault) L8 K* M, W% J' f! y0 k
  62.    
    + C# N+ V' W, Z; {7 G
  63.      bsp_InitUart();# b- a& V" R1 M# E
  64.      PrintfLogo();3 p+ d) q& G$ A& [7 h' J5 N" h
  65.      bsp_InitLed();         /* 初始LED指示灯端口 */. b1 O) n* ?. f
  66.      mpu_setup();
    1 g$ C1 @" e7 q9 ~
  67.    
    % }6 R2 L- b- o6 Y8 g( V  g- L
  68.      /* 进入主程序循环体 */
    - j8 r/ M4 S# B' Q
  69.      while (1)
    # J8 Z5 x; V3 \4 Y- ]& Q
  70.      {
    : N* `6 C3 O( Z' w8 ]( W6 [
  71.          bsp_LedToggle(1);
    . w1 c% ]0 a+ Q. x2 K* T, w+ b
  72.          bsp_LedToggle(3);
    & b! ]9 N( i1 q, t$ r6 l
  73.          Delay(LOOP_COUNT);9 O. s) a4 F$ V2 V  Q  q
  74.      }
    $ {) ~2 w: s! M, U, C1 q# O
  75. }0 K! E- ^- a2 X! ^  Q; M- \

  76. : y% u9 M* ]7 C. ~9 e6 S& Y
  77. /*. o1 n/ T  z; k; t
  78. *******************************************************************************************
    , S, Q9 X8 q+ H$ v, o
  79. *    函 数 名: Delay8 U( t5 b3 e( }1 T+ T
  80. *    功能说明: nCount 延迟
    % \% W7 d% A% f2 ]1 ~1 y
  81. *    形    参:无* v: W5 @' |2 N& T
  82. *    返 回 值: 无' K- s6 J. D6 S. D5 m
  83. *******************************************************************************************
    6 `# b2 k4 Q) B1 p3 Y) _
  84. */
    ' C2 C: a$ U: i# T$ n
  85. static void Delay(uint32_t nCount)% O' o  \: O6 v/ Y8 L
  86. {( M1 ]5 c8 P/ R# t8 Z& h/ @. f# U% ~
  87.      while(nCount--)
    ( R! X) o" e% _& o% S
  88.      {; j+ S5 l4 d, N
  89.          __DSB();
    ; |8 Z- P) O* A7 i
  90.      }
    ; d7 S- k' T; _7 ~4 E
  91. }
复制代码
  n& r3 H% [# E
baiyongbin2009 回答时间:2014-12-19 18:16:43
6.2.3      实验三:MPU的API函数
实验目的:
    1.学习MPU的配置
实验内容:
    1.初始化串口,LED和MPU
    2.主程序实现LED的闪烁
    3.这个实验相对于前面两个只是重新封装了下,方便调用
实验现象:
    请用USB转串口线连接PC机和开发板。PC机上运行SecureCRT软件,波特率设置为115200bps,无硬件流控。从PC机的软件界面观察程序执行结果(如果访问MPU范围之外的空间将出现下面现象):
6.4.png
                              
    进入了硬件异常。
程序设计:
本程序主要分为两个部分:
Ø  MPU的配置
Ø  主程序
1.    MPU的配置
    这里将相关的函数进行了专门的配置,方便用户进行调用。
  1. #define MPU_DEFS_RASR_SIZE_32B   (0x04 << MPU_RASR_SIZE_Pos)3 `) ?+ S, L( j
  2. #define MPU_DEFS_RASR_SIZE_64B   (0x05 << MPU_RASR_SIZE_Pos)
    $ |) `9 W0 I; a5 ]2 U# ^
  3. #define MPU_DEFS_RASR_SIZE_128B  (0x06 << MPU_RASR_SIZE_Pos)
    $ {3 o; I  p: r
  4. #define MPU_DEFS_RASR_SIZE_256B  (0x07 << MPU_RASR_SIZE_Pos)( p, z. B( R" r! o5 g8 o
  5. #define MPU_DEFS_RASR_SIZE_512B  (0x08 << MPU_RASR_SIZE_Pos)+ t6 z4 X8 u% T" [3 {
  6. #define MPU_DEFS_RASR_SIZE_1KB   (0x09 << MPU_RASR_SIZE_Pos)4 u$ h3 Q; x0 N+ y/ n7 Y
  7. #define MPU_DEFS_RASR_SIZE_2KB   (0x0A << MPU_RASR_SIZE_Pos)
    + j! l" t' E' Z  a" v' K
  8. #define MPU_DEFS_RASR_SIZE_4KB   (0x0B << MPU_RASR_SIZE_Pos)" X4 V* k! ?* u0 d, S+ d
  9. #define MPU_DEFS_RASR_SIZE_8KB   (0x0C << MPU_RASR_SIZE_Pos)
    ( c5 J. N8 Z* y' q# _0 w
  10. #define MPU_DEFS_RASR_SIZE_16KB  (0x0D << MPU_RASR_SIZE_Pos)
    1 D+ ?' E% k) l: l: ?: |/ |4 a
  11. #define MPU_DEFS_RASR_SIZE_32KB  (0x0E << MPU_RASR_SIZE_Pos)
    ; r' ?5 f& s* L2 B, v! E8 }& i
  12. #define MPU_DEFS_RASR_SIZE_64KB  (0x0F << MPU_RASR_SIZE_Pos)# y  V( v- R& W" n6 g0 h9 T- W) b
  13. #define MPU_DEFS_RASR_SIZE_128KB (0x10 << MPU_RASR_SIZE_Pos)
    6 }  x" a( {+ l: O
  14. #define MPU_DEFS_RASR_SIZE_256KB (0x11 << MPU_RASR_SIZE_Pos)- a( I% T# `7 A+ `/ g
  15. #define MPU_DEFS_RASR_SIZE_512KB (0x12 << MPU_RASR_SIZE_Pos)1 Y% j: d$ U% r! k
  16. #define MPU_DEFS_RASR_SIZE_1MB   (0x13 << MPU_RASR_SIZE_Pos)
    ( |7 R9 ]0 z& v) m% p
  17. #define MPU_DEFS_RASR_SIZE_2MB   (0x14 << MPU_RASR_SIZE_Pos)
    2 b# ?- \; o5 B; \" f/ D( O! Y! ?6 {
  18. #define MPU_DEFS_RASR_SIZE_4MB   (0x15 << MPU_RASR_SIZE_Pos)6 s# ^3 U& {: D- d' I6 {) r
  19. #define MPU_DEFS_RASR_SIZE_8MB   (0x16 << MPU_RASR_SIZE_Pos)- ^, |3 j! q& e" t, {1 z/ l  o% \
  20. #define MPU_DEFS_RASR_SIZE_16MB  (0x17 << MPU_RASR_SIZE_Pos)5 k( p; G" V5 S" y, E0 X/ k
  21. #define MPU_DEFS_RASR_SIZE_32MB  (0x18 << MPU_RASR_SIZE_Pos)
    # K6 M0 e1 ^/ x
  22. #define MPU_DEFS_RASR_SIZE_64MB  (0x19 << MPU_RASR_SIZE_Pos)
    & p  [7 @" }5 O1 }( S) T
  23. #define MPU_DEFS_RASR_SIZE_128MB (0x1A << MPU_RASR_SIZE_Pos)/ y5 X$ T, j$ n9 k
  24. #define MPU_DEFS_RASR_SIZE_256MB (0x1B << MPU_RASR_SIZE_Pos)
    ! }* t9 a5 ^" Z1 j2 B6 B5 I: b
  25. #define MPU_DEFS_RASR_SIZE_512MB (0x1C << MPU_RASR_SIZE_Pos). G7 n4 J* A7 g$ M" M% S& K
  26. #define MPU_DEFS_RASR_SIZE_1GB   (0x1D << MPU_RASR_SIZE_Pos)+ r: n+ y: B2 C5 B, t+ \2 |% E
  27. #define MPU_DEFS_RASR_SIZE_2GB   (0x1E << MPU_RASR_SIZE_Pos)
    - {. f0 A+ T+ J, R& N: M3 A
  28. #define MPU_DEFS_RASR_SIZE_4GB   (0x1F << MPU_RASR_SIZE_Pos)2 X  v1 N& \# o- h1 q5 \2 I
  29. #define MPU_DEFS_RASE_AP_NO_ACCESS       (0x0 << MPU_RASR_AP_Pos)- y7 F4 @. V  j) e
  30. #define MPU_DEFS_RASE_AP_PRIV_RW         (0x1 << MPU_RASR_AP_Pos)
    : F: X  }! y: j- p# t! \1 ]
  31. #define MPU_DEFS_RASE_AP_PRIV_RW_USER_RO (0x2 << MPU_RASR_AP_Pos)
    7 W4 ^  g* ?% [) d) r/ v
  32. #define MPU_DEFS_RASE_AP_FULL_ACCESS     (0x3 << MPU_RASR_AP_Pos)
    # j, K: ~0 W5 F7 I) A
  33. #define MPU_DEFS_RASE_AP_PRIV_RO         (0x5 << MPU_RASR_AP_Pos)( k  u3 b& i! z$ q
  34. #define MPU_DEFS_RASE_AP_RO              (0x6 << MPU_RASR_AP_Pos)4 }$ F+ D) O, o5 A/ N
  35. #define MPU_DEFS_NORMAL_MEMORY_WT        (MPU_RASR_C_Msk)4 N/ p6 I  m5 ]. A/ s# \2 U% ~4 N
  36. #define MPU_DEFS_NORMAL_MEMORY_WB        (MPU_RASR_C_Msk | MPU_RASR_B_Msk)1 k* o6 Q4 ^& |" M4 r1 n
  37. #define MPU_DEFS_NORMAL_SHARED_MEMORY_WT (MPU_RASR_C_Msk | MPU_RASR_S_Msk)) M, H2 C( T) h8 A& L% |5 P+ T% l
  38. #define MPU_DEFS_NORMAL_SHARED_MEMORY_WB (MPU_DEFS_NORMAL_MEMORY_WB | MPU_RASR_S_Msk)
    # n! {5 N7 r& Y+ N6 T6 L( L
  39. #define MPU_DEFS_SHARED_DEVICE           (MPU_RASR_B_Msk | MPU_RASR_S_Msk)
    / P6 S1 l6 f6 M, H3 \6 ?
  40. #define MPU_DEFS_STRONGLY_ORDERED_DEVICE (0x0)
    / g. G) r8 ?  i' D7 |
  41. . Y( h4 }* h% s: a  f
  42. /*************************************************/
    9 i; m- U# t' M% k& a2 D
  43. void mpu_region_config(uint32_t region_num, uint32_t addr, uint32_t size, uint32_t attributes);+ \  Y2 j' H: H. b/ k) U5 H" Q
  44. void mpu_enable(uint32_t options);% R7 F# z" H( l7 V
  45. void mpu_disable(void);
    % }+ J% @8 g% {& x- ]7 h: q9 f" p
  46. void mpu_region_disable(uint32_t region_num);
    4 }: o/ K& M" v  ?+ i
  47. ; c3 Z! s* N! a) Y# Z
  48. /*. i3 W0 T) W& z* c
  49. *******************************************************************************************! g0 M( I8 e3 `
  50. *    函 数 名: bsp_InitMPU2 H) N& ?! g" _! `  i- ^; ?) C
  51. *    功能说明: 内存保护单元初始化
    ' t# W+ X6 I7 J, X% h" m5 J8 ?$ M
  52. *    形    参: 无
    / t4 U0 Y3 l8 c/ O) f! E' u
  53. *    返 回 值: 0 表示失败,1 表示成功
    + Y* e6 E+ t8 N1 l
  54. *******************************************************************************************
    6 z# E7 h: K0 ~% x/ U
  55. */7 E: U& f9 S- u9 a
  56. uint8_t bsp_InitMPU(void)% N9 a- K! C9 X% D
  57. {
    + s% j6 ~! _, L
  58.      if (MPU->TYPE==0), p2 m) V( V6 u
  59.      {
    1 I9 q9 x0 N( }; I( l
  60.          return 0;
    1 O+ y  r2 h" y
  61.      }+ N0 b% @# A0 ~; U/ M
  62.     /* 第一步要先禁止MPU再进行相应的设置 */  7 @$ G1 T$ L5 z+ p$ d; G
  63.      mpu_disable();
    , Q) U3 E; g5 a- e0 q( G5 U
  64.    
    4 h5 f4 X) p. j8 r% _6 q0 c
  65.      /* 设置MPU的8个Region */
    & M7 a' \/ K5 b! j
  66.      /* 配置Region 0 - Flash */8 v! G  B/ ]3 p, R' n7 _
  67.      mpu_region_config(0, 0x08000000, MPU_DEFS_RASR_SIZE_1MB,
    : c& S& i: _# Q# T2 S
  68.      MPU_DEFS_NORMAL_MEMORY_WT | MPU_DEFS_RASE_AP_FULL_ACCESS |8 @/ @" u# u3 W  L: G( `$ O' z! c3 h
  69.      MPU_RASR_ENABLE_Msk),; S* m* P: l% u. J3 t  J
  70.      /* 配置Region 1 - SRAM *// U0 k$ A2 O0 Q+ ~, `2 D* y4 F
  71.      mpu_region_config(1, 0x20000000, MPU_DEFS_RASR_SIZE_128KB,
    - a  ]# _% E+ _0 x9 A6 M7 p
  72.      MPU_DEFS_NORMAL_MEMORY_WT | MPU_DEFS_RASE_AP_FULL_ACCESS |/ R. h+ U7 O! |, P
  73.      MPU_RASR_ENABLE_Msk),
    . `# s/ D' S' g7 m  |; s3 F
  74.      /* 配置Region 2 - GPIO D */1 `0 L: \2 u" `' {! s+ u
  75.      mpu_region_config(2, GPIOF_BASE, MPU_DEFS_RASR_SIZE_1KB,
    , B; E. T* m- f3 `5 v
  76.      MPU_DEFS_SHARED_DEVICE    | MPU_DEFS_RASE_AP_FULL_ACCESS |
    , ^& Y; a0 X; |$ s( J+ i
  77.      MPU_RASR_ENABLE_Msk),, f( ]$ F: @; r  z, ^
  78.      /* 配置Region 3 - Reset Clock CTRL */) H* L3 ^' R: Q: H6 G% v
  79.      mpu_region_config(3, RCC_BASE, MPU_DEFS_RASR_SIZE_1KB,
    9 X0 M7 {# x1 ?7 n
  80.      MPU_DEFS_SHARED_DEVICE    | MPU_DEFS_RASE_AP_FULL_ACCESS |
    ! j6 y+ a* ^# S  g* L
  81.      MPU_RASR_ENABLE_Msk),
    8 h. q# W. J8 M0 _! w
  82.      /* 禁止Region 4 */
    ' `5 {- z, X3 I% z0 U
  83.      mpu_region_disable(4);. h- B6 `6 \% |8 j; d  Q1 g6 E
  84.      /* 禁止Region 5 */- n. L5 d9 W1 O+ w' F6 X
  85.      mpu_region_disable(5);
    $ `5 T/ s3 @3 ^6 b
  86.      /* 禁止Region 6 */
    ! J8 j; h- }* n, g* W
  87.      mpu_region_disable(6);" Z. u9 F1 F7 r1 k
  88.      /* 禁止Region 7 */5 _2 F4 o: o0 u+ r+ c( |2 C. j
  89.      mpu_region_disable(7);* F% o) ?) t: i5 l" W
  90.    
    6 k* }0 ~- |  N" W) z) A! w
  91.      /* 使能允许MPU */# V0 s4 J% T1 z  T) M+ r( l6 |
  92.      mpu_enable(0);8 V5 S2 T) V+ r2 b- a; t
  93.    
    8 }( a% R' g6 P1 |7 y7 e& f  E# L
  94.      return 1;5 Y7 K+ R8 k4 ], ?! Y
  95. }
    " b* h% ]& O& a8 ]5 ?

  96. 8 i- W3 R9 l1 e3 O7 M+ B: V2 u
  97. /*
    , G( S( Q8 ~' \9 D, N! p
  98. *******************************************************************************************! S3 g. x$ {+ ~, p: W5 d0 t
  99. *    函 数 名: mpu_enable
    6 ]& S  l+ B" j
  100. *    功能说明: mpu使能,mpu控制寄存器有3位,功能分别如下:
    # i( k9 y2 \# }9 U! p
  101. *             位2  PRIVDEFENA 是否为特权级打开缺省存储器映射(即背景
    3 ^  s1 A* |. S6 I6 q
  102. *                             region)。
    0 Y+ R# G5 r" j6 z
  103. *                             1 = 特权级下打开背景region( ^9 d$ |0 g0 o5 J: l2 [
  104. *                             0 = 不打开背景region。任何访问违例以及对
    " z1 D1 ?5 u9 P4 \1 \/ E, r" I
  105. *                                 region外地址区的访问都将引起fault。
    / w: k/ K" T0 {- B
  106. *             位1  HFNMIENA   1=在NMI和硬fault服务例程中不强制除能MPU
    ) w+ r; O! E& O1 W. Z5 z# c6 p
  107. *                             0=在NMI和硬fault服务例程中强制除能MPU
    0 c1 n7 o1 ~5 }5 K0 C" f
  108. *             位0  ENABLE     使能或者禁止
    2 |/ i! [# V5 c$ W7 O) h
  109. *    形    参: options  MPU_CTRL_HFNMIENA_Msk或者MPU_CTRL_PRIVDEFENA_Msk
    8 S! O5 Z/ P9 U' }
  110. *    返 回 值: 无5 N' ]6 }" E; F% K7 q: S
  111. *******************************************************************************************
    9 Y6 d+ `6 i' f
  112. */
    5 r+ U( y! t; u
  113. void mpu_enable(uint32_t options)
      |; ^% v  e0 ]) ^' E& L
  114. {
    ; x. S7 p, N2 W; y5 _" C- Y
  115.      MPU->CTRL = MPU_CTRL_ENABLE_Msk | options; + E3 B8 D# [% a7 `6 s
  116.      __DSB();  // Ensure MPU settings take effects
    ) i  H5 V1 F) k# w, W: J( ~
  117.      __ISB();  // Sequence instruction fetches using update settings9 A8 d. J% `% ]( m
  118. }
    , z  ~& h6 |( X

  119. " p5 h( t8 q( G: Q" k1 S5 P6 g  R$ v
  120. /*
    ; U0 R0 b3 _0 D: x2 O' B
  121. *******************************************************************************************7 H6 C3 }+ d/ |) `. m7 E
  122. *    函 数 名: mpu_disable3 J' I/ S4 u8 R2 N. C5 v& x
  123. *    功能说明: 禁止mpu
    7 a+ H" X6 }2 Z+ ~& a; J) z
  124. *    形    参: 无
    ) M9 G2 X$ z$ h$ T* o
  125. *    返 回 值: 无
    % l. j, |# q" y( y( O# c
  126. *******************************************************************************************. [: @; L8 U; h9 |: @; Y2 g8 H% a
  127. */% ~0 p( @1 u& z8 N* g
  128. void mpu_disable(void)
    5 l5 r$ y  ?* e1 H- u* v- \1 \
  129. {
    ) h; X: y& }& v* U, B; C" i  c
  130.      __DMB();            // Make sure outstanding transfers are done7 E  {$ d, u7 ]- P
  131.      MPU->CTRL = 0;      // Disable the MPU3 p3 x6 M  |  ~* e" t# _6 ]
  132. }
    7 d6 W  n) |1 W9 r2 Z- l5 l

  133. + G; q& |+ A; j; Y: ?( H% [
  134. /*
    / \) T9 J( e2 h1 B
  135. *******************************************************************************************
    3 o+ o. t5 K; S8 O
  136. *    函 数 名: mpu_region_disable
    3 N; p) o, M; g# N. q
  137. *    功能说明: 禁止mpu谋一个region9 T$ t; f# e1 s1 @# I5 h& b* m
  138. *    形    参: region_num  范围0 - 7
    . b+ X" s' L/ P9 n, L. a3 t
  139. *    返 回 值: 无$ D" \+ l- q! Q3 _1 B
  140. *******************************************************************************************
    . f) t* r  |" _) K& m8 b
  141. */
    : F( k  M5 p+ g8 @5 F
  142. void mpu_region_disable(uint32_t region_num)
    3 M' u7 O  d$ f1 r7 h9 z8 P! z* l
  143. {, E; W  R9 Q4 q3 G5 ?; d7 L& i3 v
  144.      MPU->RNR  = region_num;. n' v$ O! |  b, X9 L- l, l9 D  E
  145.      MPU->RBAR = 0;
    0 U. ^6 B1 ?! N
  146.      MPU->RASR = 0;  x6 y% d2 z' j# n7 l
  147. }   
    * I/ x' }+ n8 J

  148. $ Q1 k3 y2 C# D, S/ O& f/ Q
  149. /*: V2 v5 a' _1 p. d+ ^/ j. l
  150. *******************************************************************************************
    1 E0 c* g$ X5 }
  151. *    函 数 名: mpu_region_config
    - ~, r; p7 H/ j9 A9 e: K
  152. *    功能说明: mpu配置( Q5 [' ?: d# }
  153. *    形    参: region_num  范围0 - 7+ b  ]4 p! W2 E1 W6 G, r
  154. *             addr  地址# ?( r# D( z! [) v
  155. *             size  大小
    * V9 e9 ?5 ?. F7 O9 \6 x4 y
  156. *             attributes 属性
    7 x6 ^5 l: J9 N! j
  157. *    返 回 值: 无  l* @7 R# y' a
  158. *******************************************************************************************
    3 s& O! ]. H, ]& n1 j% `. \4 K& c
  159. */
    - w+ `% L- f: m7 n3 @3 A+ ^8 t
  160. void mpu_region_config(uint32_t region_num, uint32_t addr, uint32_t size, uint32_t attributes)( F- D: L) ^! x  C
  161. {1 e( E: _& F1 r/ h; R
  162.      MPU->RNR  = region_num;% ^% w) d: \5 h' C$ ]! {& E. Y, S
  163.      MPU->RBAR = addr;" a$ w; {5 Q% X4 S2 F+ M
  164.      MPU->RASR = size | attributes;& }! r. v. F, f; ]
  165. }
复制代码
2.    主程序
  1. /* 仅允许本文件内调用的函数声明 */
    : U& W2 M  K& W$ Q
  2. static void PrintfLogo(void);
    4 a7 G4 g& a0 F2 Y* d9 m1 _7 W4 [" r
  3. static void Delay(uint32_t nCount);
    2 K1 m! b! C  z5 a. I
  4. /*( }, J8 c9 ^: c" i1 e0 \1 Q
  5. *******************************************************************************************
    & l/ W& L8 s+ j+ L7 }. B
  6. *    函 数 名: main
    - F7 y6 @0 x( B8 n/ Q
  7. *    功能说明: c程序入口
    , Y& D3 T/ f9 R9 |
  8. *    形    参:无2 q+ C0 [6 t" ?% ?
  9. *    返 回 值: 错误代码(无需处理)% J" c# w1 x  t$ s, x0 e
  10. *******************************************************************************************
    " [  v7 b" ^6 o8 W9 u5 A
  11. */8 g  M* r. A8 Y
  12. int main(void)" z0 g: R: I/ ~% f, v( o& A- S- t
  13. {   ; [# k6 l) J% f+ h
  14.      //(在Cortex-M3 r1p1中推荐使用, 在Cortex-M3 r2px 和 Cortex-M4中默认支持)  H- b# G1 i3 d* X9 i
  15.      SCB->CCR |= SCB_CCR_STKALIGN_Msk;        // 使能堆栈的双字对齐模式% f% p- G2 |/ z  r( }& v: f
  16.     SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; // 使能 MemManage fault
    $ H- f8 K& _$ e" c
  17.     9 J5 t& `# `; f8 A# y( ~( m
  18.      bsp_InitUart();% p0 k" T+ E6 q$ D
  19.      PrintfLogo();$ H* ^  Y) }; @
  20.      bsp_Init();            /* 硬件初始化 */# c3 d* z  w5 Z1 f" H: f

  21. $ y  Q6 k: |1 m" V9 I
  22.      /* 进入主程序循环体 */; z( M% o$ ?6 e+ ^9 ~0 ]8 a! }- k
  23.      while (1)) L" i6 B5 f- V1 V* C6 [
  24.      {3 E% K8 t& O; [: G1 @6 `/ E
  25.          bsp_LedToggle(1);
    . L/ N0 B2 D% x9 H
  26.          bsp_LedToggle(3);
    & `# \5 E* V, j- Y2 G% H2 u
  27.          Delay(LOOP_COUNT);
    ; o. X# c4 i3 f; L  Z
  28.      }
    - ~1 k8 X2 [3 C5 ]1 M% z
  29. }$ w/ X! p0 ~5 D  h7 P
  30. 6 `, v4 V- u" R
  31. /*) {. O" [9 n/ ^' t- T) h' V
  32. *******************************************************************************************
    / W8 S; K% C* j7 y: @) t
  33. *    函 数 名: Delay$ J" J1 n' r  L0 B- `* g& T# Y* g  L
  34. *    功能说明: nCount 延迟  `+ r1 T0 d/ v! K- {6 b- Z' q
  35. *    形    参:无
    % c, ?$ z0 k0 b9 u, j
  36. *    返 回 值: 无1 ^$ k1 c, k, D; v5 Y# q
  37. */' o. I4 e: g: U: C2 y
  38. static void Delay(uint32_t nCount)
    ; D2 K/ P! U- m: O! t& U; I, T4 {
  39. {8 u; P; x* ^/ _3 z* e, _6 v2 W, }
  40.      while(nCount--)( ]1 [% K7 V7 V( Q7 _, Z
  41.      {
    7 B" j! V: A0 M
  42.          __DSB();/ O* y& E  p2 b7 ]% H
  43.      }
    5 k; }$ g# c4 H/ U& I
  44. }
复制代码

7 C5 M% @: B" c
baiyongbin2009 回答时间:2014-12-19 18:17:28
6.3  总结
          本期教程相对来说也比较的重要,希望初学RTOS的同学认真的学习。
; @' Y5 n* I) S
参考资料:
1.    Patterns fortime-triggered embedded systems英文版和中文版
2.    Cortex-M3权威指南中文版
3.    TheDefinitive Guide to Arm Cortex-M3 and Cortex-M4 Processors(M4权威指南)
0 U, F5 p+ R/ M+ U" J1 d: [

所属标签

相似技术帖

官网相关资源

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