硬汉嵌入式论坛

 找回密码
 立即注册
查看: 6919|回复: 3
收起左侧

[μCOS-III] 【uCOS-III教程】第6章   内存保护单元MPU

[复制链接]

740

主题

1326

回帖

3546

积分

管理员

春暖花开

Rank: 9Rank: 9Rank: 9

积分
3546
QQ
发表于 2014-12-12 11:57:00 | 显示全部楼层 |阅读模式
第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的配置相对比较容易,前提是一定要看权威指南上面对这个的介绍。
/*
*******************************************************************************************
*       : 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 outstandingtransfers are done
         
         /* 禁止MPU */
         MPU->CTRL = 0;  

    /* 配置MPU4region */      
         for (i=0;i<4;i++)
         {           
                   MPU->RNR  = i;                 // 选择配置那个region
                   MPU->RBAR =mpu_cfg_rbar;   // 配置地址
                   MPU->RASR =mpu_cfg_rasr;   // 配置属性和大小
         }
         
         /* 下面的配置,相当于禁止*/
         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 updatesettings
}
2.    主程序
        主程序的功能也比较的简单,就是实现LED的闪烁。
#defineMPU_DEFS_RASR_SIZE_32B   (0x04 <<MPU_RASR_SIZE_Pos)
#define MPU_DEFS_RASR_SIZE_64B   (0x05 << MPU_RASR_SIZE_Pos)
#defineMPU_DEFS_RASR_SIZE_128B  (0x06 <<MPU_RASR_SIZE_Pos)
#defineMPU_DEFS_RASR_SIZE_256B  (0x07 <<MPU_RASR_SIZE_Pos)
#defineMPU_DEFS_RASR_SIZE_512B  (0x08 <<MPU_RASR_SIZE_Pos)
#defineMPU_DEFS_RASR_SIZE_1KB   (0x09 <<MPU_RASR_SIZE_Pos)
#defineMPU_DEFS_RASR_SIZE_2KB   (0x0A <<MPU_RASR_SIZE_Pos)
#defineMPU_DEFS_RASR_SIZE_4KB   (0x0B <<MPU_RASR_SIZE_Pos)
#defineMPU_DEFS_RASR_SIZE_8KB   (0x0C <<MPU_RASR_SIZE_Pos)
#defineMPU_DEFS_RASR_SIZE_16KB  (0x0D <<MPU_RASR_SIZE_Pos)
#defineMPU_DEFS_RASR_SIZE_32KB  (0x0E <<MPU_RASR_SIZE_Pos)
#defineMPU_DEFS_RASR_SIZE_64KB  (0x0F <<MPU_RASR_SIZE_Pos)
#defineMPU_DEFS_RASR_SIZE_128KB (0x10 << MPU_RASR_SIZE_Pos)
#defineMPU_DEFS_RASR_SIZE_256KB (0x11 << MPU_RASR_SIZE_Pos)
#defineMPU_DEFS_RASR_SIZE_512KB (0x12 << MPU_RASR_SIZE_Pos)
#defineMPU_DEFS_RASR_SIZE_1MB   (0x13 <<MPU_RASR_SIZE_Pos)
#defineMPU_DEFS_RASR_SIZE_2MB   (0x14 <<MPU_RASR_SIZE_Pos)
#defineMPU_DEFS_RASR_SIZE_4MB   (0x15 <<MPU_RASR_SIZE_Pos)
#defineMPU_DEFS_RASR_SIZE_8MB   (0x16 <<MPU_RASR_SIZE_Pos)
#defineMPU_DEFS_RASR_SIZE_16MB  (0x17 <<MPU_RASR_SIZE_Pos)
#defineMPU_DEFS_RASR_SIZE_32MB  (0x18 <<MPU_RASR_SIZE_Pos)
#defineMPU_DEFS_RASR_SIZE_64MB  (0x19 <<MPU_RASR_SIZE_Pos)
#defineMPU_DEFS_RASR_SIZE_128MB (0x1A << MPU_RASR_SIZE_Pos)
#defineMPU_DEFS_RASR_SIZE_256MB (0x1B << MPU_RASR_SIZE_Pos)
#defineMPU_DEFS_RASR_SIZE_512MB (0x1C << MPU_RASR_SIZE_Pos)
#defineMPU_DEFS_RASR_SIZE_1GB   (0x1D <<MPU_RASR_SIZE_Pos)
#defineMPU_DEFS_RASR_SIZE_2GB   (0x1E <<MPU_RASR_SIZE_Pos)
#defineMPU_DEFS_RASR_SIZE_4GB   (0x1F <<MPU_RASR_SIZE_Pos)
#defineMPU_DEFS_RASE_AP_NO_ACCESS       (0x0<< MPU_RASR_AP_Pos)
#defineMPU_DEFS_RASE_AP_PRIV_RW         (0x1<< MPU_RASR_AP_Pos)
#defineMPU_DEFS_RASE_AP_PRIV_RW_USER_RO (0x2 << MPU_RASR_AP_Pos)
#defineMPU_DEFS_RASE_AP_FULL_ACCESS     (0x3<< MPU_RASR_AP_Pos)
#defineMPU_DEFS_RASE_AP_PRIV_RO         (0x5<< MPU_RASR_AP_Pos)
#defineMPU_DEFS_RASE_AP_RO              (0x6<< MPU_RASR_AP_Pos)
#define MPU_DEFS_NORMAL_MEMORY_WT        (MPU_RASR_C_Msk)
#defineMPU_DEFS_NORMAL_MEMORY_WB       (MPU_RASR_C_Msk | MPU_RASR_B_Msk)
#defineMPU_DEFS_NORMAL_SHARED_MEMORY_WT (MPU_RASR_C_Msk | MPU_RASR_S_Msk)
#defineMPU_DEFS_NORMAL_SHARED_MEMORY_WB (MPU_DEFS_NORMAL_MEMORY_WB | MPU_RASR_S_Msk)
#defineMPU_DEFS_SHARED_DEVICE          (MPU_RASR_B_Msk | MPU_RASR_S_Msk)
#defineMPU_DEFS_STRONGLY_ORDERED_DEVICE (0x0)

