本帖最后由 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.2.1 实验一:MPU简易使用例子一实验目的: 1.学习MPU的配置 实验内容: 1.初始化串口,LED和MPU 2.主程序实现LED的闪烁 实验现象: 请用USB转串口线连接PC机和开发板。PC机上运行SecureCRT软件,波特率设置为115200bps,无硬件流控。从PC机的软件界面观察程序执行结果(如果访问MPU范围之外的空间将出现下面现象):
进入了硬件异常。 程序设计: 本程序主要分为两个部分: Ø MPU的配置 Ø 主程序 1. MPU的配置 MPU的配置相对比较容易,前提是一定要看权威指南上面对这个的介绍。 - /*
- *******************************************************************************************
- * 函 数 名: mpu_setup
- * 功能说明: mpu配置
- * 形 参:无
- * 返 回 值: 无
- *******************************************************************************************
- */
- static int mpu_setup(void)
- {
- uint32_t i;
-
- uint32_t const mpu_cfg_rbar[4] =
- {
- 0x08000000, // Flash
- 0x20000000, // SRAM
- GPIOF_BASE, // GPIO F base address
- RCC_BASE // Reset Clock CTRL base address
- };
-
- uint32_t const mpu_cfg_rasr[4] =
- {
- (MPU_DEFS_RASR_SIZE_1MB | MPU_DEFS_NORMAL_MEMORY_WT |
- MPU_DEFS_RASE_AP_FULL_ACCESS | MPU_RASR_ENABLE_Msk), // Flash
- (MPU_DEFS_RASR_SIZE_128KB | MPU_DEFS_NORMAL_MEMORY_WT |
- MPU_DEFS_RASE_AP_FULL_ACCESS | MPU_RASR_ENABLE_Msk), // SRAM
- (MPU_DEFS_RASR_SIZE_1KB | MPU_DEFS_SHARED_DEVICE |
- MPU_DEFS_RASE_AP_FULL_ACCESS | MPU_RASR_ENABLE_Msk), // GPIO D
- (MPU_DEFS_RASR_SIZE_1KB | MPU_DEFS_SHARED_DEVICE |
- MPU_DEFS_RASE_AP_FULL_ACCESS | MPU_RASR_ENABLE_Msk) // RCC
- };
-
- /* 通过读取此寄存器的DREGION位值,够判断芯片中是否配了MPU */
- if (MPU->TYPE==0)
- {
- return 1;
- }
- __DMB(); // Make sure outstanding transfers are done
-
- /* 禁止MPU */
- MPU->CTRL = 0;
-
- /* 配置MPU的4个region */
- for (i=0;i<4;i++)
- {
- MPU->RNR = i; // 选择配置那个region
- MPU->RBAR = mpu_cfg_rbar[i]; // 配置地址
- MPU->RASR = mpu_cfg_rasr[i]; // 配置属性和大小
- }
-
- /* 下面的配置,相当于禁止*/
- for (i=4;i<8;i++)
- {
- MPU->RNR = i;
- MPU->RBAR = 0;
- MPU->RASR = 0;
- }
-
- /* 使能MPU */
- MPU->CTRL = MPU_CTRL_ENABLE_Msk;
- __DSB(); // Ensure MPU settings take effects
- __ISB(); // Sequence instruction fetches using update settings
- }
复制代码2. 主程序 主程序的功能也比较的简单,就是实现LED的闪烁。 - #define MPU_DEFS_RASR_SIZE_32B (0x04 << MPU_RASR_SIZE_Pos)
- #define MPU_DEFS_RASR_SIZE_64B (0x05 << MPU_RASR_SIZE_Pos)
- #define MPU_DEFS_RASR_SIZE_128B (0x06 << MPU_RASR_SIZE_Pos)
- #define MPU_DEFS_RASR_SIZE_256B (0x07 << MPU_RASR_SIZE_Pos)
- #define MPU_DEFS_RASR_SIZE_512B (0x08 << MPU_RASR_SIZE_Pos)
- #define MPU_DEFS_RASR_SIZE_1KB (0x09 << MPU_RASR_SIZE_Pos)
- #define MPU_DEFS_RASR_SIZE_2KB (0x0A << MPU_RASR_SIZE_Pos)
- #define MPU_DEFS_RASR_SIZE_4KB (0x0B << MPU_RASR_SIZE_Pos)
- #define MPU_DEFS_RASR_SIZE_8KB (0x0C << MPU_RASR_SIZE_Pos)
- #define MPU_DEFS_RASR_SIZE_16KB (0x0D << MPU_RASR_SIZE_Pos)
- #define MPU_DEFS_RASR_SIZE_32KB (0x0E << MPU_RASR_SIZE_Pos)
- #define MPU_DEFS_RASR_SIZE_64KB (0x0F << MPU_RASR_SIZE_Pos)
- #define MPU_DEFS_RASR_SIZE_128KB (0x10 << MPU_RASR_SIZE_Pos)
- #define MPU_DEFS_RASR_SIZE_256KB (0x11 << MPU_RASR_SIZE_Pos)
- #define MPU_DEFS_RASR_SIZE_512KB (0x12 << MPU_RASR_SIZE_Pos)
- #define MPU_DEFS_RASR_SIZE_1MB (0x13 << MPU_RASR_SIZE_Pos)
- #define MPU_DEFS_RASR_SIZE_2MB (0x14 << MPU_RASR_SIZE_Pos)
- #define MPU_DEFS_RASR_SIZE_4MB (0x15 << MPU_RASR_SIZE_Pos)
- #define MPU_DEFS_RASR_SIZE_8MB (0x16 << MPU_RASR_SIZE_Pos)
- #define MPU_DEFS_RASR_SIZE_16MB (0x17 << MPU_RASR_SIZE_Pos)
- #define MPU_DEFS_RASR_SIZE_32MB (0x18 << MPU_RASR_SIZE_Pos)
- #define MPU_DEFS_RASR_SIZE_64MB (0x19 << MPU_RASR_SIZE_Pos)
- #define MPU_DEFS_RASR_SIZE_128MB (0x1A << MPU_RASR_SIZE_Pos)
- #define MPU_DEFS_RASR_SIZE_256MB (0x1B << MPU_RASR_SIZE_Pos)
- #define MPU_DEFS_RASR_SIZE_512MB (0x1C << MPU_RASR_SIZE_Pos)
- #define MPU_DEFS_RASR_SIZE_1GB (0x1D << MPU_RASR_SIZE_Pos)
- #define MPU_DEFS_RASR_SIZE_2GB (0x1E << MPU_RASR_SIZE_Pos)
- #define MPU_DEFS_RASR_SIZE_4GB (0x1F << MPU_RASR_SIZE_Pos)
- #define MPU_DEFS_RASE_AP_NO_ACCESS (0x0 << MPU_RASR_AP_Pos)
- #define MPU_DEFS_RASE_AP_PRIV_RW (0x1 << MPU_RASR_AP_Pos)
- #define MPU_DEFS_RASE_AP_PRIV_RW_USER_RO (0x2 << MPU_RASR_AP_Pos)
- #define MPU_DEFS_RASE_AP_FULL_ACCESS (0x3 << MPU_RASR_AP_Pos)
- #define MPU_DEFS_RASE_AP_PRIV_RO (0x5 << MPU_RASR_AP_Pos)
- #define MPU_DEFS_RASE_AP_RO (0x6 << MPU_RASR_AP_Pos)
- #define MPU_DEFS_NORMAL_MEMORY_WT (MPU_RASR_C_Msk)
- #define MPU_DEFS_NORMAL_MEMORY_WB (MPU_RASR_C_Msk | MPU_RASR_B_Msk)
- #define MPU_DEFS_NORMAL_SHARED_MEMORY_WT (MPU_RASR_C_Msk | MPU_RASR_S_Msk)
- #define MPU_DEFS_NORMAL_SHARED_MEMORY_WB (MPU_DEFS_NORMAL_MEMORY_WB | MPU_RASR_S_Msk)
- #define MPU_DEFS_SHARED_DEVICE (MPU_RASR_B_Msk | MPU_RASR_S_Msk)
- #define MPU_DEFS_STRONGLY_ORDERED_DEVICE (0x0)
-
- #define LOOP_COUNT 0x3FFFFF
-
- /* 仅允许本文件内调用的函数声明 */
- static void PrintfLogo(void);
- static int mpu_setup(void);
- static void Delay(uint32_t nCount);
-
- /*
- *******************************************************************************************
- * 函 数 名: main
- * 功能说明: c程序入口
- * 形 参:无
- * 返 回 值: 错误代码(无需处理)
- *******************************************************************************************
- */
- int main(void)
- {
- //(在Cortex-M3 r1p1中推荐使用, 在Cortex-M3 r2px 和 Cortex-M4中默认支持)
- SCB->CCR |= SCB_CCR_STKALIGN_Msk; // 使能堆栈的双字对齐模式
- SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; // 使能 MemManage fault
-
- bsp_InitUart();
- PrintfLogo();
- bsp_InitLed(); /* 初始LED指示灯端口 */
- mpu_setup();
-
- /* 进入主程序循环体 */
- while (1)
- {
- bsp_LedToggle(1);
- bsp_LedToggle(3);
- Delay(LOOP_COUNT);
- }
- }
-
- /*
- *******************************************************************************************
- * 函 数 名: Delay
- * 功能说明: nCount 延迟
- * 形 参:无
- * 返 回 值: 无
- *******************************************************************************************
- */
- static void Delay(uint32_t nCount)
- {
- while(nCount--)
- {
- __DSB();
- }
- }
复制代码
|