前言:随着汽车电子控制系统复杂度不断提升,采用实时操作系统以提升任务调度能力、降低软件耦合度已成为主流。NXP S32K 系列 MCU 在车规级应用中广泛使用,而 FreeRTOS 作为轻量、成熟、开源的 RTOS,是 S32K 项目中最常用的操作系统之一。
目录
[二、FreeRTOS 文件结构说明](#二、FreeRTOS 文件结构说明)
一、环境准备
S32 Design Studio for ARM
Version: 2.2
SDK:RTM V3.0.0
FreeRTOS版本:我用的是S32_SDK_S32K1xx_RTM_4.0.3中提供的RTOS的代码
二、FreeRTOS 文件结构说明
相关说明大家可以在网上找找,很多也很容易理解。
三、创建工程
1.我使用的是官方的示例工程作为基础,如下:
2.添加相关的文件进来,用方框框住的是我主动添加的,其它是工程自带的。

3.FreeRTOSConfig.h文件是需要自己编写的,这里给大家一个基础的能跑起来的示例:
#ifndef FREERTOS_CONFIG_H
#define FREERTOS_CONFIG_H
/*-----------------------------------------------------------
* Application specific definitions.
*----------------------------------------------------------*/
/* CMSIS */
#include "stdint.h"
#include "system_S32K146.h"
/* ========== 基本调度配置 ========== */
#define configUSE_PREEMPTION 1
#define configUSE_IDLE_HOOK 0
#define configUSE_TICK_HOOK 0
#define configUSE_16_BIT_TICKS 0
#define configIDLE_SHOULD_YIELD 1
#define configCPU_CLOCK_HZ ( SystemCoreClock )
#define configTICK_RATE_HZ ( ( TickType_t )1000 )
#define configMAX_PRIORITIES 7
#define configMINIMAL_STACK_SIZE ( ( uint16_t )200 )
#define configMAX_TASK_NAME_LEN 16
/* ========== 内存管理 ========== */
#define configSUPPORT_DYNAMIC_ALLOCATION 1
#define configSUPPORT_STATIC_ALLOCATION 0
#define configTOTAL_HEAP_SIZE ( ( size_t )( 20 * 1024 ) )
/* ========== Hook Functions ========== */
#define configUSE_MALLOC_FAILED_HOOK 0
#define configUSE_STACK_OVERFLOW_CHECK 2
/* ========== Cortex-M4 中断优先级配置(⚠ 必须正确) ========== */
/* S32K146 = Cortex-M4F = 4 bits priority */
#define configPRIO_BITS 4
/* 库优先级定义(数字越小,优先级越高) */
#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 15
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 5
/* 内核使用的 NVIC 实际值 */
#define configKERNEL_INTERRUPT_PRIORITY \
( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
#define configMAX_SYSCALL_INTERRUPT_PRIORITY \
( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
/* ========== API 支持裁剪 ========== */
#define INCLUDE_vTaskDelay 1
#define INCLUDE_xTaskGetSchedulerState 1
#define INCLUDE_xTaskGetCurrentTaskHandle 1
#define INCLUDE_uxTaskGetStackHighWaterMark 1
#define INCLUDE_vTaskSuspend 1
#define INCLUDE_vTaskDelete 1
/* ========== 断言(调试阶段强烈建议打开) ========== */
#define configASSERT( x ) \
if( ( x ) == 0 ) { taskDISABLE_INTERRUPTS(); for( ;; ); }
#endif /* FREERTOS_CONFIG_H */
到此我编译完全没报错,然后进行功能的测试。
四、RTOS的测试Code以及问题纠正
void TestTask(void *p)
{
uint8_t date[8]={0};
for (;;)
{
CAN0_SendMultiMailBox(0x1F5,date,8);
vTaskDelay(pdMS_TO_TICKS(500));
}
}
/*!
\brief The main function for the project.
\details The startup initialization sequence is the following:
* - __start (startup asm routine)
* - __init_hardware()
* - main()
* - PE_low_level_init()
* - Common_Init()
* - Peripherals_Init()
*/
int main(void)
{
BoardInit();
APP_Init();
BaseType_t create= xTaskCreate(TestTask, "CAN", 256, NULL, 2, NULL);
vTaskStartScheduler();
/*** End of RTOS startup code. ***/
/*** Processor Expert end of main routine. DON'T MODIFY THIS CODE!!! ***/
for(;;) {
if(exit_code != 0) {
break;
}
}
return exit_code;
/*** Processor Expert end of main routine. DON'T WRITE CODE BELOW!!! ***/
} /*** End of main routine. DO NOT MODIFY THIS TEXT!!! ***/
发现我的CAN线上完全没数据。通过单步调试后发现,任务创建成功,但是在任务调度的代码的这里跑飞。
也就是没有启动成功,后面发现,需要给中断这些配置映射到RTOS当中所以我看了启动文件(.s文件)后发现里面没有对应的RTOS的中断名称,但是有"SVC_Handler""PendSV_Handler""SysTick_Handler",这些是和RTOS中的名称很相似,我又在网上查资料后发现确实是这几个要映射过去,所有我又在FreeRTOSConfig.h文件中添加了:
#define vPortSVCHandler SVC_Handler
#define xPortPendSVHandler PendSV_Handler
#define xPortSysTickHandler SysTick_Handler
编译后仍然后报错。

发现是在

这里报错。
#define FEATURE_OSIF_USE_SYSTICK (1)
#define FEATURE_OSIF_USE_PIT (0)
#define FEATURE_OSIF_FREERTOS_ISR_CONTEXT_METHOD (1) /* Cortex M device */
其中定时器冲突, 我把"FEATURE_OSIF_USE_SYSTICK"置零后问题解决。CAN线上也出现数据。

至此基本跑通RTOS系统。
五、结束语
将 FreeRTOS 移植到 S32K 的过程并不复杂,但涉及中断优先级、Tick 定时器、中断映射、内存管理等多个细节,如果任意一处处理不当,就会造成调度器无法启动或任务切换异常。希望本文提供的模板能够帮助你快速建立一套可复用的移植体系,使后续项目能够稳定、高效地运行在 FreeRTOS 之上。