BSF_RL 发表于 2012-7-29 00:20:41

ucosii for m4 带fpu

本帖最后由 BSF_RL 于 2012-7-29 00:22 编辑

在网上买了块STM32F4 discovery的板子,想把ucosii移植到上面跑跑。在网上收罗一遍,M4上移植ucosii的比较少,m4和m3差不太多就把M3的移植接口用来植m4,移植完后,下载到硬件运行程序尽然死掉了,费劲跟踪出错的地方,在跟踪的过程中发现堆栈出问题了。我在我们的BBS上看到了有位已经在m4上移植了ucosii,但是不支持FPU,我下载下来参考一下,其工程中把FPU关闭了,我查看我的工程,FPU是使能的,于是我也把FPU关闭,运行程序,led闪烁起来了,这说明M3的移植接口适用于M4,但是使能FPU为什么就不行了呢!继续跟踪单步调试,最后终于找到原因了,在使能FPU后,M4自动入栈和出栈的寄存器多了18个,如果按照M3的结构,其堆栈必定冲破栈底,这就是为什么会死掉的原因所在,但这18个寄存器到底是什么,我在网上没有找到资料,发了一个贴也没有人回答这时我突然想到RT-Thread,在哪个realthouch不是用的是M4的么,下个工程看看他是怎么处理的,下面就是cpuport.c中的定义的结构体
struct exception_stack_frame
{
    rt_uint32_t r0;
    rt_uint32_t r1;
    rt_uint32_t r2;
    rt_uint32_t r3;
    rt_uint32_t r12;
    rt_uint32_t lr;
    rt_uint32_t pc;
    rt_uint32_t psr;

#if USE_FPU
    /* FPU register */
    rt_uint32_t S0;
    rt_uint32_t S1;
    rt_uint32_t S2;
    rt_uint32_t S3;
    rt_uint32_t S4;
    rt_uint32_t S5;
    rt_uint32_t S6;
    rt_uint32_t S7;
    rt_uint32_t S8;
    rt_uint32_t S9;
    rt_uint32_t S10;
    rt_uint32_t S11;
    rt_uint32_t S12;
    rt_uint32_t S13;
    rt_uint32_t S14;
    rt_uint32_t S15;
    rt_uint32_t FPSCR;
    rt_uint32_t NO_NAME;
#endif
};

struct stack_frame
{
    /* r4 ~ r11 register */
    rt_uint32_t r4;
    rt_uint32_t r5;
    rt_uint32_t r6;
    rt_uint32_t r7;
    rt_uint32_t r8;
    rt_uint32_t r9;
    rt_uint32_t r10;
    rt_uint32_t r11;

#if USE_FPU
    /* FPU register s16 ~ s31 */
    rt_uint32_t s16;
    rt_uint32_t s17;
    rt_uint32_t s18;
    rt_uint32_t s19;
    rt_uint32_t s20;
    rt_uint32_t s21;
    rt_uint32_t s22;
    rt_uint32_t s23;
    rt_uint32_t s24;
    rt_uint32_t s25;
    rt_uint32_t s26;
    rt_uint32_t s27;
    rt_uint32_t s28;
    rt_uint32_t s29;
    rt_uint32_t s30;
    rt_uint32_t s31;
#endif

