这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 行业应用 » 汽车电子 » 【FreeRtos】FreeRtos + MPU模块的配置使用

共1条 1/1 1 跳转至

【FreeRtos】FreeRtos + MPU模块的配置使用

高工
2026-04-02 15:12:15     打赏

【简介】

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

image.png

针对MPU 的说明,此贴(【S32K3XX】MPU 功能验证)(【S32K3XX】Memory 访问默认权限配置)之前有过介绍。

开启配置后 S32DS 编译代码会有如下的link错误。

image.png

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

image.png

#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" );
    }
}



   


           


共1条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]