#defineLOOP_COUNT 0x3FFFFF      

/* 仅允许本文件内调用的函数声明 */
static voidPrintfLogo(void);
static int mpu_setup(void);
static voidDelay(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_tnCount)
{
         while(nCount--)
         {
                   __DSB();
         }
}
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的配置相对比较容易,前提是一定要看权威指南上面对这个的介绍。
/*
*******************************************************************************************
*       : mpu_setup
*       功能说明: mpu配置
*           参:无
*       :
*******************************************************************************************
*/
static intmpu_setup(void)
{
         uint32_t i;
         
         uint32_t const mpu_cfg_rbar[4] =
         {
                     // Flash - region 0
                   (0x08000000 |MPU_RBAR_VALID_Msk | (MPU_RBAR_REGION_Msk & 0)),
                   // SRAM  - region 1
                   (0x20000000 |MPU_RBAR_VALID_Msk | (MPU_RBAR_REGION_Msk & 1)),
                   // GPIO D base address -region 2
                   (GPIOF_BASE |MPU_RBAR_VALID_Msk | (MPU_RBAR_REGION_Msk & 2)),
                   // Reset Clock CTRL baseaddress - region 3
                   (RCC_BASE   | MPU_RBAR_VALID_Msk | (MPU_RBAR_REGION_Msk& 3))
         };
         
         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 outstandingtransfers are done
         
         /* 禁止MPU */
         MPU->CTRL = 0;  

    /* 配置MPU4region */      
         for (i=0;i<4;i++)
         {           
                   MPU->RNR  = i;                 // 选择配置那个region
                   MPU->RBAR =mpu_cfg_rbar;   // 配置地址
                   MPU->RASR =mpu_cfg_rasr;   // 配置属性和大小
         }
         
         /* 下面的配置,相当于禁止其余的4region */
         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 updatesettings
}
2.    主程序
        主程序的功能也比较的简单,就是实现LED的闪烁。
