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

          新聞中心

          UCOS移植心得

          作者: 時間:2016-11-27 來源:網(wǎng)絡(luò) 收藏
          移植UCOS之前,你首先應(yīng)該做好三件事:


          1.弄懂UCOS,這是誰都知道的哦 ^_^

          2. 弄懂你想要移植到的硬件平臺

          3. 清楚你使用的編譯器是如何處理函數(shù)的局部變量和怎么樣處理函數(shù)間的參數(shù)傳遞

          這里多廢話幾句第三點:在UCOS里面,所有函數(shù)都要求具有重入性(除了OSSTAR()外,只有這個函數(shù)我覺得是不需要的,它僅僅使用了一次);重入性是多任務(wù)的基礎(chǔ),而所謂重入性從函數(shù)而言就是它的變量的保存問題,在中斷這個函數(shù)的執(zhí)行時它使用的變量需要得到保存,以便返回后的執(zhí)行是正確的,就我使用的編譯器而言,它通過堆棧傳遞函數(shù)參數(shù),

          重入性問題就很容易解決拉,在中斷任務(wù)時,它的參數(shù)已經(jīng)在堆棧里面了,只要你保存好CPU寄存器和堆棧指針SP就好

          而如果你使用的是KEIL的話就比較復(fù)雜拉,首先KEIL是51單片機的東西,51只有很少的存儲空間,KEIL的重入性是通過設(shè)立模擬棧實現(xiàn)的,當任務(wù)中斷執(zhí)行時,你不僅需要保存CPU寄存器,還要保存模擬棧的內(nèi)容,特別是51的SP尋址能力不強,只有8位,不能在64K的空間自移動,而UCOS比較大,KEIL編譯時只能用大規(guī)模方式,這就意味著所有的全局變量都會保存在片外空間,而SP無法訪問到,你需要設(shè)立一個公共的系統(tǒng)棧,保存正在運行的任務(wù)的數(shù)據(jù),在任務(wù)切換時把這個系統(tǒng)棧的內(nèi)容拷貝到它的任務(wù)棧里,操作比較繁瑣

          注意系統(tǒng)的初始化問題,我在第一個任務(wù)里調(diào)用了系統(tǒng)初始化函數(shù),在里面開中斷允許.

          任務(wù)可以是關(guān)中斷時被掛起,也可以是開中斷時被掛起,那么在任務(wù)切換回來后如何保證它的中斷狀況呢?問題可以通過給每個任務(wù)設(shè)置一個中斷計數(shù)器解決,并初始化為 0,記錄每個任務(wù)的開關(guān)中斷次數(shù),關(guān)一次中斷加 1,開一次中斷減 1, 在任務(wù)調(diào)度的時候保存當前任務(wù)的中斷計數(shù)器,切換到新任務(wù)時查看新任務(wù)的中斷計數(shù)器,如果為 0就開中斷返回,不然就直接返回(任務(wù)級切換是在關(guān)中斷下進行的);而對于中斷級任務(wù)調(diào)度,肯定是發(fā)生在開中斷情況下的,就要查看是否需要關(guān)中斷處理

          現(xiàn)在開始說我的移植:我移植到的平臺是凌陽公司的SPCE061A 16位單片機,它有2K的RAM,32K的ROM空間,基本上夠用,但不能有太多功能,我在研究了這款片子的資料后,才開始自己的移植,主要是學(xué)了一下它的匯編語言和混合編程以及CPU得硬件方面;在堆棧的問題上我發(fā)現(xiàn)凌陽的SP是16位的,可以尋址64K的空間,不需要設(shè)立系統(tǒng)棧. 在OS_CPU_C.C中注意堆棧的初始化,一定要在任務(wù)切換時嚴格遵守你的初始化時假定的寄存器順序.

          下面開始移植最重要的三個文件:

          OS_CPU_C.C:

          OSTaskStkInit():

          stk=(OS_STK *)ptos;


          *stk--=*((INT16U*)task+1);/*任務(wù)首地址 (PC)*/

          *stk--=0x0000;/*SR(R6) */

          *stk--=0x0000;/*BP(R5) */

          *stk--=0x0000;/*R4*/

          *stk--=0x0000;/*R3*/

          *stk--=0x0000;/*R2*/

          *stk--=0x0000;/*R1*/

          *stk--=0x0000;/*該任務(wù)的中斷狀況計數(shù)器*/

          return((void *)stk);

          別的就是空函數(shù),比較簡單,這里略去

          這個文件比較簡單,唯一要注意的是堆棧初始化函數(shù),像剛剛說到的,你假定的堆棧內(nèi)容必須在任務(wù)切換時嚴格遵守.還有就是定義幾個空函數(shù)

          OS_CPU_A.ASM:

          這個文件呢是移植的關(guān)鍵,需要用匯編語言編寫,(我有個同學(xué)很能噴,認為匯編語言純屬沒用,像這種話千萬不要相信!),在這個文件里,你需要完成UCOS的核心代碼!

          首先是OSStartHighRdy():

          該函數(shù)在系統(tǒng)開始時使最高優(yōu)先級任務(wù)運行,代碼如下:

          _OSStartHighRdy:

          CALL_OSTaskSwHook



          R1=0x0001

          [_OSRunning]=R1



          R1=[_OSTCBCur]

          SP=[R1]

          POP R1 FROM [SP]

          [_InterruptC]=R1//彈出任務(wù)中斷狀況計數(shù)器

          POP R1,R5 FROM [SP]

          RETI

          接著是OSCtxSw():

          完成任務(wù)切換,代碼如下:

          _OSCtxSw:

          PUSH R1,R5 TO [SP]

          R1=[_InterruptC]

          PUSH R1 TO [SP]//保存任務(wù)中斷狀況



          R2=[_OSTCBCur]

          [R2]=SP

          CALL _OSTaskSwHook



          //OSUCBCur=OSTCBHighRdy

          R1=_OSTCBCur

          R2=[_OSTCBHighRdy]

          [R1]=R2



          //OSPrioCur=OSPrioHighRdy

          R1=[_OSPrioHighRdy]

          [_OSPrioCur]=R1



          R1=[_OSTCBHighRdy]

          SP=[R1]

          POP R1 FROM [SP]

          [_InterruptC]=R1//彈出任務(wù)中斷狀況

          CMP R1,0//查看是否需要開中斷

          JNE KAI

          INT IRQ

          KAI: POP R1,R5 FROM [SP]

          RETI

          上一頁 1 2 下一頁

          關(guān)鍵詞: UCOS移植心

          評論


          技術(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); })();