<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          μC/OS-II在80x86上的移植

          作者: 時(shí)間:2016-10-08 來源:網(wǎng)絡(luò) 收藏

          OSTaskStkInit()

          OSTaskCreateHook()

          OSTaskDelHook()

          OSTaskSwHook()

          OSTaskStatHook()

          OSTimeTickHook()

          實(shí)際需要修改的只有OSTaskStkInit()函數(shù),其他五個(gè)函數(shù)需要聲明,但不一定有實(shí)際內(nèi)容。這五個(gè)函數(shù)都是用戶定義的,所以O(shè)S_CPU_C.C中沒有給出代碼。如果用戶需要使用這些函數(shù),請(qǐng)將文件OS_CFG.H中的#define constant OS_CPU_HOOKS_EN設(shè)為1,設(shè)為0表示不使用這些函數(shù)。

          程序清單L 9.9 18.2Hz 的OSTickISR()函數(shù).

          _OSTickISRPROCFAR

          ;

          PUSHA; 保存被中斷任務(wù)的CPU環(huán)境

          PUSHES

          PUSHDS

          ;

          MOVAX,SEG_OSIntNesting;載入 DS

          MOVDS,AX

          ;

          INCBYTEPTR_OSIntNesting;標(biāo)示uC/OS-II進(jìn)入中斷

          ;

          INT081H; 調(diào)用DOS的時(shí)鐘中斷處理函數(shù)

          ;

          CALLFARPTR_OSTimeTick; 調(diào)用OSTimeTick()函數(shù)

          ;

          CALLFARPTR_OSIntExit;標(biāo)示uC/OS-IIof中斷結(jié)束

          ;

          POPDS; 恢復(fù)被中斷任務(wù)的CPU環(huán)境

          POPES

          POPA

          ;

          IRET; 返回被中斷任務(wù)

          ;

          _OSTickISRENDP

          圖F9.7 傳遞參數(shù) pdata的堆棧初始化結(jié)構(gòu)

          9.05.01 OSTaskStkInit()

          該函數(shù)由OSTaskCreate()或OSTaskCreateExt()調(diào)用,用來初始化任務(wù)的堆棧。初始狀態(tài)的堆棧模擬發(fā)生一次中斷后的堆棧結(jié)構(gòu)。圖F9.7說明了OSTaskStkInit()初始化后的堆棧內(nèi)容。請(qǐng)注意,圖中的堆棧結(jié)構(gòu)不是調(diào)用OSTaskStkInit()任務(wù)的,而是新創(chuàng)建任務(wù)的。

          當(dāng)調(diào)用OSTaskCreate()或OSTaskCreateExt()創(chuàng)建一個(gè)新任務(wù)時(shí),需要傳遞的參數(shù)是:

          任務(wù)代碼的起使地址,參數(shù)指針(pdata),任務(wù)堆棧頂端的地址,任務(wù)的優(yōu)先級(jí)。

          OSTaskCreateExt()還需要一些其他參數(shù),但與OSTask StkInit()沒有關(guān)系。

          OSTaskStkInit()(程序清單L9.10)只需要以上提到的3個(gè)參數(shù)(task,pdata,和ptos)。

          程序清單L 9.10 OSTaskStkInit().

          void*OSTaskStkInit(void(*task)(void*pd),void*pdata,void*ptos,INT16Uopt)

          {

          INT16U*stk;

          opt=opt;/*'opt'未使用,此處可防止編譯器的警告 */

          stk=(INT16U*)ptos;/* 載入堆棧指針 (1)*/

          *stk--=(INT16U)FP_SEG(pdata);/* 放置向函數(shù)傳遞的參數(shù) (2)*/

          *stk--=(INT16U)FP_OFF(pdata);

          *stk--=(INT16U)FP_SEG(task);/* 函數(shù)返回地址(3)*/

          *stk--=(INT16U)FP_OFF(task);

          *stk--=(INT16U)0x0202;/*SW 設(shè)置為中斷開啟 (4)*/

          *stk--=(INT16U)FP_SEG(task);/* 堆棧頂端放置指向任務(wù)代碼的指針*/

          *stk--=(INT16U)FP_OFF(task);

          *stk--=(INT16U)0xAAAA;/*AX=0xAAAA(5)*/

          *stk--=(INT16U)0xCCCC;/*CX=0xCCCC*/

          *stk--=(INT16U)0xDDDD;/*DX=0xDDDD*/

          *stk--=(INT16U)0xBBBB;/*BX=0xBBBB*/

          *stk--=(INT16U)0x0000;/*SP=0x0000*/

          *stk--=(INT16U)0x1111;/*BP=0x1111*/

          *stk--=(INT16U)0x2222;/*SI=0x2222*/

          *stk--=(INT16U)0x3333;/*DI=0x3333*/

          *stk--=(INT16U)0x4444;/*ES=0x4444*/

          *stk=_DS;/*DS=當(dāng)前CPU的 DS寄存器 (6)*/

          return((void*)stk);

          }

          由于80x86堆棧是16位寬的(以字為單位)[程序清單L9.10(1)],OSTaskStkInit()將創(chuàng)立一個(gè)指向以字為單位內(nèi)存區(qū)域的指針。同時(shí)要求堆棧指針指向空堆棧的頂端。

          筆者使用的BorlandC/C++編譯器配置為用堆棧而不是寄存器來傳送參數(shù)pdata,此時(shí)參數(shù)pdata的段地址和偏移量都將被保存在堆棧中[程序清單L9.10(2)]。

          堆棧中緊接著是任務(wù)函數(shù)的起始地址[程序清單L9.10(3)],理論上,此處應(yīng)該為任務(wù)的返回地址,但在μC/OS-II中,任務(wù)函數(shù)必須為無限循環(huán)結(jié)構(gòu),不能有返回點(diǎn)。

          返回地址下面是狀態(tài)字(SW)[程序清單L9.10(4)], 設(shè)置狀態(tài)字也是為了模擬中斷發(fā)生后的堆棧結(jié)構(gòu)。堆棧中的SW初始化為0x0202,這將使任務(wù)啟動(dòng)后允許中斷發(fā)生;如果設(shè)為0x0002,則任務(wù)啟動(dòng)后將禁止中斷。需要注意的是,如果選擇任務(wù)啟動(dòng)后允許中斷發(fā)生,則所有的任務(wù)運(yùn)行期間中斷都允許;同樣,如果選擇任務(wù)啟動(dòng)后禁止中斷,則所有的任務(wù)都禁止中斷發(fā)生,而不能有所選擇。

          如果確實(shí)需要突破上述限制,可以通過參數(shù)pdata向任務(wù)傳遞希望實(shí)現(xiàn)的中斷狀態(tài)。如果某個(gè)任務(wù)選擇啟動(dòng)后禁止中斷,那么其他的任務(wù)在運(yùn)行的時(shí)候需要重新開啟中斷。同時(shí)還要修改OSTaskIdle()和OSTaskStat()函數(shù),在運(yùn)行時(shí)開啟中斷。如果以上任何一個(gè)環(huán)節(jié)出現(xiàn)問題,系統(tǒng)就會(huì)崩潰。所以筆者還是推薦用戶設(shè)置SW為0x0202,在任務(wù)啟動(dòng)時(shí)開啟中斷。

          堆棧中還要留出各個(gè)寄存器的空間,注意寄存器在堆棧中的位置要和運(yùn)行指令PUSHA,PUSHES,和PUSHDS和壓入堆棧的次序相同。 上述指令在每次進(jìn)入中斷服務(wù)程序時(shí)都會(huì)調(diào)用[程序清單L9.10(5)]。AX,BX,CX,DX,SP,BP,SI,和DI的次序是和指令PUSHA的壓棧次序相同的。如果使用沒有PUSHA指令的8086處理器,就要使用多個(gè)PUSH指令壓入上述寄存器,且順序要與PUSHA相同。 在程序清單L9.10中每個(gè)寄存器被初始化為不同的值, 這是為了調(diào)試方便。

          Borland編譯器支持偽寄存器變量操作,可以用_DS關(guān)鍵字取得CPUDS寄存器的值,程序清單

          L9.10中(6)標(biāo)記處用_DS直接把DS寄存器拷貝到堆棧中。

          堆棧初始化工作結(jié)束后,OSTaskStkInit()返回新的堆棧棧頂指針,OSTaskCreate()或

          OSTaskCreateExt()將指針保存在任務(wù)的OS_TCB中。

          9.05.02 OSTaskCreateHook()

          OS_CPU_C.C中未定義,此函數(shù)為用戶定義。

          9.05.03 OSTaskDelHook()

          OS_CPU_C.C中未定義,此函數(shù)為用戶定義。

          9.05.04 OSTaskSwHook()

          OS_CPU_C.C中未定義,此函數(shù)為用戶定義。其用法請(qǐng)參考例程3。

          9.05.05 OSTaskStatHook()



          關(guān)鍵詞:

          評(píng)論


          相關(guān)推薦

          技術(shù)專區(qū)

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();