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

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

[复制链接]
baiyongbin2009 发布时间:2014-12-19 18:09
本帖最后由 baiyongbin2009 于 2014-12-19 18:12 编辑

特别说明:
1.  本教程是安富莱电子原创。
2.  安富莱STM32F407开发板资料已经全部开源,开源地址:地址链接
3.  当前共配套300多个实例,4套用户手册。

第6章  内存保护单元MPU

    本期教程带领大家学习内存保护单元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

6.2.1      实验一:MPU简易使用例子一
实验目的:
    1.学习MPU的配置
实验内容:
    1.初始化串口,LED和MPU
    2.主程序实现LED的闪烁
实验现象:
    请用USB转串口线连接PC机和开发板。PC机上运行SecureCRT软件,波特率设置为115200bps,无硬件流控。从PC机的软件界面观察程序执行结果(如果访问MPU范围之外的空间将出现下面现象):
6.2.png

    进入了硬件异常。
程序设计:
本程序主要分为两个部分:
  Ø  MPU的配置
  Ø  主程序
1.    MPU的配置
    MPU的配置相对比较容易,前提是一定要看权威指南上面对这个的介绍。
  1. /*
  2. *******************************************************************************************
  3. *    函 数 名: mpu_setup
  4. *    功能说明: mpu配置
  5. *    形    参:无
  6. *    返 回 值: 无
  7. *******************************************************************************************
  8. */
  9. static int mpu_setup(void)
  10. {
  11.      uint32_t i;
  12.    
  13.      uint32_t const mpu_cfg_rbar[4] =
  14.      {
  15.          0x08000000,  // Flash
  16.          0x20000000,  // SRAM
  17.          GPIOF_BASE,  // GPIO F base address
  18.          RCC_BASE     // Reset Clock CTRL base address
  19.      };
  20.    
  21.      uint32_t const mpu_cfg_rasr[4] =
  22.      {
  23.          (MPU_DEFS_RASR_SIZE_1MB       | MPU_DEFS_NORMAL_MEMORY_WT |
  24.          MPU_DEFS_RASE_AP_FULL_ACCESS | MPU_RASR_ENABLE_Msk), // Flash
  25.          (MPU_DEFS_RASR_SIZE_128KB     | MPU_DEFS_NORMAL_MEMORY_WT |
  26.          MPU_DEFS_RASE_AP_FULL_ACCESS | MPU_RASR_ENABLE_Msk), // SRAM
  27.          (MPU_DEFS_RASR_SIZE_1KB       | MPU_DEFS_SHARED_DEVICE    |
  28.          MPU_DEFS_RASE_AP_FULL_ACCESS | MPU_RASR_ENABLE_Msk), // GPIO D
  29.          (MPU_DEFS_RASR_SIZE_1KB       | MPU_DEFS_SHARED_DEVICE    |
  30.          MPU_DEFS_RASE_AP_FULL_ACCESS | MPU_RASR_ENABLE_Msk)  // RCC
  31.      };
  32.    
  33.      /* 通过读取此寄存器的DREGION位值,够判断芯片中是否配了MPU */
  34.      if (MPU->TYPE==0)
  35.     {
  36.          return 1;
  37.      }   
  38.      __DMB();                 // Make sure outstanding transfers are done
  39.    
  40.      /* 禁止MPU */
  41.      MPU->CTRL = 0;

  42.     /* 配置MPU的4个region */
  43.      for (i=0;i<4;i++)
  44.      {         
  45.          MPU->RNR  = i;                 // 选择配置那个region
  46.          MPU->RBAR = mpu_cfg_rbar[i];   // 配置地址
  47.          MPU->RASR = mpu_cfg_rasr[i];   // 配置属性和大小
  48.      }
  49.    
  50.      /* 下面的配置,相当于禁止*/
  51.      for (i=4;i<8;i++)
  52.      {
  53.          MPU->RNR  = i;
  54.          MPU->RBAR = 0;  
  55.          MPU->RASR = 0;
  56.      }   

  57.     /* 使能MPU */
  58.      MPU->CTRL = MPU_CTRL_ENABLE_Msk;
  59.      __DSB();  // Ensure MPU settings take effects
  60.      __ISB();  // Sequence instruction fetches using update settings
  61. }
