[RTOS]关于STM32F4移植uCOSIII使用FPU会HardFault

首先必须要谢谢正点原子的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		

这个时候再编译下,排错,然后下载试下应该就可以了

  • 4
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

山猫Show

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值