#ifndef INCLUDED_OS_MPU_H #define INCLUDED_OS_MPU_H #ifndef INCLUDED_OS_TYPES_H #include #endif /*INCLUDED_OS_TYPES_H*/ #ifndef INCLUDED_OS_COMPILER_H #include #endif /*INCLUDED_OS_COMPILER_H*/ #ifndef INCLUDED_CMSIS_H #include #endif /*INCLUDED_CMSIS_H*/ /* ------------------------------------------------------------------------------------------------------------------ */ /* */ typedef struct { os_uintptr_t TYPE; /* 提供 MPU 信息 */ os_uintptr_t CTRL; /* MPU使能/禁止的背景区域控制 */ os_uintptr_t RNR; /* 选择待配置的MPU区域 */ os_uintptr_t RBAR; /* 定义MPU区域的基地址 */ os_uintptr_t RASR; /* 定义MPU区域的属性和大小 */ os_uintptr_t RBAR_A1; /* RBAR的别名 */ os_uintptr_t RBSR_A1; /* RASR的别名 */ os_uintptr_t RBAR_A2; /* RBAR的别名 */ os_uintptr_t RBSR_A2; /* RASR的别名 */ os_uintptr_t RBAR_A3; /* RBAR的别名 */ os_uintptr_t RBSR_A3; /* RASR的别名 */ }os_mpu_t; #define OS_MPU ((os_mpu_t*)(0xE000ED90u)) OS_PACKED_STRUCT(os_mpu_type_t){ os_uint_t SEPARATE:1; os_uint_t RESERVED_0:7; os_uint_t DREGION:8; os_uint_t IREGION:8; os_uint_t RESERVED_1:8; }os_mpu_type_t; OS_PACKED_STRUCT(os_mpu_ctrl_t){ os_uint_t ENABLE:1; os_uint_t HFNMIENA:1; os_uint_t PRIVDEFENA:1; os_uint_t RESERVED:29; }os_mpu_ctrl_t; OS_PACKED_STRUCT(os_mpu_rnr_t){ os_uint_t REGION:8; os_uint_t RESERVED:24; }os_mpu_rnr_t; OS_PACKED_STRUCT(os_mpu_rbar_t){ os_uint_t REGION:4; os_uint_t VALID:1; os_uint_t ADDR:27; }os_mpu_rbar_t; OS_PACKED_STRUCT(os_mpu_rasr_t){ os_uint_t ENABLE:1; /* 区域使能 */ os_uint_t SIZE:5; /* MPU保护区域大小 */ os_uint_t RESERVED_0:2; os_uint_t SRD:8; /* 子区域禁止 */ os_uint_t B:1; /* 可缓冲 */ os_uint_t C:1; /* 可缓存 */ os_uint_t S:1; /* 可共用 */ os_uint_t TEX:3; /* 类型展开域 */ os_uint_t RESERVED_1:2; /* 保留 */ os_uint_t AP:3; /* 数据访问允许域 */ os_uint_t RESERVED_2:1; /* 保留 */ os_uint_t XN:1; /* 指令访问禁止(1=禁止该区域的取值, 非要这么做会引发存储器管理错误) */ os_uint_t RESERVED_3:3; /* 保留 */ }os_mpu_rasr_t; /* ------------------------------------------------------------------------------------------------------------------ */ /* */ #define OS_MPU_RASR_ENABLE_Pos 0 #define OS_MPU_RASR_SIZE_Pos 1 #define OS_MPU_RASR_SRD_Pos 8 #define OS_MPU_RASR_B_Pos 16 #define OS_MPU_RASR_C_Pos 17 #define OS_MPU_RASR_S_Pos 18 #define OS_MPU_RASR_TEX_Pos 19 #define OS_MPU_RASR_AP_Pos 24 #define OS_MPU_RASR_XN_Pos 28 #define OS_MPU_DEFS_RASR_SIZE_32B (0x04<CTRL = OS_MPU_CTRL_ENABLE_Msk | options; CMSIS_DSB(); CMSIS_ISB(); } OS_STATIC_FORCE_INLINE void os_mpu_disable(void){ CMSIS_DMB(); OS_MPU->CTRL = 0; } OS_STATIC_FORCE_INLINE void os_mpu_region_disable(os_uint_t region_num){ OS_MPU->RNR = region_num; OS_MPU->RBAR = 0; OS_MPU->RASR = 0; } OS_STATIC_FORCE_INLINE void os_mpu_region_config(os_uint_t region_num, os_uintptr_t addr, os_size_t size, os_uint_t attribute){ OS_MPU->RNR = region_num; OS_MPU->RBAR = addr; OS_MPU->RASR = ((size << OS_MPU_RASR_SIZE_Pos) & OS_MPU_RASR_SIZE_Msk) | attribute; } /* ------------------------------------------------------------------------------------------------------------------ */ /* Example */ #if 0 /* 以下是 MPU 配置示例 */ int mpu_setup(void){ if(OS_MPU->TYPE == 0){ return 1; /* 错误 */ } os_mpu_disable(); /* 0 - Flash */ os_mpu_region_config(0 , 0x08000000 , OS_MPU_DEFS_RASR_SIZE_1MB , OS_MPU_DEFS_NORMAL_MEMORY_WT | OS_MPU_DEFS_RASR_AP_PRIV_FULL_ACCESS | OS_MPU_RASR_ENABLE_Msk); /* 1 - SRAM */ os_mpu_region_config(1 , 0x20000000 , OS_MPU_DEFS_RASR_SIZE_128KB , OS_MPU_DEFS_NORMAL_MEMORY_WT | OS_MPU_DEFS_RASR_AP_PRIV_FULL_ACCESS | OS_MPU_RASR_ENABLE_Msk); /* 2 - GPIOD */ os_mpu_region_config(2 , GPIOD_BASE , OS_MPU_DEFS_RASR_SIZE_1KB , OS_MPU_DEFS_SHARED_DEVICE | OS_MPU_DEFS_RASR_AP_PRIV_FULL_ACCESS | OS_MPU_RASR_ENABLE_Msk); /* 3 - 复位时钟 */ os_mpu_region_config(3 , RCC_BASE , OS_MPU_DEFS_RASR_SIZE_1KB , OS_MPU_DEFS_SHARED_DEVICE | OS_MPU_DEFS_RASR_AP_PRIV_FULL_ACCESS | OS_MPU_RASR_ENABLE_Msk); os_mpu_region_disable(4); os_mpu_region_disable(5); os_mpu_region_disable(6); os_mpu_region_disable(7); os_mpu_enable(0); /* 使能MPU,无需其它设置 */ return 0; /* 无错误 */ } #endif /* 0 */ #endif /*INCLUDED_OS_MPU_H*/