#defineMPU_DEFS_RASR_SIZE_32B   (0x04 <<MPU_RASR_SIZE_Pos)
#defineMPU_DEFS_RASR_SIZE_64B   (0x05 <<MPU_RASR_SIZE_Pos)
#defineMPU_DEFS_RASR_SIZE_128B  (0x06 <<MPU_RASR_SIZE_Pos)
#defineMPU_DEFS_RASR_SIZE_256B  (0x07 <<MPU_RASR_SIZE_Pos)
#defineMPU_DEFS_RASR_SIZE_512B  (0x08 <<MPU_RASR_SIZE_Pos)
#defineMPU_DEFS_RASR_SIZE_1KB   (0x09 <<MPU_RASR_SIZE_Pos)
#defineMPU_DEFS_RASR_SIZE_2KB   (0x0A <<MPU_RASR_SIZE_Pos)
#defineMPU_DEFS_RASR_SIZE_4KB   (0x0B << MPU_RASR_SIZE_Pos)
#defineMPU_DEFS_RASR_SIZE_8KB   (0x0C <<MPU_RASR_SIZE_Pos)
#defineMPU_DEFS_RASR_SIZE_16KB  (0x0D <<MPU_RASR_SIZE_Pos)
#defineMPU_DEFS_RASR_SIZE_32KB  (0x0E <<MPU_RASR_SIZE_Pos)
#defineMPU_DEFS_RASR_SIZE_64KB  (0x0F <<MPU_RASR_SIZE_Pos)
#defineMPU_DEFS_RASR_SIZE_128KB (0x10 << MPU_RASR_SIZE_Pos)
#defineMPU_DEFS_RASR_SIZE_256KB (0x11 << MPU_RASR_SIZE_Pos)
#defineMPU_DEFS_RASR_SIZE_512KB (0x12 << MPU_RASR_SIZE_Pos)
#defineMPU_DEFS_RASR_SIZE_1MB   (0x13 <<MPU_RASR_SIZE_Pos)
#defineMPU_DEFS_RASR_SIZE_2MB   (0x14 <<MPU_RASR_SIZE_Pos)
#defineMPU_DEFS_RASR_SIZE_4MB   (0x15 <<MPU_RASR_SIZE_Pos)
#defineMPU_DEFS_RASR_SIZE_8MB   (0x16 <<MPU_RASR_SIZE_Pos)
#defineMPU_DEFS_RASR_SIZE_16MB  (0x17 <<MPU_RASR_SIZE_Pos)
#defineMPU_DEFS_RASR_SIZE_32MB  (0x18 <<MPU_RASR_SIZE_Pos)
#defineMPU_DEFS_RASR_SIZE_64MB  (0x19 <<MPU_RASR_SIZE_Pos)
#defineMPU_DEFS_RASR_SIZE_128MB (0x1A << MPU_RASR_SIZE_Pos)
#defineMPU_DEFS_RASR_SIZE_256MB (0x1B << MPU_RASR_SIZE_Pos)
#defineMPU_DEFS_RASR_SIZE_512MB (0x1C << MPU_RASR_SIZE_Pos)
#defineMPU_DEFS_RASR_SIZE_1GB   (0x1D <<MPU_RASR_SIZE_Pos)
#defineMPU_DEFS_RASR_SIZE_2GB   (0x1E <<MPU_RASR_SIZE_Pos)
#defineMPU_DEFS_RASR_SIZE_4GB   (0x1F <<MPU_RASR_SIZE_Pos)
#defineMPU_DEFS_RASE_AP_NO_ACCESS       (0x0<< MPU_RASR_AP_Pos)
#defineMPU_DEFS_RASE_AP_PRIV_RW         (0x1<< MPU_RASR_AP_Pos)
#defineMPU_DEFS_RASE_AP_PRIV_RW_USER_RO (0x2 << MPU_RASR_AP_Pos)
#defineMPU_DEFS_RASE_AP_FULL_ACCESS     (0x3<< MPU_RASR_AP_Pos)
#defineMPU_DEFS_RASE_AP_PRIV_RO         (0x5<< MPU_RASR_AP_Pos)
#defineMPU_DEFS_RASE_AP_RO              (0x6<< MPU_RASR_AP_Pos)
#defineMPU_DEFS_NORMAL_MEMORY_WT       (MPU_RASR_C_Msk)
#defineMPU_DEFS_NORMAL_MEMORY_WB       (MPU_RASR_C_Msk | MPU_RASR_B_Msk)
#defineMPU_DEFS_NORMAL_SHARED_MEMORY_WT (MPU_RASR_C_Msk | MPU_RASR_S_Msk)
#defineMPU_DEFS_NORMAL_SHARED_MEMORY_WB (MPU_DEFS_NORMAL_MEMORY_WB | MPU_RASR_S_Msk)
#defineMPU_DEFS_SHARED_DEVICE          (MPU_RASR_B_Msk | MPU_RASR_S_Msk)
#defineMPU_DEFS_STRONGLY_ORDERED_DEVICE (0x0)