复制代码
2.    主程序
    主程序的功能也比较的简单,就是实现LED的闪烁。
  1. #define MPU_DEFS_RASR_SIZE_32B   (0x04 << MPU_RASR_SIZE_Pos)
  2. #define MPU_DEFS_RASR_SIZE_64B   (0x05 << MPU_RASR_SIZE_Pos)
  3. #define MPU_DEFS_RASR_SIZE_128B  (0x06 << MPU_RASR_SIZE_Pos)
  4. #define MPU_DEFS_RASR_SIZE_256B  (0x07 << MPU_RASR_SIZE_Pos)
  5. #define MPU_DEFS_RASR_SIZE_512B  (0x08 << MPU_RASR_SIZE_Pos)
  6. #define MPU_DEFS_RASR_SIZE_1KB   (0x09 << MPU_RASR_SIZE_Pos)
  7. #define MPU_DEFS_RASR_SIZE_2KB   (0x0A << MPU_RASR_SIZE_Pos)
  8. #define MPU_DEFS_RASR_SIZE_4KB   (0x0B << MPU_RASR_SIZE_Pos)
  9. #define MPU_DEFS_RASR_SIZE_8KB   (0x0C << MPU_RASR_SIZE_Pos)
  10. #define MPU_DEFS_RASR_SIZE_16KB  (0x0D << MPU_RASR_SIZE_Pos)
  11. #define MPU_DEFS_RASR_SIZE_32KB  (0x0E << MPU_RASR_SIZE_Pos)
  12. #define MPU_DEFS_RASR_SIZE_64KB  (0x0F << MPU_RASR_SIZE_Pos)
  13. #define MPU_DEFS_RASR_SIZE_128KB (0x10 << MPU_RASR_SIZE_Pos)
  14. #define MPU_DEFS_RASR_SIZE_256KB (0x11 << MPU_RASR_SIZE_Pos)
  15. #define MPU_DEFS_RASR_SIZE_512KB (0x12 << MPU_RASR_SIZE_Pos)
  16. #define MPU_DEFS_RASR_SIZE_1MB   (0x13 << MPU_RASR_SIZE_Pos)
  17. #define MPU_DEFS_RASR_SIZE_2MB   (0x14 << MPU_RASR_SIZE_Pos)
  18. #define MPU_DEFS_RASR_SIZE_4MB   (0x15 << MPU_RASR_SIZE_Pos)
  19. #define MPU_DEFS_RASR_SIZE_8MB   (0x16 << MPU_RASR_SIZE_Pos)
  20. #define MPU_DEFS_RASR_SIZE_16MB  (0x17 << MPU_RASR_SIZE_Pos)
  21. #define MPU_DEFS_RASR_SIZE_32MB  (0x18 << MPU_RASR_SIZE_Pos)
  22. #define MPU_DEFS_RASR_SIZE_64MB  (0x19 << MPU_RASR_SIZE_Pos)
  23. #define MPU_DEFS_RASR_SIZE_128MB (0x1A << MPU_RASR_SIZE_Pos)
  24. #define MPU_DEFS_RASR_SIZE_256MB (0x1B << MPU_RASR_SIZE_Pos)
  25. #define MPU_DEFS_RASR_SIZE_512MB (0x1C << MPU_RASR_SIZE_Pos)
  26. #define MPU_DEFS_RASR_SIZE_1GB   (0x1D << MPU_RASR_SIZE_Pos)
  27. #define MPU_DEFS_RASR_SIZE_2GB   (0x1E << MPU_RASR_SIZE_Pos)
  28. #define MPU_DEFS_RASR_SIZE_4GB   (0x1F << MPU_RASR_SIZE_Pos)
  29. #define MPU_DEFS_RASE_AP_NO_ACCESS       (0x0 << MPU_RASR_AP_Pos)
  30. #define MPU_DEFS_RASE_AP_PRIV_RW         (0x1 << MPU_RASR_AP_Pos)
  31. #define MPU_DEFS_RASE_AP_PRIV_RW_USER_RO (0x2 << MPU_RASR_AP_Pos)
  32. #define MPU_DEFS_RASE_AP_FULL_ACCESS     (0x3 << MPU_RASR_AP_Pos)
  33. #define MPU_DEFS_RASE_AP_PRIV_RO         (0x5 << MPU_RASR_AP_Pos)
  34. #define MPU_DEFS_RASE_AP_RO              (0x6 << MPU_RASR_AP_Pos)
  35. #define MPU_DEFS_NORMAL_MEMORY_WT        (MPU_RASR_C_Msk)
  36. #define MPU_DEFS_NORMAL_MEMORY_WB        (MPU_RASR_C_Msk | MPU_RASR_B_Msk)
  37. #define MPU_DEFS_NORMAL_SHARED_MEMORY_WT (MPU_RASR_C_Msk | MPU_RASR_S_Msk)
  38. #define MPU_DEFS_NORMAL_SHARED_MEMORY_WB (MPU_DEFS_NORMAL_MEMORY_WB | MPU_RASR_S_Msk)
  39. #define MPU_DEFS_SHARED_DEVICE           (MPU_RASR_B_Msk | MPU_RASR_S_Msk)
  40. #define MPU_DEFS_STRONGLY_ORDERED_DEVICE (0x0)

  41. #define LOOP_COUNT 0x3FFFFF

  42. /* 仅允许本文件内调用的函数声明 */
  43. static void PrintfLogo(void);
  44. static int mpu_setup(void);
  45. static void Delay(uint32_t nCount);

  46. /*
  47. *******************************************************************************************
  48. *    函 数 名: main
  49. *    功能说明: c程序入口
  50. *    形    参:无
  51. *    返 回 值: 错误代码(无需处理)
  52. *******************************************************************************************
  53. */
  54. int main(void)
  55. {   
  56.      //(在Cortex-M3 r1p1中推荐使用, 在Cortex-M3 r2px 和 Cortex-M4中默认支持)
  57.      SCB->CCR |= SCB_CCR_STKALIGN_Msk;        // 使能堆栈的双字对齐模式
  58.     SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; // 使能 MemManage fault
  59.    
  60.      bsp_InitUart();
  61.      PrintfLogo();
  62.      bsp_InitLed();         /* 初始LED指示灯端口 */
  63.      mpu_setup();
  64.    
  65.      /* 进入主程序循环体 */
  66.      while (1)
  67.      {
  68.          bsp_LedToggle(1);
  69.          bsp_LedToggle(3);
  70.          Delay(LOOP_COUNT);
  71.      }
  72. }

  73. /*
  74. *******************************************************************************************
  75. *    函 数 名: Delay
  76. *    功能说明: nCount 延迟
  77. *    形    参:无
  78. *    返 回 值: 无
  79. *******************************************************************************************
  80. */
  81. static void Delay(uint32_t nCount)
  82. {
  83.      while(nCount--)
  84.      {
  85.          __DSB();
  86.      }
  87. }
