μC/OS-II v2.92.11版本移植到STM32F103

之前用的都是μC/OS-III版本,这几天心血来潮尝试了下μC/OS-II的最新版移植到stm32f103的板子上,移植完毕后,板子可以正常跑,但是同事在调试的时候用printf函数打印浮点的时候却出错,仿真的时候浮点运算结果却是正常的,按照AAPCS规约,堆栈需要8字节对齐,查看同事的任务创建函数如下:

OSTaskCreate ( task_name,    ( void* ) 0, ( OS_STK* ) & TASK_STK[STK_SIZE - 1], TASK_PRIO );

 按照老版本的UcosII规则,直接在任务堆栈数组前用关键字__align(8)后打印便没有问题,但是实际情况在这个版本却行不通,打印还是错误……悲剧!

到os_cpu_c.c文件下查看任务函数堆栈初始化函数如下:

 

OS_STK *OSTaskStkInit ( void ( *task ) ( void *p_arg ), void *p_arg, OS_STK *ptos, INT16U opt )
{
    OS_STK *p_stk;


    ( void ) opt;                                /* 'opt' is not used, prevent warning                 */
    p_stk       = ptos;                            /* Load stack pointer                                 */
    /* Align the stack to 8-bytes.                        */
    p_stk      = ( OS_STK * ) ( ( OS_STK ) ( p_stk ) & 0xFFFFFFF8u );
    /* Registers stacked as if auto-saved on exception    */
    * ( p_stk )    = ( INT32U ) 0x01000000uL;      /* xPSR                                               */
    * ( --p_stk )  = ( INT32U ) task;              /* Entry Point                                        */
    * ( --p_stk )  = ( INT32U ) OS_TaskReturn;     /* R14 (LR)                                           */
    * ( --p_stk )  = ( INT32U ) 0x12121212uL;      /* R12                                                */
    * ( --p_stk )  = ( INT32U ) 0x03030303uL;      /* R3                                                 */
    * ( --p_stk )  = ( INT32U ) 0x02020202uL;      /* R2                                                 */
    * ( --p_stk )  = ( INT32U ) 0x01010101uL;      /* R1                                                 */
    * ( --p_stk )  = ( INT32U ) p_arg;             /* R0 : argument                                      */

    /* Remaining registers saved on process stack         */
    * ( --p_stk )  = ( INT32U ) 0x11111111uL;      /* R11                                                */
    * ( --p_stk )  = ( INT32U ) 0x10101010uL;      /* R10                                                */
    * ( --p_stk )  = ( INT32U ) 0x09090909uL;      /* R9                                                 */
    * ( --p_stk )  = ( INT32U ) 0x08080808uL;      /* R8                                                 */
    * ( --p_stk )  = ( INT32U ) 0x07070707uL;      /* R7                                                 */
    * ( --p_stk )  = ( INT32U ) 0x06060606uL;      /* R6                                                 */
    * ( --p_stk )  = ( INT32U ) 0x05050505uL;      /* R5                                                 */
    * ( --p_stk )  = ( INT32U ) 0x04040404uL;      /* R4                                                 */

    return ( p_stk );
}

任务函数堆栈首地址已经是8字节对齐,但是看入栈后的地址却不是8字节对齐了,p_stk只自减了15次,最后的栈地址并不是8字节对齐;按照arm核入栈规则,栈地址先减去4后入栈,但是ucosII的入栈却是先入栈后减4,正确的任务创建方法应该是:

OSTaskCreate ( task_name,    ( void* ) 0, ( OS_STK* ) & TASK_STK[STK_SIZE], TASK_PRIO );

任务函数堆栈初始化函数修改为:

OS_STK *OSTaskStkInit ( void ( *task ) ( void *p_arg ), void *p_arg, OS_STK *ptos, INT16U opt )
{
    OS_STK *p_stk;


    ( void ) opt;                                /* 'opt' is not used, prevent warning                 */
    p_stk       = ptos;                            /* Load stack pointer                                 */
    /* Align the stack to 8-bytes.                        */
    p_stk      = ( OS_STK * ) ( ( OS_STK ) ( p_stk ) & 0xFFFFFFF8u );
    /* Registers stacked as if auto-saved on exception    */
    * ( --p_stk )    = ( INT32U ) 0x01000000uL;      /* xPSR                                               */
    * ( --p_stk )  = ( INT32U ) task;              /* Entry Point                                        */
    * ( --p_stk )  = ( INT32U ) OS_TaskReturn;     /* R14 (LR)                                           */
    * ( --p_stk )  = ( INT32U ) 0x12121212uL;      /* R12                                                */
    * ( --p_stk )  = ( INT32U ) 0x03030303uL;      /* R3                                                 */
    * ( --p_stk )  = ( INT32U ) 0x02020202uL;      /* R2                                                 */
    * ( --p_stk )  = ( INT32U ) 0x01010101uL;      /* R1                                                 */
    * ( --p_stk )  = ( INT32U ) p_arg;             /* R0 : argument                                      */

    /* Remaining registers saved on process stack         */
    * ( --p_stk )  = ( INT32U ) 0x11111111uL;      /* R11                                                */
    * ( --p_stk )  = ( INT32U ) 0x10101010uL;      /* R10                                                */
    * ( --p_stk )  = ( INT32U ) 0x09090909uL;      /* R9                                                 */
    * ( --p_stk )  = ( INT32U ) 0x08080808uL;      /* R8                                                 */
    * ( --p_stk )  = ( INT32U ) 0x07070707uL;      /* R7                                                 */
    * ( --p_stk )  = ( INT32U ) 0x06060606uL;      /* R6                                                 */
    * ( --p_stk )  = ( INT32U ) 0x05050505uL;      /* R5                                                 */
    * ( --p_stk )  = ( INT32U ) 0x04040404uL;      /* R4                                                 */

    return ( p_stk );
}

最后打印float型数据,结果正确。

posted @ 2017-04-19 20:19  迷途小菜鸟  阅读(1016)  评论(0编辑  收藏  举报