参考 JSW-Token 发的帖子,我做了如下修改,但是不成,程序跑飞,且编译器提示S16~S31 Bad register name symbol
请帮忙看看哪里有问题:
1. 使能KEIL 的 FPU和MCU 的FPU
Target Option → Floating Point Hardware→Use FPU
BSP_PreInit()中:
ROM_FPUEnable();
ROM_FPULazyStackingEnable();
2. 修改OSTaskStkInit函数,加入浮点堆栈处理, FPSCR,S15~S0总计18*4=72个字节压栈,还有S31~S16总计 16*4=64字节压栈处理
OSTaskStkInit()中:
...
stk = ptos; /* Load stack pointer */
/* Registers stacked as if auto-saved on exception */
// 要使用FPU,需要加入浮点堆栈处理, FPSCR,S15~S0总计18*4=72个字节压栈,还有S31~S16总计 16*4=64字节压栈处理
#if 1
*( stk) = (INT32U)0xccuL; /* No Name Register */
*(--stk) = (INT32U)0xdduL; /* FPSCR */
*(--stk) = (INT32U)0xAAAAAAAAuL; /* S15 */
*(--stk) = (INT32U)0xAAAAAAAAuL; /* S14 */
*(--stk) = (INT32U)0xAAAAAAAAuL; /* S13 */
*(--stk) = (INT32U)0xAAAAAAAAuL; /* S12 */
*(--stk) = (INT32U)0xAAAAAAAAuL; /* S11 */
*(--stk) = (INT32U)0xAAAAAAAAuL; /* S10 */
*(--stk) = (INT32U)0xAAAAAAAAuL; /* S9 */
*(--stk) = (INT32U)0xAAAAAAAAuL; /* S8 */
*(--stk) = (INT32U)0xAAAAAAAAuL; /* S7 */
*(--stk) = (INT32U)0xAAAAAAAAuL; /* S6 */
*(--stk) = (INT32U)0xAAAAAAAAuL; /* S5 */
*(--stk) = (INT32U)0xAAAAAAAAuL; /* S4 */
*(--stk) = (INT32U)0xAAAAAAAAuL; /* S3 */
*(--stk) = (INT32U)0xAAAAAAAAuL; /* S2 */
*(--stk) = (INT32U)0xAAAAAAAAuL; /* S1 */
*(--stk) = (INT32U)0xAAAAAAAAuL; /* S0 */
#endif
*(--stk) = (INT32U)0x01000000uL; /* xPSR */
*(--stk) = (INT32U)task; /* Entry Point PC */
*(--stk) = (INT32U)0xFFFFFFFEL; /* R14 (LR) (init value will */
/* cause fault if ever used) */ 
*(--stk) = (INT32U)0x12121212uL; /* R12 */
*(--stk) = (INT32U)0x03030303uL; /* R3 */
*(--stk) = (INT32U)0x02020202uL; /* R2 */
*(--stk) = (INT32U)0x01010101uL; /* R1 */
*(--stk) = (INT32U)p_arg; /* R0 : argument */
/* Remaining registers saved on process stack */
#if 1
*(--stk) = (INT32U)0xBBBBBBBBuL; /* S31 */
*(--stk) = (INT32U)0xBBBBBBBBuL; /* S30 */
*(--stk) = (INT32U)0xBBBBBBBBuL; /* S29 */
*(--stk) = (INT32U)0xBBBBBBBBuL; /* S28 */
*(--stk) = (INT32U)0xBBBBBBBBuL; /* S27 */
*(--stk) = (INT32U)0xBBBBBBBBuL; /* S26 */
*(--stk) = (INT32U)0xBBBBBBBBuL; /* S25 */
*(--stk) = (INT32U)0xBBBBBBBBuL; /* S24 */
*(--stk) = (INT32U)0xBBBBBBBBuL; /* S23 */
*(--stk) = (INT32U)0xBBBBBBBBuL; /* S22 */
*(--stk) = (INT32U)0xBBBBBBBBuL; /* S21 */
*(--stk) = (INT32U)0xBBBBBBBBuL; /* S20 */
*(--stk) = (INT32U)0xBBBBBBBBuL; /* S19 */
*(--stk) = (INT32U)0xBBBBBBBBuL; /* S18 */
*(--stk) = (INT32U)0xBBBBBBBBuL; /* S17 */
*(--stk) = (INT32U)0xBBBBBBBBuL; /* S16 */
#endif
*(--stk) = (INT32U)0x11111111uL; /* R11 */
*(--stk) = (INT32U)0x10101010uL; /* R10 */
...
3. 修改PendSV中断,加入浮点寄存器 S31~S16的压栈和出栈处理
OSPendSV
CPSID I ; Prevent interruption during context switch
MRS R0, PSP ; PSP is process stack pointer 栈指针
CBZ R0, OSPendSV_nosave ; 若PSP=0则执行OSPendSV_nosave函数
;SUB R0, R0, #0x40 ; Save remaining regs S16-S31 on process stack
;MOV R1, R0
;STM R1!, {S16-S31}
SUB R0, R0, #0x20 ; 压栈R4~R11,共8个寄存器,即4字节*8 = 32 = 0x20
MOV R1, R0
STM R1!, {R4-R11} ; 压栈
LDR R1, =OSTCBCur ; R1 = &OSTCBCur
LDR R1, [R1] ; R1 = *R1 = *OSTCBCur
STR R0, [R1] ; *R1 = R0 (R0 is SP of process being switched out)
; At this point, entire context of process has been saved
OSPendSV_nosave
PUSH {R14} ; Save LR exc_return value
LDR R0, =OSTaskSwHook ; 调用钩子函数OSTaskSwHook();
BLX R0
POP {R14} ; 恢复R14
LDR R0, =OSPrioCur ; 令当前优先级=最高优先级, OSPrioCur = OSPrioHighRdy
LDR R1, =OSPrioHighRdy
LDRB R2, [R1]
STRB R2, [R0]
LDR R0, =OSTCBCur ; 设置当前TCB指针 OSTCBCur = OSTCBHighRdy;
LDR R1, =OSTCBHighRdy
LDR R2, [R1]
STR R2, [R0]
LDR R0, [R2] ; R0 is new process SP; SP = OSTCBHighRdy->OSTCBStkPtr;
MOV R1, R0
LDM R1!, {R4-R11} ; Restore r4-11 from new process stack
ADDS R0, R0, #0x20 ; R4~R11 Regirst
;VLDM R0, {S16-S31} ; Restore S16-S31 from new process stack
;ADDS R0, R0, #0x40
MSR PSP, R0 ; PSP=R0, Load PSP with new process SP
ORR LR, LR, #0x04 ; 确保LR<2>=1,返回到使用进程堆栈
CPSIE I ; 开中断
BX LR ; Exception return will restore remaining context