复制代码

收藏 评论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. /*
  2. *******************************************************************************************
  3. *    函 数 名: mpu_setup
  4. *    功能说明: mpu配置
  5. *    形    参:无
  6. *    返 回 值: 无
  7. *******************************************************************************************
  8. */
  9. static int mpu_setup(void)
  10. {
  11.      uint32_t i;
  12.    
  13.      uint32_t const mpu_cfg_rbar[4] =
  14.      {
  15.            // Flash - region 0
  16.          (0x08000000 | MPU_RBAR_VALID_Msk | (MPU_RBAR_REGION_Msk & 0)),
  17.          // SRAM  - region 1
  18.          (0x20000000 | MPU_RBAR_VALID_Msk | (MPU_RBAR_REGION_Msk & 1)),
  19.          // GPIO D base address - region 2
  20.          (GPIOF_BASE | MPU_RBAR_VALID_Msk | (MPU_RBAR_REGION_Msk & 2)),
  21.          // Reset Clock CTRL base address - region 3
  22.          (RCC_BASE   | MPU_RBAR_VALID_Msk | (MPU_RBAR_REGION_Msk & 3))
  23.      };
  24.    
  25.      uint32_t const mpu_cfg_rasr[4] =
  26.      {
  27.          (MPU_DEFS_RASR_SIZE_1MB       | MPU_DEFS_NORMAL_MEMORY_WT |
  28.          MPU_DEFS_RASE_AP_FULL_ACCESS | MPU_RASR_ENABLE_Msk), // Flash
  29.          (MPU_DEFS_RASR_SIZE_128KB     | MPU_DEFS_NORMAL_MEMORY_WT |
  30.          MPU_DEFS_RASE_AP_FULL_ACCESS | MPU_RASR_ENABLE_Msk), // SRAM
  31.          (MPU_DEFS_RASR_SIZE_1KB       | MPU_DEFS_SHARED_DEVICE    |
  32.          MPU_DEFS_RASE_AP_FULL_ACCESS | MPU_RASR_ENABLE_Msk), // GPIO D
  33.          (MPU_DEFS_RASR_SIZE_1KB       | MPU_DEFS_SHARED_DEVICE    |
  34.          MPU_DEFS_RASE_AP_FULL_ACCESS | MPU_RASR_ENABLE_Msk)  // RCC
  35.      };
  36.    
  37.      /* 通过读取此寄存器的DREGION位值,够判断芯片中是否配了MPU */
  38.      if (MPU->TYPE==0)
  39.     {
  40.          return 1;
  41.      }   
  42.      __DMB();                 // Make sure outstanding transfers are done
  43.    
  44.      /* 禁止MPU */
  45.      MPU->CTRL = 0;

  46.     /* 配置MPU的4个region */
  47.      for (i=0;i<4;i++)
  48.      {         
  49.          MPU->RNR  = i;                 // 选择配置那个region
  50.          MPU->RBAR = mpu_cfg_rbar[i];   // 配置地址
  51.          MPU->RASR = mpu_cfg_rasr[i];   // 配置属性和大小
  52.      }
  53.    
  54.      /* 下面的配置,相当于禁止其余的4个region */
  55.      for (i=4;i<8;i++)
  56.      {
  57.          MPU->RNR  = i;
  58.          MPU->RBAR = 0;  
  59.          MPU->RASR = 0;
  60.      }   

  61.     /* 使能MPU */
  62.      MPU->CTRL = MPU_CTRL_ENABLE_Msk;
  63.      __DSB();  // Ensure MPU settings take effects
  64.      __ISB();  // Sequence instruction fetches using update settings
  65. }