#defineLOOP_COUNT 0x3FFFFF      

/* 仅允许本文件内调用的函数声明 */
static voidPrintfLogo(void);
static intmpu_setup(void);
static voidDelay(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 voidDelay(uint32_t nCount)
{
         while(nCount--)
         {
                   __DSB();
         }
}

努力打造安富莱高质量微信公众号:点击扫描图片关注
回复

使用道具 举报

740

主题

1326

回帖

3546

积分

管理员

春暖花开

Rank: 9Rank: 9Rank: 9

积分
3546
QQ
 楼主| 发表于 2014-12-12 12:07:11 | 显示全部楼层
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的配置
        这里将相关的函数进行了专门的配置,方便用户进行调用。
#defineMPU_DEFS_RASR_SIZE_32B   (0x04 <<MPU_RASR_SIZE_Pos)
#define MPU_DEFS_RASR_SIZE_64B   (0x05 << MPU_RASR_SIZE_Pos)
#defineMPU_DEFS_RASR_SIZE_128B  (0x06 <<MPU_RASR_SIZE_Pos)
#defineMPU_DEFS_RASR_SIZE_256B  (0x07 <<MPU_RASR_SIZE_Pos)
#defineMPU_DEFS_RASR_SIZE_512B  (0x08 <<MPU_RASR_SIZE_Pos)
#defineMPU_DEFS_RASR_SIZE_1KB   (0x09 <<MPU_RASR_SIZE_Pos)
#defineMPU_DEFS_RASR_SIZE_2KB   (0x0A <<MPU_RASR_SIZE_Pos)
#defineMPU_DEFS_RASR_SIZE_4KB   (0x0B <<MPU_RASR_SIZE_Pos)
#defineMPU_DEFS_RASR_SIZE_8KB   (0x0C <<MPU_RASR_SIZE_Pos)
#defineMPU_DEFS_RASR_SIZE_16KB  (0x0D <<MPU_RASR_SIZE_Pos)
#defineMPU_DEFS_RASR_SIZE_32KB  (0x0E <<MPU_RASR_SIZE_Pos)
#defineMPU_DEFS_RASR_SIZE_64KB  (0x0F <<MPU_RASR_SIZE_Pos)
#defineMPU_DEFS_RASR_SIZE_128KB (0x10 << MPU_RASR_SIZE_Pos)
#defineMPU_DEFS_RASR_SIZE_256KB (0x11 << MPU_RASR_SIZE_Pos)
#defineMPU_DEFS_RASR_SIZE_512KB (0x12 << MPU_RASR_SIZE_Pos)
#defineMPU_DEFS_RASR_SIZE_1MB   (0x13 <<MPU_RASR_SIZE_Pos)
#defineMPU_DEFS_RASR_SIZE_2MB   (0x14 <<MPU_RASR_SIZE_Pos)
#defineMPU_DEFS_RASR_SIZE_4MB   (0x15 << MPU_RASR_SIZE_Pos)
#defineMPU_DEFS_RASR_SIZE_8MB   (0x16 <<MPU_RASR_SIZE_Pos)
#defineMPU_DEFS_RASR_SIZE_16MB  (0x17 <<MPU_RASR_SIZE_Pos)
#defineMPU_DEFS_RASR_SIZE_32MB  (0x18 <<MPU_RASR_SIZE_Pos)
#defineMPU_DEFS_RASR_SIZE_64MB  (0x19 <<MPU_RASR_SIZE_Pos)
#defineMPU_DEFS_RASR_SIZE_128MB (0x1A << MPU_RASR_SIZE_Pos)
#defineMPU_DEFS_RASR_SIZE_256MB (0x1B << MPU_RASR_SIZE_Pos)
#defineMPU_DEFS_RASR_SIZE_512MB (0x1C << MPU_RASR_SIZE_Pos)
#defineMPU_DEFS_RASR_SIZE_1GB   (0x1D <<MPU_RASR_SIZE_Pos)
#defineMPU_DEFS_RASR_SIZE_2GB   (0x1E <<MPU_RASR_SIZE_Pos)
#defineMPU_DEFS_RASR_SIZE_4GB   (0x1F <<MPU_RASR_SIZE_Pos)
#defineMPU_DEFS_RASE_AP_NO_ACCESS       (0x0<< MPU_RASR_AP_Pos)
#defineMPU_DEFS_RASE_AP_PRIV_RW         (0x1<< MPU_RASR_AP_Pos)
#defineMPU_DEFS_RASE_AP_PRIV_RW_USER_RO (0x2 << MPU_RASR_AP_Pos)
#defineMPU_DEFS_RASE_AP_FULL_ACCESS     (0x3<< MPU_RASR_AP_Pos)
#defineMPU_DEFS_RASE_AP_PRIV_RO         (0x5<< MPU_RASR_AP_Pos)
#defineMPU_DEFS_RASE_AP_RO              (0x6<< MPU_RASR_AP_Pos)
#defineMPU_DEFS_NORMAL_MEMORY_WT       (MPU_RASR_C_Msk)
#defineMPU_DEFS_NORMAL_MEMORY_WB       (MPU_RASR_C_Msk | MPU_RASR_B_Msk)
#defineMPU_DEFS_NORMAL_SHARED_MEMORY_WT (MPU_RASR_C_Msk | MPU_RASR_S_Msk)
#defineMPU_DEFS_NORMAL_SHARED_MEMORY_WB (MPU_DEFS_NORMAL_MEMORY_WB | MPU_RASR_S_Msk)
#defineMPU_DEFS_SHARED_DEVICE          (MPU_RASR_B_Msk | MPU_RASR_S_Msk)
#defineMPU_DEFS_STRONGLY_ORDERED_DEVICE (0x0)
/*************************************************/
voidmpu_region_config(uint32_t region_num, uint32_t addr, uint32_t size, uint32_tattributes);
voidmpu_enable(uint32_t options);
voidmpu_disable(void);
voidmpu_region_disable(uint32_t region_num);
/*
*******************************************************************************************
*       : bsp_InitMPU
*       功能说明: 内存保护单元初始化
*           :
*       : 0 表示失败,1 表示成功
*******************************************************************************************
*/
uint8_tbsp_InitMPU(void)
{
         if (MPU->TYPE==0)
         {
                   return 0;
         }
    /* 第一步要先禁止MPU再进行相应的设置 */   
         mpu_disable();
         
         /* 设置MPU8Region */
         /* 配置Region 0 - Flash*/
         mpu_region_config(0, 0x08000000,MPU_DEFS_RASR_SIZE_1MB,
         MPU_DEFS_NORMAL_MEMORY_WT |MPU_DEFS_RASE_AP_FULL_ACCESS |
         MPU_RASR_ENABLE_Msk),
         /* 配置Region 1 - SRAM*/
         mpu_region_config(1, 0x20000000,MPU_DEFS_RASR_SIZE_128KB,
         MPU_DEFS_NORMAL_MEMORY_WT |MPU_DEFS_RASE_AP_FULL_ACCESS |
         MPU_RASR_ENABLE_Msk),
         /* 配置Region 2 - GPIOD */
         mpu_region_config(2, GPIOF_BASE,MPU_DEFS_RASR_SIZE_1KB,
         MPU_DEFS_SHARED_DEVICE    |MPU_DEFS_RASE_AP_FULL_ACCESS |
         MPU_RASR_ENABLE_Msk),
         /* 配置Region 3 - ResetClock CTRL */
         mpu_region_config(3, RCC_BASE,MPU_DEFS_RASR_SIZE_1KB,
         MPU_DEFS_SHARED_DEVICE    | MPU_DEFS_RASE_AP_FULL_ACCESS |
         MPU_RASR_ENABLE_Msk),  
         /* 禁止Region 4 */
         mpu_region_disable(4);
         /* 禁止Region 5 */
         mpu_region_disable(5);
         /* 禁止Region 6 */
         mpu_region_disable(6);
         /* 禁止Region 7 */
         mpu_region_disable(7);
         
         /* 使能允许MPU */
         mpu_enable(0);
         
         return 1;
}
/*
*******************************************************************************************
*       : mpu_enable
*       功能说明: mpu使能,mpu控制寄存器有3位,功能分别如下:
*             2  PRIVDEFENA 是否为特权级打开缺省存储器映射(即背景
*                             region)。
*                             1 = 特权级下打开背景region
*                             0 = 不打开背景region。任何访问违例以及对
*                                 region外地址区的访问都将引起fault
*             1  HFNMIENA  1=NMI和硬fault服务例程中不强制除能MPU
*                             0=NMI和硬fault服务例程中强制除能MPU
*             0  ENABLE    使能或者禁止
*           : options  MPU_CTRL_HFNMIENA_Msk或者MPU_CTRL_PRIVDEFENA_Msk
*       :
*******************************************************************************************
*/
voidmpu_enable(uint32_t options)
{
         MPU->CTRL = MPU_CTRL_ENABLE_Msk |options;  
         __DSB();  // Ensure MPU settings take effects
         __ISB();  // Sequence instruction fetches using updatesettings
}
/*
*******************************************************************************************
*       : mpu_disable
*       功能说明: 禁止mpu
*           :
*       :
*******************************************************************************************
*/
voidmpu_disable(void)
{
         __DMB();            // Make sure outstanding transfersare done
         MPU->CTRL = 0;      // Disable the MPU
}
/*
*******************************************************************************************
*       :mpu_region_disable
*       功能说明: 禁止mpu谋一个region
*           :region_num  范围0 - 7
*       :
*******************************************************************************************
*/
voidmpu_region_disable(uint32_t region_num)
{
         MPU->RNR  = region_num;
         MPU->RBAR = 0;
         MPU->RASR = 0;
}      
/*
*******************************************************************************************
*       :mpu_region_config
*       功能说明: mpu配置
*           :region_num  范围0 - 7
*             addr  地址
*             size  大小
*             attributes 属性
*       :
*******************************************************************************************
*/
void mpu_region_config(uint32_tregion_num, uint32_t addr, uint32_t size, uint32_t attributes)
{
         MPU->RNR  = region_num;
         MPU->RBAR = addr;
         MPU->RASR = size | attributes;
}
2.    主程序
/* 仅允许本文件内调用的函数声明 */
static voidPrintfLogo(void);
static voidDelay(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_Init();               /* 硬件初始化 */
         /* 进入主程序循环体 */
         while (1)
         {
                   bsp_LedToggle(1);
                   bsp_LedToggle(3);
                   Delay(LOOP_COUNT);
         }
}
/*
*******************************************************************************************
*       : Delay
*       功能说明: nCount 延迟
*           参:无
*       :
*/
static voidDelay(uint32_t nCount)
{
         while(nCount--)
         {
                   __DSB();
         }
}
6.3  实验总结
          本期教程相对来说也比较的重要,希望初学RTOS的同学认真的学习。
参考资料:
1.    Patterns fortime-triggered embedded systems英文版和中文版
2.    Cortex-M3权威指南中文版
3.    TheDefinitive Guide to Arm Cortex-M3 and Cortex-M4 Processors(M4权威指南)
努力打造安富莱高质量微信公众号:点击扫描图片关注
回复

使用道具 举报

740

主题

1326

回帖

3546

积分

管理员

春暖花开

Rank: 9Rank: 9Rank: 9

积分
3546
QQ
 楼主| 发表于 2014-12-12 13:03:28 | 显示全部楼层
[s:152] [s:152] [s:152]
努力打造安富莱高质量微信公众号:点击扫描图片关注
回复

使用道具 举报

6

主题

90

回帖

108

积分

初级会员

积分
108
QQ
发表于 2014-12-20 08:47:23 | 显示全部楼层
这里的大师都很厉害,但是为嘛老是我在坐沙发
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2025-5-11 19:31 , Processed in 0.254970 second(s), 27 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表