??
字號(hào):
關(guān)于uCOS51V1.0版本不支持參數(shù)傳遞BUG的修正
2003/05/16 asdjf@163.com http://www.hjhj.com
uCOS51V1.0版本有一個(gè)嚴(yán)重BUG,不支持參數(shù)傳遞(在uCOS51V1.1版本中已經(jīng)修正)。 網(wǎng)友YAYACOMNET指出此問題,經(jīng)過檢查是由于pdata沒有入棧造成的。KEIL編譯器對于函數(shù)參數(shù)的傳遞種類繁多,有時(shí)用寄存器,有時(shí)用仿真堆棧,還有的寄存器和堆棧混用,這下處理參數(shù)傳遞好象變得很復(fù)雜,似乎無法實(shí)現(xiàn)。幸運(yùn)的是uC/OS-II的任務(wù)參數(shù)只有一個(gè)void *pdata,通過這個(gè)空指針,可以傳遞任意的結(jié)構(gòu)體變量,用戶參數(shù)安排在結(jié)構(gòu)體里,使用靈活。經(jīng)過查C51.PDF知,此種情況下,任務(wù)的void *ppdata參數(shù)恰好是用R3、R2、R1傳遞,而不通過虛擬堆棧。R3、R2、R1用于傳遞任務(wù)參數(shù)ppdata,其中R3代表存儲(chǔ)器類型,R2為高字節(jié)偏移,R1為低字節(jié)位移。因?yàn)槲矣玫娜荴DATA,所以存儲(chǔ)器類型固定為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沒被用到,保留此語句防止告警產(chǎn)生
stk = (OS_STK *)ptos; //用戶堆棧最低有效地址
*stk++ = 15; //用戶堆棧長度
*stk++ = (INT16U)task & 0xFF; //任務(wù)地址低8位
*stk++ = (INT16U)task >> 8; //任務(wù)地址高8位
*stk++ = 0x00; //PSW
*stk++ = 0x0A; //ACC
*stk++ = 0x0B; //B
*stk++ = 0x00; //DPL
*stk++ = 0x00; //DPH
*stk++ = 0x00; //R0
//R3、R2、R1用于傳遞任務(wù)參數(shù)ppdata,其中R3代表存儲(chǔ)器類型,R2為高字節(jié)偏移,R1為低字節(jié)位移。
//通過分析KEIL匯編,了解到任務(wù)的void *ppdata參數(shù)恰好是用R3、R2、R1傳遞,不是通過虛擬堆棧。
*stk++ = (INT16U)ppdata & 0xFF; //R1
*stk++ = (INT16U)ppdata >> 8; //R2
*stk++ = 0x01; //R3 因?yàn)槲矣玫娜荴DATA,所以存儲(chǔ)器類型固定為1,見C51.PDF第178頁說明。
*stk++ = 0x04; //R4
*stk++ = 0x05; //R5
*stk++ = 0x06; //R6
*stk++ = 0x07; //R7
//不用保存SP,任務(wù)切換時(shí)根據(jù)用戶堆棧長度計(jì)算得出。
*stk++ = (INT16U) (ptos+MaxStkSize) >> 8; //?C_XBP 仿真堆棧指針高8位
*stk++ = (INT16U) (ptos+MaxStkSize) & 0xFF; //?C_XBP 仿真堆棧指針低8位
return ((void *)ptos);
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -