赞
踩
首先必须要谢谢正点原子的uCOS开发手册V3.0,介绍的很详细,大神就是大神
然后呢,这几天就在看的时候发现移植uCOSIII出现了开启FPU的时候就会HardFault,然后上网搜了一下,果然这个问题烂大街了已经,然后我也稍微研究了一下,发现出问题的是uCOS官方的文件不符合浮点寄存器的入栈和出栈顺序,然后呢,经过两个小时的寻找解决方案,最终还是在安富莱电子的uCOSIII教程1-11期中找到了解决方案,出现问题的点有两个: 一个是 CPU_STK *OSTaskStkInit(), 另一个是 PendSV中断。其余的地方按照原子哥的方法修改,然后融合到一起就没问题了。
以下解决方案是基于uCOSIII 3.04版本,其他版本自行测试
具体的移植方法是:
1,按照原子哥的方法移植到编译没有错误为止,然后试一下,添加一个打印浮点数的任务,Debug一下试试会不会死在
/**
* @brief This function handles Hard Fault exception.
* @param None
* @retval None
*/
void HardFault_Handler(void)
{
/* Go to infinite loop when Hard Fault exception occurs */
while (1)
{
}
}
其实根本不用试,这是必须的。
2,找到OSTaskStkInit(在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 : argument */ /* 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 */ *--p_stk = (CPU_STK)0xFFFFFFFDUL; return (p_stk); }
3,找到PendSV_Handler(在os_cpu_a.asm),改为以下代码
PendSV_Handler CPSID I ; Prevent interruption during context switch MRS R0, PSP ; PSP is process stack pointer CBZ R0, PendSVHandler_nosave ; Skip register save the first time CBZ R0, PendSVHandler_nosave ; Skip register save the first time 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 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 CPSIE I BX LR ; Exception return will restore remaining context END
这个时候再编译下,排错,然后下载试下应该就可以了
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。