    struct exception_stack_frame exception_stack_frame;
};
看了上面的代码心中的疑惑明了了。
依据TH-thread的代码修改UCOSII的移植接口
OS_STK *OSTaskStkInit (void (*task)(void *p_arg), void *p_arg, OS_STK *ptos, INT16U opt)
{
    OS_STK *stk;


    (void)opt;                                 /* 'opt' is not used, prevent warning               */
    stk       = ptos;                            /* Load stack pointer                                 */
   stk++;
                /* Registers stacked as if auto-saved on exception    */
   #if USE_FPU
    *(--stk)= (INT32U)0xaa;                          /* R? : argument                                    */
    *(--stk)= (INT32U)0xa;                   /* FPSCR : argument                                    */
    *(--stk)= (INT32U)0x15;                   /* S15 : argument                                           */       
    *(--stk)= (INT32U)0x14;                   /* S14 : argument                                    */
    *(--stk)= (INT32U)0x13;                   /* S13 : argument                                    */
    *(--stk)= (INT32U)0x12;                   /* S12 : argument                                    */
    *(--stk)= (INT32U)0x11;                   /* S11 : argument                                    */
    *(--stk)= (INT32U)0x10;                   /* S10 : argument                                    */
    *(--stk)= (INT32U)0x9;                   /* S9 : argument                                    */
    *(--stk)= (INT32U)0x8;                   /* S8 : argument                                    */
    *(--stk)= (INT32U)0x7;                   /* S7 : argument                                 */        
    *(--stk)= (INT32U)0x6;                   /* S6 : argument                                    */       
    *(--stk)= (INT32U)0x5;                   /* S5 : argument                                    */
    *(--stk)= (INT32U)0x4;                   /* S4 : argument                                    */
    *(--stk)= (INT32U)0x3;                   /* S3 : argument                                    */
    *(--stk)= (INT32U)0x2;                   /* S2 : argument                                    */
    *(--stk)= (INT32U)0x1;                   /* S1 : argument                                    */
    *(--stk)= (INT32U)0x0;                   /* S0 : argument                                    */
#endif

    *(--stk)= (INT32U)0x01000000uL;            /* xPSR                                             */
    *(--stk)= (INT32U)task;                  /* Entry Point                                        */
    *(--stk)= (INT32U)OS_TaskReturn;         /* R14 (LR)                                           */
    *(--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         */
   
    *(--stk)= (INT32U)0x11111111uL;            /* R11                                                */
    *(--stk)= (INT32U)0x10101010uL;            /* R10                                                */
    *(--stk)= (INT32U)0x09090909uL;            /* R9                                                 */
    *(--stk)= (INT32U)0x08080808uL;            /* R8                                                 */
    *(--stk)= (INT32U)0x07070707uL;            /* R7                                                 */
    *(--stk)= (INT32U)0x06060606uL;            /* R6                                                 */
    *(--stk)= (INT32U)0x05050505uL;            /* R5                                                 */
    *(--stk)= (INT32U)0x04040404uL;            /* R4                                                 */
               
#if USE_FPU
               /* FPU register s16 ~ s31 */
    *(--stk)= (INT32U)0x31uL;            /* S31                                                 */
    *(--stk)= (INT32U)0x30uL;            /* S30                                                 */
    *(--stk)= (INT32U)0x29uL;            /* S29                                                 */
    *(--stk)= (INT32U)0x28uL;            /* S28                                                 */
    *(--stk)= (INT32U)0x27uL;            /* S27                                                 */
    *(--stk)= (INT32U)0x26uL;            /* S26                                                 */
    *(--stk)= (INT32U)0x25uL;            /* S25                                                 */
    *(--stk)= (INT32U)0x24uL;            /* S24                                                 */
    *(--stk)= (INT32U)0x23uL;            /* S23                                                 */
    *(--stk)= (INT32U)0x22uL;            /* S22                                                 */
    *(--stk)= (INT32U)0x21uL;            /* S21                                                 */
    *(--stk)= (INT32U)0x20uL;            /* S20                                                 */
    *(--stk)= (INT32U)0x19uL;            /* S19                                                 */
    *(--stk)= (INT32U)0x18uL;            /* S18                                                 */
    *(--stk)= (INT32U)0x17uL;            /* S17                                                 */
    *(--stk)= (INT32U)0x16uL;            /* S16                                                 */
#endif

    return (stk);
}
这只是堆栈初始化部分,最重要的部分是任务切换部分,任务切换我觉得就是保护现场,和恢复现场,可是汇编不会,还那样 参考下rt-thread
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

    SUBS    R0, R0, #0x20                                       ; Save remaining regs r4-11 on process stack
    STM   R0, {R4-R11}
       
    IF      {FPU} != "SoftVFP"
        VSTMFDr0!, {d8 - d15}         ; push FPU register s16~s31
    ENDIF
       
    LDR   R1, =OSTCBCur                                       ; OSTCBCur->OSTCBStkPtr = SP;
    LDR   R1,
    STR   R0,                                           ; 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,
    STRB    R2,

    LDR   R0, =OSTCBCur                                       ; OSTCBCur= OSTCBHighRdy;
    LDR   R1, =OSTCBHighRdy
    LDR   R2,
    STR   R2,

    LDR   R0,                                           ; R0 is new process SP; SP = OSTCBHighRdy->OSTCBStkPtr;
   
        IF      {FPU} != "SoftVFP"
    VLDMFDr0!, {d8 - d15}                                                 ; pop FPU register s16~s31
        ENDIF

        LDM   R0, {R4-R11}                              ; Restore r4-11 from new process stack
       
    ADDS    R0, R0, #0x20
    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

我有些不明白的是IF      {FPU} != "SoftVFP" 是怎么来的?
下面奉上工程 mdk的如有不对的地方请指正!









CDSN 发表于 2012-8-1 16:58:58

{:smile:}谢谢,分享

orange-208 发表于 2012-8-5 09:28:42

楼主的STM32是F407VG系列吗? 我正准备搞个最小系统板玩玩,以前搞过STM32F103。

chenerbox2 发表于 2012-8-5 09:40:31

STM32F4 discovery这个我就感觉挺好的 主要便宜啊

i55x 发表于 2012-8-5 09:44:25

用rlarm吧,对于stm32来说,比ucos好太多了。

niba 发表于 2012-8-5 10:48:09

i55x 发表于 2012-8-5 09:44 static/image/common/back.gif
用rlarm吧,对于stm32来说,比ucos好太多了。

好多了?有啥优势呢?

ST_ATMEL_NXP 发表于 2013-10-8 13:52:54

不知楼主的疑问解决了没有!

ST_ATMEL_NXP 发表于 2013-10-8 20:04:00

有编译通过的吗?我用MDK4.72A编译,开启FPU有运行异常。

kidfl 发表于 2013-10-9 16:19:32

感谢楼主分享
页: [1]
查看完整版本: ucosii for m4 带fpu