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

【安富莱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权威指南)

所属标签

STM32团队

意法半导体微控制器和微处理器拥有广泛的产品线,包含低成本的8位单片机和基于ARM® Cortex®-M0、M0+、M3、M4、M33、M7及A7内核并具备丰富外设选择的32位微控制器及微处理器


最新内容

相似技术帖

官网相关资源

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