复制代码
2.    主程序
    主程序的功能也比较的简单,就是实现LED的闪烁。
  1. #define MPU_DEFS_RASR_SIZE_32B   (0x04 << MPU_RASR_SIZE_Pos)
  2. #define MPU_DEFS_RASR_SIZE_64B   (0x05 << MPU_RASR_SIZE_Pos)
  3. #define MPU_DEFS_RASR_SIZE_128B  (0x06 << MPU_RASR_SIZE_Pos)
  4. #define MPU_DEFS_RASR_SIZE_256B  (0x07 << MPU_RASR_SIZE_Pos)
  5. #define MPU_DEFS_RASR_SIZE_512B  (0x08 << MPU_RASR_SIZE_Pos)
  6. #define MPU_DEFS_RASR_SIZE_1KB   (0x09 << MPU_RASR_SIZE_Pos)
  7. #define MPU_DEFS_RASR_SIZE_2KB   (0x0A << MPU_RASR_SIZE_Pos)
  8. #define MPU_DEFS_RASR_SIZE_4KB   (0x0B << MPU_RASR_SIZE_Pos)
  9. #define MPU_DEFS_RASR_SIZE_8KB   (0x0C << MPU_RASR_SIZE_Pos)
  10. #define MPU_DEFS_RASR_SIZE_16KB  (0x0D << MPU_RASR_SIZE_Pos)
  11. #define MPU_DEFS_RASR_SIZE_32KB  (0x0E << MPU_RASR_SIZE_Pos)
  12. #define MPU_DEFS_RASR_SIZE_64KB  (0x0F << MPU_RASR_SIZE_Pos)
  13. #define MPU_DEFS_RASR_SIZE_128KB (0x10 << MPU_RASR_SIZE_Pos)
  14. #define MPU_DEFS_RASR_SIZE_256KB (0x11 << MPU_RASR_SIZE_Pos)
  15. #define MPU_DEFS_RASR_SIZE_512KB (0x12 << MPU_RASR_SIZE_Pos)
  16. #define MPU_DEFS_RASR_SIZE_1MB   (0x13 << MPU_RASR_SIZE_Pos)
  17. #define MPU_DEFS_RASR_SIZE_2MB   (0x14 << MPU_RASR_SIZE_Pos)
  18. #define MPU_DEFS_RASR_SIZE_4MB   (0x15 << MPU_RASR_SIZE_Pos)
  19. #define MPU_DEFS_RASR_SIZE_8MB   (0x16 << MPU_RASR_SIZE_Pos)
  20. #define MPU_DEFS_RASR_SIZE_16MB  (0x17 << MPU_RASR_SIZE_Pos)
  21. #define MPU_DEFS_RASR_SIZE_32MB  (0x18 << MPU_RASR_SIZE_Pos)
  22. #define MPU_DEFS_RASR_SIZE_64MB  (0x19 << MPU_RASR_SIZE_Pos)
  23. #define MPU_DEFS_RASR_SIZE_128MB (0x1A << MPU_RASR_SIZE_Pos)
  24. #define MPU_DEFS_RASR_SIZE_256MB (0x1B << MPU_RASR_SIZE_Pos)
  25. #define MPU_DEFS_RASR_SIZE_512MB (0x1C << MPU_RASR_SIZE_Pos)
  26. #define MPU_DEFS_RASR_SIZE_1GB   (0x1D << MPU_RASR_SIZE_Pos)
  27. #define MPU_DEFS_RASR_SIZE_2GB   (0x1E << MPU_RASR_SIZE_Pos)
  28. #define MPU_DEFS_RASR_SIZE_4GB   (0x1F << MPU_RASR_SIZE_Pos)
  29. #define MPU_DEFS_RASE_AP_NO_ACCESS       (0x0 << MPU_RASR_AP_Pos)
  30. #define MPU_DEFS_RASE_AP_PRIV_RW         (0x1 << MPU_RASR_AP_Pos)
  31. #define MPU_DEFS_RASE_AP_PRIV_RW_USER_RO (0x2 << MPU_RASR_AP_Pos)
  32. #define MPU_DEFS_RASE_AP_FULL_ACCESS     (0x3 << MPU_RASR_AP_Pos)
  33. #define MPU_DEFS_RASE_AP_PRIV_RO         (0x5 << MPU_RASR_AP_Pos)
  34. #define MPU_DEFS_RASE_AP_RO              (0x6 << MPU_RASR_AP_Pos)
  35. #define MPU_DEFS_NORMAL_MEMORY_WT        (MPU_RASR_C_Msk)
  36. #define MPU_DEFS_NORMAL_MEMORY_WB        (MPU_RASR_C_Msk | MPU_RASR_B_Msk)
  37. #define MPU_DEFS_NORMAL_SHARED_MEMORY_WT (MPU_RASR_C_Msk | MPU_RASR_S_Msk)
  38. #define MPU_DEFS_NORMAL_SHARED_MEMORY_WB (MPU_DEFS_NORMAL_MEMORY_WB | MPU_RASR_S_Msk)
  39. #define MPU_DEFS_SHARED_DEVICE           (MPU_RASR_B_Msk | MPU_RASR_S_Msk)
  40. #define MPU_DEFS_STRONGLY_ORDERED_DEVICE (0x0)

  41. #define LOOP_COUNT 0x3FFFFF

  42. /* 仅允许本文件内调用的函数声明 */
  43. static void PrintfLogo(void);
  44. static int mpu_setup(void);
  45. static void Delay(uint32_t nCount);

  46. /*
  47. *******************************************************************************************
  48. *    函 数 名: main
  49. *    功能说明: c程序入口
  50. *    形    参:无
  51. *    返 回 值: 错误代码(无需处理)
  52. *******************************************************************************************
  53. */
  54. int main(void)
  55. {   
  56.      //(在Cortex-M3 r1p1中推荐使用, 在Cortex-M3 r2px 和 Cortex-M4中默认支持)
  57.      SCB->CCR |= SCB_CCR_STKALIGN_Msk;        // 使能堆栈的双字对齐模式
  58.     SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; // 使能 MemManage fault
  59.    
  60.      bsp_InitUart();
  61.      PrintfLogo();
  62.      bsp_InitLed();         /* 初始LED指示灯端口 */
  63.      mpu_setup();
  64.    
  65.      /* 进入主程序循环体 */
  66.      while (1)
  67.      {
  68.          bsp_LedToggle(1);
  69.          bsp_LedToggle(3);
  70.          Delay(LOOP_COUNT);
  71.      }
  72. }

  73. /*
  74. *******************************************************************************************
  75. *    函 数 名: Delay
  76. *    功能说明: nCount 延迟
  77. *    形    参:无
  78. *    返 回 值: 无
  79. *******************************************************************************************
  80. */
  81. static void Delay(uint32_t nCount)
  82. {
  83.      while(nCount--)
  84.      {
  85.          __DSB();
  86.      }
  87. }
