首页 > 代码库 > stm32f407 官方ucos-iii 不支持FPU 导致haltfault错误的处理办法
stm32f407 官方ucos-iii 不支持FPU 导致haltfault错误的处理办法
由于官方提供的μCOS-III移植工程中对于浮点寄存器的入栈和出栈处理是错误的,所以网上就流传了
各种修正版本。但是这些修正的代码只能在 MDK4.7 以下版本中可以正常的运行,MDK4.7 及其以上的版
的 16 个浮点寄存器入栈。
各种修正版本。但是这些修正的代码只能在 MDK4.7 以下版本中可以正常的运行,MDK4.7 及其以上的版
本无法正常运行。下面针对高版本的MDK进行修正处理
处理方法如下:
为了解决 FPU 的问题,有两个函数需要修改:一个是 CPU_STK *OSTaskStkInit(),另一个是 PendSV
中断。 最后需要在工程选项中开启FPU的支持
修改函数CPU_STK *OSTaskStkInit()
函数所在的在:
uCOS-III\Ports\ARM-Cortex-M4\Generic\RealView\os_cpu_c.c
修改后的内容如下:
CPU_STK *OSTaskStkInit (OS_TASK_PTR p_task, void *p_arg, CPU_STK *p_stk_base, CPU_STK *p_stk_limit, CPU_STK_SIZE stk_size, OS_OPT opt) { CPU_STK *p_stk; (void)opt; /* Prevent compiler warning */ p_stk = &p_stk_base[stk_size]; /* Load stack pointer */ /* Align the stack to 8-bytes. */ p_stk = (CPU_STK *)((CPU_STK)(p_stk) & 0xFFFFFFF8); /* Registers stacked as if auto-saved on exception */ *--p_stk = (CPU_STK)0x01000000u; /* xPSR */ *--p_stk = (CPU_STK)p_task; /* Entry Point */ *--p_stk = (CPU_STK)OS_TaskReturn; /* R14 (LR) */ *--p_stk = (CPU_STK)0x12121212u; /* R12 */ *--p_stk = (CPU_STK)0x03030303u; /* R3 */ *--p_stk = (CPU_STK)0x02020202u; /* R2 */ *--p_stk = (CPU_STK)p_stk_limit; /* R1 */ *--p_stk = (CPU_STK)p_arg; /* R0 */ /* Remaining registers saved on process stack */ *--p_stk = (CPU_STK)0x11111111u; /* R11 */ *--p_stk = (CPU_STK)0x10101010u; /* R10 */ *--p_stk = (CPU_STK)0x09090909u; /* R9 */ *--p_stk = (CPU_STK)0x08080808u; /* R8 */ *--p_stk = (CPU_STK)0x07070707u; /* R7 */ *--p_stk = (CPU_STK)0x06060606u; /* R6 */ *--p_stk = (CPU_STK)0x05050505u; /* R5 */ *--p_stk = (CPU_STK)0x04040404u; /* R4 */ ;if ENABLE_FPU *--p_stk = (CPU_STK)0xFFFFFFFDUL; (1) ;endif return (p_stk); }
修改函数OS_CPU_PendSVHandler
函数所在的位置在:
uCOS-III\Ports\ARM-Cortex-M4\Generic\RealView\os_cpu_a.asm
修改后的内容
<pre name="code" class="cpp">OS_CPU_PendSVHandler CPSID I ; Prevent interruption during context switch MRS R0, PSP ; PSP is process stack pointer CBZ R0, OS_CPU_PendSVHandler_nosave ; Skip register save the first time ;if enable the FPU TST LR, #0x10 IT EQ VSTMDBEQ R0!, {S16-S31} MOV R3, LR STMDB R0!,{R3-R11} LDR R1, =OSTCBCurPtr ; OSTCBCurPtr->OSTCBStkPtr = SP; LDR R1, [R1] STR R0, [R1] ; R0 is SP of process being switched out ; At this point, entire context of process has been saved OS_CPU_PendSVHandler_nosave PUSH {R14} ; Save LR exc_return value LDR R0, =OSTaskSwHook ; OSTaskSwHook(); BLX R0 POP {R14} LDR R0, =OSPrioCur ; OSPrioCur = OSPrioHighRdy; LDR R1, =OSPrioHighRdy LDRB R2, [R1] STRB R2, [R0] LDR R0, =OSTCBCurPtr ; OSTCBCurPtr = OSTCBHighRdyPtr; LDR R1, =OSTCBHighRdyPtr LDR R2, [R1] STR R2, [R0] LDR R0, [R2] ; R0 is new process SP; SP = OSTCBHighRdyPtr->StkPtr; LDMIA R0!,{R3-R11} MOV LR, R3 TST LR, #0x10 IT EQ VLDMIAEQ R0!, {S16-S31} MSR PSP, R0 ; Load PSP with new process SP ORR LR, LR, #0x04 ; Ensure exception return uses process stack CPSIE I BX LR ; Exception return will restore remaining context END
1. 通过检测 EXC_RETURN(LR)的 bit4 来看这个任务是否使用
的 16 个浮点寄存器入栈。
2. 这里比较好理解,只不过也将 EXC_RETURN进行了入栈。
3. 参考上面的第二条,只不过这里是出栈。
4. 参考上面的第一条,只不过这里是出栈。
开启FPU
修改了上面的两个地方后别忘了开启 FPU:
开启FPU的优劣
开启FPU的好处就是加快浮点运算的执行速度,缺点就是增加任务堆栈的大小,因为34个浮点寄存器也需要入栈。同时也增加了任务的切换时间
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。