当前位置:   article > 正文

STM32F4 + UCOSIII 关于使能FPU导致HardFault的问题

STM32F4 + UCOSIII 关于使能FPU导致HardFault的问题

最近在工作过程中 使用stm32f4 + ucosiii开发 

在使用sqrt的时候 发现总会跑进hardfault

 

一开始以为是没有使用FPU 导致浮点运算不了 后来单独实验 在不使能FPU 的情况下 浮点也可正常运算

然后发现裸机的话可以正常运行 跑系统就不行 

将问题定位到ucos端  寻找资料 是ucosiii 代码问题 现mark一下 

UCOSIII版本为V3.03

 

主要修改3个点,红色为修改内容。

1.stm32f4的启动文件

Reset_Handler    PROC
                 EXPORT  Reset_Handler             [WEAK]
        IMPORT  SystemInit
        IMPORT  __main
            
                 LDR R0,=0xE000ED88 ;使能FPU CP10 CP11
                 LDR R1,[R0]
                 ORR R1,R1,#(0XF << 20)
                 STR R1,[R0]
                 DSB
                 
                 LDR.W R0,=0xE000EF34
                 LDR R1,[R0]
                 AND R1,R1,#(0x3FFFFFFF)
                 STR R1,[R0]
                 ISB

                 LDR     R0, =SystemInit
                 BLX     R0
                 LDR     R0, =__main
                 BX      R0
                 ENDP

2.修改os_cpu.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                                     */
   
                                                         /* Registers stacked as if auto-saved on exception        */
    //#if (__FPU_PRESENT==1)&&(__FPU_USED==1)         /* Registers stacked as if auto-saved on exception        */
    *(--p_stk) = (CPU_STK)0x00000000u; //No Name Register  
    *(--p_stk) = (CPU_STK)0x00001000u; //FPSCR
    *(--p_stk) = (CPU_STK)0x00000015u; //s15
    *(--p_stk) = (CPU_STK)0x00000014u; //s14
    *(--p_stk) = (CPU_STK)0x00000013u; //s13
    *(--p_stk) = (CPU_STK)0x00000012u; //s12
    *(--p_stk) = (CPU_STK)0x00000011u; //s11
    *(--p_stk) = (CPU_STK)0x00000010u; //s10
    *(--p_stk) = (CPU_STK)0x00000009u; //s9
    *(--p_stk) = (CPU_STK)0x00000008u; //s8
    *(--p_stk) = (CPU_STK)0x00000007u; //s7
    *(--p_stk) = (CPU_STK)0x00000006u; //s6
    *(--p_stk) = (CPU_STK)0x00000005u; //s5
    *(--p_stk) = (CPU_STK)0x00000004u; //s4
    *(--p_stk) = (CPU_STK)0x00000003u; //s3
    *(--p_stk) = (CPU_STK)0x00000002u; //s2
    *(--p_stk) = (CPU_STK)0x00000001u; //s1
    *(--p_stk) = (CPU_STK)0x00000000u; //s0
    //#endif

    
    *--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             */
    //#if (__FPU_PRESENT==1)&&(__FPU_USED==1)
    *(--p_stk) = (CPU_STK)0x00000031u; //s31
    *(--p_stk) = (CPU_STK)0x00000030u; //s30
    *(--p_stk) = (CPU_STK)0x00000029u; //s29
    *(--p_stk) = (CPU_STK)0x00000028u; //s28
    *(--p_stk) = (CPU_STK)0x00000027u; //s27
    *(--p_stk) = (CPU_STK)0x00000026u; //s26
    *(--p_stk) = (CPU_STK)0x00000025u; //s25
    *(--p_stk) = (CPU_STK)0x00000024u; //s24
    *(--p_stk) = (CPU_STK)0x00000023u; //s23
    *(--p_stk) = (CPU_STK)0x00000022u; //s22
    *(--p_stk) = (CPU_STK)0x00000021u; //s21
    *(--p_stk) = (CPU_STK)0x00000020u; //s20
    *(--p_stk) = (CPU_STK)0x00000019u; //s19
    *(--p_stk) = (CPU_STK)0x00000018u; //s18
    *(--p_stk) = (CPU_STK)0x00000017u; //s17
    *(--p_stk) = (CPU_STK)0x00000016u; //s16
    //#endif

    *--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 (OS_CPU_ARM_FP_EN == DEF_ENABLED)
    if ((opt & OS_OPT_TASK_SAVE_FP) != (CPU_INT16U)0) {
        *--p_stk = (CPU_STK)0x02000000u;                        /* FPSCR                                                  */
                                                                /* Initialize S0-S31 floating point registers             */
        *--p_stk = (CPU_STK)0x41F80000u;                        /* S31                                                    */
        *--p_stk = (CPU_STK)0x41F00000u;                        /* S30                                                    */
        *--p_stk = (CPU_STK)0x41E80000u;                        /* S29                                                    */
        *--p_stk = (CPU_STK)0x41E00000u;                        /* S28                                                    */
        *--p_stk = (CPU_STK)0x41D80000u;                        /* S27                                                    */
        *--p_stk = (CPU_STK)0x41D00000u;                        /* S26                                                    */
        *--p_stk = (CPU_STK)0x41C80000u;                        /* S25                                                    */
        *--p_stk = (CPU_STK)0x41C00000u;                        /* S24                                                    */
        *--p_stk = (CPU_STK)0x41B80000u;                        /* S23                                                    */
        *--p_stk = (CPU_STK)0x41B00000u;                        /* S22                                                    */
        *--p_stk = (CPU_STK)0x41A80000u;                        /* S21                                                    */
        *--p_stk = (CPU_STK)0x41A00000u;                        /* S20                                                    */
        *--p_stk = (CPU_STK)0x41980000u;                        /* S19                                                    */
        *--p_stk = (CPU_STK)0x41900000u;                        /* S18                                                    */
        *--p_stk = (CPU_STK)0x41880000u;                        /* S17                                                    */
        *--p_stk = (CPU_STK)0x41800000u;                        /* S16                                                    */
        *--p_stk = (CPU_STK)0x41700000u;                        /* S15                                                    */
        *--p_stk = (CPU_STK)0x41600000u;                        /* S14                                                    */
        *--p_stk = (CPU_STK)0x41500000u;                        /* S13                                                    */
        *--p_stk = (CPU_STK)0x41400000u;                        /* S12                                                    */
        *--p_stk = (CPU_STK)0x41300000u;                        /* S11                                                    */
        *--p_stk = (CPU_STK)0x41200000u;                        /* S10                                                    */
        *--p_stk = (CPU_STK)0x41100000u;                        /* S9                                                     */
        *--p_stk = (CPU_STK)0x41000000u;                        /* S8                                                     */
        *--p_stk = (CPU_STK)0x40E00000u;                        /* S7                                                     */
        *--p_stk = (CPU_STK)0x40C00000u;                        /* S6                                                     */
        *--p_stk = (CPU_STK)0x40A00000u;                        /* S5                                                     */
        *--p_stk = (CPU_STK)0x40800000u;                        /* S4                                                     */
        *--p_stk = (CPU_STK)0x40400000u;                        /* S3                                                     */
        *--p_stk = (CPU_STK)0x40000000u;                        /* S2                                                     */
        *--p_stk = (CPU_STK)0x3F800000u;                        /* S1                                                     */
        *--p_stk = (CPU_STK)0x00000000u;                        /* S0                                                     */
    }