复制代码

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)
  2. #define MPU_DEFS_RASR_SIZE_64B   (0x05 << MPU_RASR_SIZE_Pos)
  3. #define MPU_DEFS_RASR_SIZE_128B  (0x06 << MPU_RASR_SIZE_Pos)
  4. #define MPU_DEFS_RASR_SIZE_256B  (0x07 << MPU_RASR_SIZE_Pos)
  5. #define MPU_DEFS_RASR_SIZE_512B  (0x08 << MPU_RASR_SIZE_Pos)
  6. #define MPU_DEFS_RASR_SIZE_1KB   (0x09 << MPU_RASR_SIZE_Pos)
  7. #define MPU_DEFS_RASR_SIZE_2KB   (0x0A << MPU_RASR_SIZE_Pos)
  8. #define MPU_DEFS_RASR_SIZE_4KB   (0x0B << MPU_RASR_SIZE_Pos)
  9. #define MPU_DEFS_RASR_SIZE_8KB   (0x0C << MPU_RASR_SIZE_Pos)
  10. #define MPU_DEFS_RASR_SIZE_16KB  (0x0D << MPU_RASR_SIZE_Pos)
  11. #define MPU_DEFS_RASR_SIZE_32KB  (0x0E << MPU_RASR_SIZE_Pos)
  12. #define MPU_DEFS_RASR_SIZE_64KB  (0x0F << MPU_RASR_SIZE_Pos)
  13. #define MPU_DEFS_RASR_SIZE_128KB (0x10 << MPU_RASR_SIZE_Pos)
  14. #define MPU_DEFS_RASR_SIZE_256KB (0x11 << MPU_RASR_SIZE_Pos)
  15. #define MPU_DEFS_RASR_SIZE_512KB (0x12 << MPU_RASR_SIZE_Pos)
  16. #define MPU_DEFS_RASR_SIZE_1MB   (0x13 << MPU_RASR_SIZE_Pos)
  17. #define MPU_DEFS_RASR_SIZE_2MB   (0x14 << MPU_RASR_SIZE_Pos)
  18. #define MPU_DEFS_RASR_SIZE_4MB   (0x15 << MPU_RASR_SIZE_Pos)
  19. #define MPU_DEFS_RASR_SIZE_8MB   (0x16 << MPU_RASR_SIZE_Pos)
  20. #define MPU_DEFS_RASR_SIZE_16MB  (0x17 << MPU_RASR_SIZE_Pos)
  21. #define MPU_DEFS_RASR_SIZE_32MB  (0x18 << MPU_RASR_SIZE_Pos)
  22. #define MPU_DEFS_RASR_SIZE_64MB  (0x19 << MPU_RASR_SIZE_Pos)
  23. #define MPU_DEFS_RASR_SIZE_128MB (0x1A << MPU_RASR_SIZE_Pos)
  24. #define MPU_DEFS_RASR_SIZE_256MB (0x1B << MPU_RASR_SIZE_Pos)
  25. #define MPU_DEFS_RASR_SIZE_512MB (0x1C << MPU_RASR_SIZE_Pos)
  26. #define MPU_DEFS_RASR_SIZE_1GB   (0x1D << MPU_RASR_SIZE_Pos)
  27. #define MPU_DEFS_RASR_SIZE_2GB   (0x1E << MPU_RASR_SIZE_Pos)
  28. #define MPU_DEFS_RASR_SIZE_4GB   (0x1F << MPU_RASR_SIZE_Pos)
  29. #define MPU_DEFS_RASE_AP_NO_ACCESS       (0x0 << MPU_RASR_AP_Pos)
  30. #define MPU_DEFS_RASE_AP_PRIV_RW         (0x1 << MPU_RASR_AP_Pos)
  31. #define MPU_DEFS_RASE_AP_PRIV_RW_USER_RO (0x2 << MPU_RASR_AP_Pos)
  32. #define MPU_DEFS_RASE_AP_FULL_ACCESS     (0x3 << MPU_RASR_AP_Pos)
  33. #define MPU_DEFS_RASE_AP_PRIV_RO         (0x5 << MPU_RASR_AP_Pos)
  34. #define MPU_DEFS_RASE_AP_RO              (0x6 << MPU_RASR_AP_Pos)
  35. #define MPU_DEFS_NORMAL_MEMORY_WT        (MPU_RASR_C_Msk)
  36. #define MPU_DEFS_NORMAL_MEMORY_WB        (MPU_RASR_C_Msk | MPU_RASR_B_Msk)
  37. #define MPU_DEFS_NORMAL_SHARED_MEMORY_WT (MPU_RASR_C_Msk | MPU_RASR_S_Msk)
  38. #define MPU_DEFS_NORMAL_SHARED_MEMORY_WB (MPU_DEFS_NORMAL_MEMORY_WB | MPU_RASR_S_Msk)
  39. #define MPU_DEFS_SHARED_DEVICE           (MPU_RASR_B_Msk | MPU_RASR_S_Msk)
  40. #define MPU_DEFS_STRONGLY_ORDERED_DEVICE (0x0)

  41. /*************************************************/
  42. void mpu_region_config(uint32_t region_num, uint32_t addr, uint32_t size, uint32_t attributes);
  43. void mpu_enable(uint32_t options);
  44. void mpu_disable(void);
  45. void mpu_region_disable(uint32_t region_num);

  46. /*
  47. *******************************************************************************************
  48. *    函 数 名: bsp_InitMPU
  49. *    功能说明: 内存保护单元初始化
  50. *    形    参: 无
  51. *    返 回 值: 0 表示失败,1 表示成功
  52. *******************************************************************************************
  53. */
  54. uint8_t bsp_InitMPU(void)
  55. {
  56.      if (MPU->TYPE==0)
  57.      {
  58.          return 0;
  59.      }
  60.     /* 第一步要先禁止MPU再进行相应的设置 */  
  61.      mpu_disable();
  62.    
  63.      /* 设置MPU的8个Region */
  64.      /* 配置Region 0 - Flash */
  65.      mpu_region_config(0, 0x08000000, MPU_DEFS_RASR_SIZE_1MB,
  66.      MPU_DEFS_NORMAL_MEMORY_WT | MPU_DEFS_RASE_AP_FULL_ACCESS |
  67.      MPU_RASR_ENABLE_Msk),
  68.      /* 配置Region 1 - SRAM */
  69.      mpu_region_config(1, 0x20000000, MPU_DEFS_RASR_SIZE_128KB,
  70.      MPU_DEFS_NORMAL_MEMORY_WT | MPU_DEFS_RASE_AP_FULL_ACCESS |
  71.      MPU_RASR_ENABLE_Msk),
  72.      /* 配置Region 2 - GPIO D */
  73.      mpu_region_config(2, GPIOF_BASE, MPU_DEFS_RASR_SIZE_1KB,
  74.      MPU_DEFS_SHARED_DEVICE    | MPU_DEFS_RASE_AP_FULL_ACCESS |
  75.      MPU_RASR_ENABLE_Msk),
  76.      /* 配置Region 3 - Reset Clock CTRL */
  77.      mpu_region_config(3, RCC_BASE, MPU_DEFS_RASR_SIZE_1KB,
  78.      MPU_DEFS_SHARED_DEVICE    | MPU_DEFS_RASE_AP_FULL_ACCESS |
  79.      MPU_RASR_ENABLE_Msk),
  80.      /* 禁止Region 4 */
  81.      mpu_region_disable(4);
  82.      /* 禁止Region 5 */
  83.      mpu_region_disable(5);
  84.      /* 禁止Region 6 */
  85.      mpu_region_disable(6);
  86.      /* 禁止Region 7 */
  87.      mpu_region_disable(7);
  88.    
  89.      /* 使能允许MPU */
  90.      mpu_enable(0);
  91.    
  92.      return 1;
  93. }

  94. /*
  95. *******************************************************************************************
  96. *    函 数 名: mpu_enable
  97. *    功能说明: mpu使能,mpu控制寄存器有3位,功能分别如下:
  98. *             位2  PRIVDEFENA 是否为特权级打开缺省存储器映射(即背景
  99. *                             region)。
  100. *                             1 = 特权级下打开背景region
  101. *                             0 = 不打开背景region。任何访问违例以及对
  102. *                                 region外地址区的访问都将引起fault。
  103. *             位1  HFNMIENA   1=在NMI和硬fault服务例程中不强制除能MPU
  104. *                             0=在NMI和硬fault服务例程中强制除能MPU
  105. *             位0  ENABLE     使能或者禁止
  106. *    形    参: options  MPU_CTRL_HFNMIENA_Msk或者MPU_CTRL_PRIVDEFENA_Msk
  107. *    返 回 值: 无
  108. *******************************************************************************************
  109. */
  110. void mpu_enable(uint32_t options)
  111. {
  112.      MPU->CTRL = MPU_CTRL_ENABLE_Msk | options;
  113.      __DSB();  // Ensure MPU settings take effects
  114.      __ISB();  // Sequence instruction fetches using update settings
  115. }

  116. /*
  117. *******************************************************************************************
  118. *    函 数 名: mpu_disable
  119. *    功能说明: 禁止mpu
  120. *    形    参: 无
  121. *    返 回 值: 无
  122. *******************************************************************************************
  123. */
  124. void mpu_disable(void)
  125. {
  126.      __DMB();            // Make sure outstanding transfers are done
  127.      MPU->CTRL = 0;      // Disable the MPU
  128. }

  129. /*
  130. *******************************************************************************************
  131. *    函 数 名: mpu_region_disable
  132. *    功能说明: 禁止mpu谋一个region
  133. *    形    参: region_num  范围0 - 7
  134. *    返 回 值: 无
  135. *******************************************************************************************
  136. */
  137. void mpu_region_disable(uint32_t region_num)
  138. {
  139.      MPU->RNR  = region_num;
  140.      MPU->RBAR = 0;
  141.      MPU->RASR = 0;
  142. }   

  143. /*
  144. *******************************************************************************************
  145. *    函 数 名: mpu_region_config
  146. *    功能说明: mpu配置
  147. *    形    参: region_num  范围0 - 7
  148. *             addr  地址
  149. *             size  大小
  150. *             attributes 属性
  151. *    返 回 值: 无
  152. *******************************************************************************************
  153. */
  154. void mpu_region_config(uint32_t region_num, uint32_t addr, uint32_t size, uint32_t attributes)
  155. {
  156.      MPU->RNR  = region_num;
  157.      MPU->RBAR = addr;
  158.      MPU->RASR = size | attributes;
  159. }
