调用OSStartHighRdy后栈溢出(uC/OS-III在MIMXRT1062上的问题)
uC/OS-III移植MIMXRT1062触发硬Fault排查方案
核心问题定位:任务栈顶地址传递错误
Cortex-M架构栈为向下生长(地址从高到低),uC/OS-III创建任务时要求传入栈的最高地址作为栈顶,但你的代码中所有OSTaskCreate调用都传入了栈数组的起始低地址(&xxxStk[0]),导致任务栈初始化后栈顶指向低地址,执行时栈向下生长直接越界,触发栈溢出或硬Fault。
修复方法
修改所有任务创建的栈顶参数,将&xxxStk[0]替换为&xxxStk[XXX_TASK_STK_SIZE - 1]:
start任务创建修改
OSTaskCreate(&startTaskTCB, startTaskName, startTask, (void *)0, startTaskPrio, &startTaskStk[START_TASK_STK_SIZE - 1], // 改为栈数组最后一个元素地址 startTaskStkLimit, startTaskStkSize, startTaskQSize, startTaskQuanta, (void *)0, OS_OPT_TASK_NONE, &err);
blinky和other任务同理修改
// blinky任务栈顶参数 &blinkyTaskStk[BLINKY_TASK_STK_SIZE - 1] // other任务栈顶参数 &otherTaskStk[OTHER_TASK_STK_SIZE - 1]
其他排查方向
1. uC/OS-III Cortex-M7移植代码错误
检查OSStartHighRdy的汇编实现,Cortex-M架构下uC/OS启动任务时应设置**PSP(任务栈指针)**而非MSP(系统栈指针)。若你的代码中存在MSR MSP, R1,需改为MSR PSP, R1。
正确的OSStartHighRdy核心汇编片段:
LDR R0, =OSTCBHighRdyPtr LDR R1, [R0] LDR R0, [R1] ; R0 = 任务栈顶地址 MSR PSP, R0 ; 设置任务栈指针PSP ORR LR, LR, #0x04 ; 切换到线程模式使用PSP BX LR ; 启动任务
2. MPU配置问题
RT1062的MPU若未正确配置任务栈所在RAM区域的权限,会触发访问错误。可暂时注释BOARD_ConfigMPU()调用测试,若故障消失,需重新配置MPU,确保任务栈所在区域有读写权限。
3. SysTick频率过高
你当前设置的SysTick频率为600kHz(SystemCoreClock/600000),远超uC/OS常规tick频率(通常1ms/1000Hz),会导致SysTick中断处理过于频繁,引发栈溢出。建议修改为与uC/OS tick匹配的频率:
SysTick_Config(SystemCoreClock / OSCfg_TickRate_Hz); // OSCfg_TickRate_Hz默认为1000
4. 任务栈大小验证
CPU_STK是32位类型(4字节),START_TASK_STK_SIZE=256对应实际栈空间为256*4=1024字节,对于你的start任务已足够,但需确保栈顶地址正确后再验证。
内容的提问来源于stack exchange,提问作者Lazaro
相关产品推荐
相关产品推荐