#endif

    return (p_stk);
}

 

3.修改os_cpu_a.asm

PendSV_Handler
    CPSID   I                                                   ; Prevent interruption during context switch
    MRS     R0, PSP                                             ; PSP is process stack pointer
    CBZ     R0, PendSV_Handler_nosave                     ; Skip register save the first time

    SUBS    R0, R0, #0x40
    VSTM    R0, {S16-S31}

    
    SUBS    R0, R0, #0x20                                       ; Save remaining regs r4-11 on process stack
    STM     R0, {R4-R11}

    LDR     R1, =OSTCBCurPtr                                       ; OSTCBCur->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
PendSV_Handler_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                                       ; OSTCBCur  = OSTCBHighRdy;
    LDR     R1, =OSTCBHighRdyPtr
    LDR     R2, [R1]
    STR     R2, [R0]

    LDR     R0, [R2]                                            ; R0 is new process SP; SP = OSTCBHighRdy->OSTCBStkPtr;
    LDM     R0, {R4-R11}                                        ; Restore r4-11 from new process stack
    ADDS    R0, R0, #0x20
    
    VLDM    R0, {S16-S31}
    ADDS    R0, R0, #0x40

    
    MSR     PSP, R0                                             ; Load PSP with new process SP
    ORR     LR, LR, #0xF4                                       ; Ensure exception return uses process stack
    CPSIE   I
    BX      LR                                                  ; Exception return will restore remaining context


    END

 

这三个地方修改完就可以正常使用FPU了

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/article/detail/50584
推荐阅读
相关标签
  

闽ICP备14008679号