复制代码
2.    主程序
  1. /* 仅允许本文件内调用的函数声明 */
  2. static void PrintfLogo(void);
  3. static void Delay(uint32_t nCount);
  4. /*
  5. *******************************************************************************************
  6. *    函 数 名: main
  7. *    功能说明: c程序入口
  8. *    形    参:无
  9. *    返 回 值: 错误代码(无需处理)
  10. *******************************************************************************************
  11. */
  12. int main(void)
  13. {   
  14.      //(在Cortex-M3 r1p1中推荐使用, 在Cortex-M3 r2px 和 Cortex-M4中默认支持)
  15.      SCB->CCR |= SCB_CCR_STKALIGN_Msk;        // 使能堆栈的双字对齐模式
  16.     SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; // 使能 MemManage fault
  17.    
  18.      bsp_InitUart();
  19.      PrintfLogo();
  20.      bsp_Init();            /* 硬件初始化 */

  21.      /* 进入主程序循环体 */
  22.      while (1)
  23.      {
  24.          bsp_LedToggle(1);
  25.          bsp_LedToggle(3);
  26.          Delay(LOOP_COUNT);
  27.      }
  28. }

  29. /*
  30. *******************************************************************************************
  31. *    函 数 名: Delay
  32. *    功能说明: nCount 延迟
  33. *    形    参:无
  34. *    返 回 值: 无
  35. */
  36. static void Delay(uint32_t nCount)
  37. {
  38.      while(nCount--)
  39.      {
  40.          __DSB();
  41.      }
  42. }
复制代码

baiyongbin2009 回答时间:2014-12-19 18:17:28
6.3  总结
          本期教程相对来说也比较的重要,希望初学RTOS的同学认真的学习。

参考资料:
1.    Patterns fortime-triggered embedded systems英文版和中文版
2.    Cortex-M3权威指南中文版
3.    TheDefinitive Guide to Arm Cortex-M3 and Cortex-M4 Processors(M4权威指南)

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