⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄

📁 范例程序 可以学习mcos的简单移植。
💻
字号:
             关于uCOS51V1.0版本不支持参数传递BUG的修正
          2003/05/16   asdjf@163.com  http://www.hjhj.com

    uCOS51V1.0版本有一个严重BUG,不支持参数传递(在uCOS51V1.1版本中已经修正)。 网友YAYACOMNET指出此问题,经过检查是由于pdata没有入栈造成的。KEIL编译器对于函数参数的传递种类繁多,有时用寄存器,有时用仿真堆栈,还有的寄存器和堆栈混用,这下处理参数传递好象变得很复杂,似乎无法实现。幸运的是uC/OS-II的任务参数只有一个void *pdata,通过这个空指针,可以传递任意的结构体变量,用户参数安排在结构体里,使用灵活。经过查C51.PDF知,此种情况下,任务的void *ppdata参数恰好是用R3、R2、R1传递,而不通过虚拟堆栈。R3、R2、R1用于传递任务参数ppdata,其中R3代表存储器类型,R2为高字节偏移,R1为低字节位移。因为我用的全是XDATA,所以存储器类型固定为1即R3=1,见C51.PDF第178页说明。修改OS_CPU_C.C的部分代码如下:

void *OSTaskStkInit (void (*task)(void *pd), void *ppdata, void *ptos, INT16U opt) reentrant
{    
    OS_STK *stk;

    ppdata = ppdata;
    opt    = opt;                               //opt没被用到,保留此语句防止告警产生    
    stk    = (OS_STK *)ptos;                    //用户堆栈最低有效地址
    *stk++ = 15;                                //用户堆栈长度
    *stk++ = (INT16U)task & 0xFF;               //任务地址低8位
    *stk++ = (INT16U)task >> 8;                 //任务地址高8位    
    *stk++ = 0x00;                              //PSW
    *stk++ = 0x0A;                              //ACC
    *stk++ = 0x0B;                              //B
    *stk++ = 0x00;                              //DPL
    *stk++ = 0x00;                              //DPH
    *stk++ = 0x00;                              //R0
    
//R3、R2、R1用于传递任务参数ppdata,其中R3代表存储器类型,R2为高字节偏移,R1为低字节位移。
//通过分析KEIL汇编,了解到任务的void *ppdata参数恰好是用R3、R2、R1传递,不是通过虚拟堆栈。
    *stk++ = (INT16U)ppdata & 0xFF;             //R1
    *stk++ = (INT16U)ppdata >> 8;               //R2
    *stk++ = 0x01;                              //R3  因为我用的全是XDATA,所以存储器类型固定为1,见C51.PDF第178页说明。

    *stk++ = 0x04;                              //R4
    *stk++ = 0x05;                              //R5
    *stk++ = 0x06;                              //R6
    *stk++ = 0x07;                              //R7
                                                //不用保存SP,任务切换时根据用户堆栈长度计算得出。    
    *stk++ = (INT16U) (ptos+MaxStkSize) >> 8;   //?C_XBP 仿真堆栈指针高8位
    *stk++ = (INT16U) (ptos+MaxStkSize) & 0xFF; //?C_XBP 仿真堆栈指针低8位
        
    return ((void *)ptos);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -