【简介】
本地集成NXP S32K3 的最新的FreeRTOS V11.1.0 版本已经适配支持了创建任务时添加MPU 的region 配置的功能,我们只需要在S32DS的FreeRTOS的配置界面下开启对应的配置即可。

针对MPU 的说明,此贴(【S32K3XX】MPU 功能验证)(【S32K3XX】Memory 访问默认权限配置)之前有过介绍。
开启配置后 S32DS 编译代码会有如下的link错误。

查看源代码文件,发现配置MPU 会将FreeRTOS 的代码和资源分配不同的属性我们需要在link 文件中添加对应的section 来支持该特性。

#if( configENABLE_MPU == 1 )
void prvSetupMPU(void) {
extern uint32_t __FreeRTOS_privileged_functions_start__[];
extern uint32_t __FreeRTOS_privileged_functions_end__[];
extern uint32_t __FreeRTOS_system_calls_start__[];
extern uint32_t __FreeRTOS_system_calls_end__[];
extern uint32_t __FreeRTOS_privileged_data_start__[];
extern uint32_t __FreeRTOS_privileged_data_end__[];
extern uint32_t __FreeRTOS_code_data_start__[];
extern uint32_t __FreeRTOS_code_data_end__[];
/* The only permitted number of regions are 8 or 16. */
configASSERT( ( configTOTAL_MPU_REGIONS == 8 ) || ( configTOTAL_MPU_REGIONS == 16 ) );
/* Ensure that the configTOTAL_MPU_REGIONS is configured correctly. */
configASSERT( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE );
/* Check the expected MPU is present. */
if( portMPU_TYPE_REG == portEXPECTED_MPU_TYPE_VALUE )
{
__asm volatile ( "dsb" );
__asm volatile ( "isb" );
/* Disable MPU before configuration */
portMPU_CTRL_REG &= ~portMPU_ENABLE;
/* portCODE_DATA_MEMORY_MAP_REGION */
portMPU_REGION_BASE_ADDRESS_REG =
( ( uint32_t ) __FreeRTOS_code_data_start__ ) |
( portMPU_REGION_VALID ) |
( portCODE_DATA_MEMORY_MAP_REGION );
portMPU_REGION_ATTRIBUTE_REG =
( prvGetMPURegionSizeSetting( ( uint32_t ) __FreeRTOS_code_data_end__ - ( uint32_t ) __FreeRTOS_code_data_start__)) |
( portMPU_REGION_READ_WRITE ) |
( ( 0x0BUL & portMPU_RASR_TEX_S_C_B_MASK ) << portMPU_RASR_TEX_S_C_B_LOCATION ) |
( portMPU_REGION_ENABLE );
/* Setup the privileged functions for privileged only access.
* This is where the kernel code is placed. */
portMPU_REGION_BASE_ADDRESS_REG =
( ( uint32_t ) __FreeRTOS_privileged_functions_start__ ) |
( portMPU_REGION_VALID ) |
( portPRIVILEGED_FUNCTIONS_REGION );
portMPU_REGION_ATTRIBUTE_REG =
( prvGetMPURegionSizeSetting( ( uint32_t ) __FreeRTOS_privileged_functions_end__
- ( uint32_t ) __FreeRTOS_privileged_functions_start__ ) ) |
( portMPU_REGION_PRIVILEGED_READ_ONLY ) |
( portMPU_REGION_ENABLE );
/* Setup the system MPU wrappers functions.
* This is where the system FreeRTOS MPU wrappers code is placed. */
portMPU_REGION_BASE_ADDRESS_REG =
( ( uint32_t ) __FreeRTOS_system_calls_start__ ) |
( portMPU_REGION_VALID ) |
( portPRIVILEGED_SYSTEM_CALLS_REGION );
portMPU_REGION_ATTRIBUTE_REG =
( prvGetMPURegionSizeSetting( ( uint32_t ) __FreeRTOS_system_calls_end__
- ( uint32_t ) __FreeRTOS_system_calls_start__ ) ) |
( portMPU_REGION_READ_WRITE ) |
( ( 0x0BUL & portMPU_RASR_TEX_S_C_B_MASK ) << portMPU_RASR_TEX_S_C_B_LOCATION ) |
( portMPU_REGION_ENABLE );
/* Setup the privileged data RAM region.
* This is where the kernel data is placed. */
portMPU_REGION_BASE_ADDRESS_REG =
( ( uint32_t ) __FreeRTOS_privileged_data_start__ ) |
( portMPU_REGION_VALID ) |
( portPRIVILEGED_DATA_REGION );
portMPU_REGION_ATTRIBUTE_REG =
( prvGetMPURegionSizeSetting( ( uint32_t ) __FreeRTOS_privileged_data_end__
- ( uint32_t ) __FreeRTOS_privileged_data_start__ ) ) |
( portMPU_REGION_PRIVILEGED_READ_WRITE ) |
( ( 0x0BUL & portMPU_RASR_TEX_S_C_B_MASK ) << portMPU_RASR_TEX_S_C_B_LOCATION ) |
( portMPU_REGION_EXECUTE_NEVER ) |
( portMPU_REGION_ENABLE );
/* Enable the memory fault exception. */
portNVIC_SYS_CTRL_STATE_REG |= portNVIC_MEM_FAULT_ENABLE;
/* Enable the MPU with the background region configured. */
portMPU_CTRL_REG |= ( portMPU_ENABLE | portMPU_BACKGROUND_ENABLE );
__asm volatile ( "dsb" );
__asm volatile ( "isb" );
}
}
我要赚赏金
