251 lines
10 KiB
C
251 lines
10 KiB
C
#ifndef INCLUDED_OS_MPU_H
|
|
#define INCLUDED_OS_MPU_H
|
|
|
|
#ifndef INCLUDED_OS_TYPES_H
|
|
#include <os_types.h>
|
|
#endif /*INCLUDED_OS_TYPES_H*/
|
|
|
|
#ifndef INCLUDED_OS_COMPILER_H
|
|
#include <os_compiler.h>
|
|
#endif /*INCLUDED_OS_COMPILER_H*/
|
|
|
|
#ifndef INCLUDED_CMSIS_H
|
|
#include <cmsis.h>
|
|
#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<<OS_MPU_RASR_SIZE_Pos)
|
|
#define OS_MPU_DEFS_RASR_SIZE_64B (0x05<<OS_MPU_RASR_SIZE_Pos)
|
|
#define OS_MPU_DEFS_RASR_SIZE_128B (0x06<<OS_MPU_RASR_SIZE_Pos)
|
|
#define OS_MPU_DEFS_RASR_SIZE_256B (0x07<<OS_MPU_RASR_SIZE_Pos)
|
|
#define OS_MPU_DEFS_RASR_SIZE_512B (0x08<<OS_MPU_RASR_SIZE_Pos)
|
|
#define OS_MPU_DEFS_RASR_SIZE_1KB (0x09<<OS_MPU_RASR_SIZE_Pos)
|
|
#define OS_MPU_DEFS_RASR_SIZE_2KB (0x0A<<OS_MPU_RASR_SIZE_Pos)
|
|
#define OS_MPU_DEFS_RASR_SIZE_4KB (0x0B<<OS_MPU_RASR_SIZE_Pos)
|
|
#define OS_MPU_DEFS_RASR_SIZE_8KB (0x0C<<OS_MPU_RASR_SIZE_Pos)
|
|
#define OS_MPU_DEFS_RASR_SIZE_16KB (0x0D<<OS_MPU_RASR_SIZE_Pos)
|
|
#define OS_MPU_DEFS_RASR_SIZE_32KB (0x0E<<OS_MPU_RASR_SIZE_Pos)
|
|
#define OS_MPU_DEFS_RASR_SIZE_64KB (0x0F<<OS_MPU_RASR_SIZE_Pos)
|
|
#define OS_MPU_DEFS_RASR_SIZE_128KB (0x10<<OS_MPU_RASR_SIZE_Pos)
|
|
#define OS_MPU_DEFS_RASR_SIZE_256KB (0x11<<OS_MPU_RASR_SIZE_Pos)
|
|
#define OS_MPU_DEFS_RASR_SIZE_512KB (0x12<<OS_MPU_RASR_SIZE_Pos)
|
|
#define OS_MPU_DEFS_RASR_SIZE_1MB (0x13<<OS_MPU_RASR_SIZE_Pos)
|
|
#define OS_MPU_DEFS_RASR_SIZE_2MB (0x14<<OS_MPU_RASR_SIZE_Pos)
|
|
#define OS_MPU_DEFS_RASR_SIZE_4MB (0x15<<OS_MPU_RASR_SIZE_Pos)
|
|
#define OS_MPU_DEFS_RASR_SIZE_8MB (0x16<<OS_MPU_RASR_SIZE_Pos)
|
|
#define OS_MPU_DEFS_RASR_SIZE_16MB (0x17<<OS_MPU_RASR_SIZE_Pos)
|
|
#define OS_MPU_DEFS_RASR_SIZE_32MB (0x18<<OS_MPU_RASR_SIZE_Pos)
|
|
#define OS_MPU_DEFS_RASR_SIZE_64MB (0x19<<OS_MPU_RASR_SIZE_Pos)
|
|
#define OS_MPU_DEFS_RASR_SIZE_128MB (0x1A<<OS_MPU_RASR_SIZE_Pos)
|
|
#define OS_MPU_DEFS_RASR_SIZE_256MB (0x1B<<OS_MPU_RASR_SIZE_Pos)
|
|
#define OS_MPU_DEFS_RASR_SIZE_512MB (0x1C<<OS_MPU_RASR_SIZE_Pos)
|
|
#define OS_MPU_DEFS_RASR_SIZE_1GB (0x1D<<OS_MPU_RASR_SIZE_Pos)
|
|
#define OS_MPU_DEFS_RASR_SIZE_2GB (0x1E<<OS_MPU_RASR_SIZE_Pos)
|
|
#define OS_MPU_DEFS_RASR_SIZE_4GB (0x1F<<OS_MPU_RASR_SIZE_Pos)
|
|
|
|
|
|
#define OS_MPU_DEFS_RASR_AP_NO_ACCESS (0x0 << OS_MPU_RASR_AP_Pos)
|
|
#define OS_MPU_DEFS_RASR_AP_PRIV_RW (0x1 << OS_MPU_RASR_AP_Pos)
|
|
#define OS_MPU_DEFS_RASR_AP_PRIV_RW_USER_RO (0x2 << OS_MPU_RASR_AP_Pos)
|
|
#define OS_MPU_DEFS_RASR_AP_PRIV_FULL_ACCESS (0x3 << OS_MPU_RASR_AP_Pos)
|
|
#define OS_MPU_DEFS_RASR_AP_PRIV_RO (0x5 << OS_MPU_RASR_AP_Pos)
|
|
#define OS_MPU_DEFS_RASR_AP_RO (0x6 << OS_MPU_RASR_AP_Pos)
|
|
|
|
#define OS_MPU_RASR_B_Msk (1<<OS_MPU_RASR_B_Pos)
|
|
#define OS_MPU_RASR_C_Msk (1<<OS_MPU_RASR_C_Pos)
|
|
#define OS_MPU_RASR_S_Msk (1<<OS_MPU_RASR_S_Pos)
|
|
#define OS_MPU_RASR_TEX_Msk (0x7<<OS_MPU_RASR_TEX_Pos)
|
|
#define OS_MPU_RASR_SIZE_Msk (0x1f<<OS_MPU_RASR_SIZE_Pos)
|
|
#define OS_MPU_RASR_ENABLE_Msk (0x1<<OS_MPU_RASR_ENABLE_Pos)
|
|
#define OS_MPU_RASR_XN_Msk (0x1<<OS_MPU_RASR_XN_Pos)
|
|
#define OS_MPU_RASR_SRD_Msk (0xff<<OS_MPU_RASR_SRD_Pos)
|
|
|
|
#define OS_MPU_DEFS_RASR_SRD_DISABLE (0x00 << OS_MPU_RASR_SRD_Pos)
|
|
|
|
#define OS_MPU_DEFS_RASR_TEX_LEVEL0 (0x0 << OS_MPU_RASR_TEX_Pos)
|
|
#define OS_MPU_DEFS_RASR_TEX_LEVEL1 (0x1 << OS_MPU_RASR_TEX_Pos)
|
|
#define OS_MPU_DEFS_RASR_TEX_LEVEL2 (0x2 << OS_MPU_RASR_TEX_Pos)
|
|
|
|
#define OS_MPU_DEFS_NORMAL_MEMORY_WT (OS_MPU_RASR_C_Msk)
|
|
#define OS_MPU_DEFS_NORMAL_MEMORY_WB (OS_MPU_RASR_C_Msk | OS_MPU_RASR_B_Msk)
|
|
#define OS_MPU_DEFS_NORMAL_MEMORY_SHARED_WT (OS_MPU_RASR_C_Msk | OS_MPU_RASR_S_Msk)
|
|
#define OS_MPU_DEFS_NORMAL_MEMORY_SHARED_WB (OS_MPU_DEFS_NORMAL_MEMORY_WB | OS_MPU_RASR_S_Msk)
|
|
#define OS_MPU_DEFS_SHARED_DEVICE (OS_MPU_RASR_B_Msk | OS_MPU_RASR_S_Msk)
|
|
#define OS_MPU_DEFS_EXTERNAL_MEMORY (OS_MPU_RASR_C_Msk | OS_MPU_RASR_B_Msk | OS_MPU_RASR_S_Msk)
|
|
#define OS_MPU_DEFS_STRONGLY_ORDERED_DEVICE (0x0)
|
|
|
|
#define OS_MPU_ACCESS_CACHEABLE (OS_MPU_RASR_C_Msk)
|
|
#define OS_MPU_ACCESS_BUFFERABLE (OS_MPU_RASR_B_Msk)
|
|
#define OS_MPU_ACCESS_SHAREABLE (OS_MPU_RASR_S_Msk)
|
|
|
|
#define OS_MPU_ACCESS_NOT_CACHEABLE (0x00 << OS_MPU_RASR_C_Pos)
|
|
#define OS_MPU_ACCESS_NOT_BUFFERABLE (0x00 << OS_MPU_RASR_B_Pos)
|
|
#define OS_MPU_ACCESS_NOT_SHAREABLE (0x00 << OS_MPU_RASR_S_Pos)
|
|
|
|
#define OS_MPU_CTRL_ENABLE_Pos (0)
|
|
#define OS_MPU_CTRL_HFNMIENA_Pos (1)
|
|
#define OS_MPU_CTRL_PRIVDEFENA_Pos (2)
|
|
|
|
#define OS_MPU_CTRL_ENABLE_Msk (1<<OS_MPU_CTRL_ENABLE_Pos)
|
|
#define OS_MPU_CTRL_HFNMIENA_Msk (1<<OS_MPU_CTRL_HFNMIENA_Pos)
|
|
#define OS_MPU_CTRL_PRIVDEFENA_Msk (1<<OS_MPU_CTRL_PRIVDEFENA_Pos)
|
|
|
|
|
|
#define OS_MPU_RBAR_REGION_Pos 0
|
|
#define OS_MPU_RBAR_VALID_Pos 4
|
|
|
|
#define OS_MPU_RBAR_VALID_Msk (1<<OS_MPU_RBAR_VALID_Pos)
|
|
#define OS_MPU_RBAR_REGION_Msk (0xf << OS_MPU_RBAR_REGION_Pos)
|
|
|
|
#define OS_MPU_DEFS_RBAR_VALID_DISABLE (0<<OS_MPU_RBAR_VALID_Pos)
|
|
|
|
/* ------------------------------------------------------------------------------------------------------------------ */
|
|
/* */
|
|
|
|
OS_STATIC_FORCE_INLINE
|
|
void os_mpu_enable(os_uint_t options){
|
|
OS_MPU->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*/
|