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

          新聞中心

          EEPW首頁(yè) > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > MC68K的C編譯器實(shí)現(xiàn)μC/OS-II向MC68K移值解析方案

          MC68K的C編譯器實(shí)現(xiàn)μC/OS-II向MC68K移值解析方案

          作者: 時(shí)間:2012-06-19 來(lái)源:網(wǎng)絡(luò) 收藏

          3.OS_CPU32.ASM文件

          μ的移植需要用戶改寫OS_CPU_A.ASM中的4個(gè)函數(shù):OSStartHighRdy()、OSCtxSw()、OSIntCtxSw()和OSTickISR()。

          (1)OSStartHighRdy()函數(shù)

          該函數(shù)由OSStart()函數(shù)調(diào)用,功能是運(yùn)行優(yōu)先級(jí)最高的就緒態(tài)任務(wù)。在調(diào)用OSStart() 之前,用戶必須先調(diào)用OSInit(),并且已經(jīng)至少創(chuàng)建了一個(gè)任務(wù)。為啟動(dòng)任務(wù),OSStartHighRdy()首先找到當(dāng)前就緒的優(yōu)先級(jí)最高的任務(wù),OSTCBHighRdy中保存有優(yōu)先級(jí)最高任務(wù)的任務(wù)控制塊(TCB)的地址,并從任務(wù)的任務(wù)控制塊中找到指向堆棧的指針,然后運(yùn)行指令 MOVEM.L(A7)+,A0-A6/D0-D7,從堆棧中彈出全部寄存器的內(nèi)容,運(yùn)行RTE中斷返回。由于任務(wù)創(chuàng)建時(shí)堆棧的結(jié)構(gòu)就是按中斷捕撈堆棧結(jié)構(gòu)初始化的,執(zhí)行RET指令后就切換到了新任務(wù)。有關(guān)μC/OS- II的任務(wù)切換機(jī)制,請(qǐng)參考系列計(jì)座(3).

          OSStartHighRdy的匯編代碼如下:

          _OSStarHighRdy

          MOVE.L(_OSTCBHighRdy),A1

          ;獲取最高優(yōu)先級(jí)就緒任務(wù)的TCB地址

          MOVE.L A1,(_OSTCBCur)

          MOVE.L (A1),A7 ;取得堆棧指針

          MOVEM.L (A7)+,A0-A6/D0-D7

          RTE ;中斷返回,切換任務(wù)

          (2)OSCtxSw( )函數(shù)

          OSCtxSw( )是一個(gè)任務(wù)級(jí)的任務(wù)切換函數(shù)(在任務(wù)中調(diào)用,區(qū)別于在中斷程序中調(diào)用的OSIntCtxSw(),在系統(tǒng)上,通過(guò)執(zhí)行一條軟中斷指令來(lái)任務(wù)切換。軟中斷向量指向函數(shù),而該函數(shù)的執(zhí)行結(jié)構(gòu)可能造成系統(tǒng)任務(wù)重新調(diào)度(例如,試圖喚醒一個(gè)優(yōu)先級(jí)更高的任務(wù)),則在函數(shù)的末尾會(huì)調(diào)用OSSched (),OSSched()將查找當(dāng)前就緒的優(yōu)先級(jí)最高的任務(wù)。如果不是當(dāng)前任務(wù),則判斷是否需要進(jìn)行任務(wù)調(diào)度,再找到該任務(wù)控制塊OS_TCB的地址,并將該地址拷貝到變量OSTCBHighRdy中,然后通過(guò)寵OS_TASK_SW()執(zhí)行軟中斷,進(jìn)行任務(wù)切換。在此過(guò)程中,變量OSTCBCur始終包含一個(gè)指向當(dāng)前運(yùn)行任務(wù)OS_TCB的指針。OSCtxSw()的匯編代碼如下:

          _OSCtxSw

          MOVEM.L A0-A6/D0-D7,-(A7) ;存儲(chǔ)當(dāng)前任務(wù)環(huán)境

          MOVE.L (_OSTCBCur),A1 ;保存當(dāng)前任務(wù)TCB指針

          MOVE.L A7,(A1)

          MOVE.L (_OSTCBHighRdy),A1 ;獲取最高優(yōu)先級(jí)就緒任務(wù)的TCB地址

          MOVE.L A1,(_OSTCBCur) ;將就緒任務(wù)設(shè)置為當(dāng)前運(yùn)行任務(wù)

          MOVE.L (A1),A7 ;取得新任務(wù)的堆棧指針

          MOVEM.L (A7)+,A0-A6/D0-D7 ;

          RTE ;中斷返回,切換任務(wù)

          (3)OSIntCtxSw()函數(shù)

          在μC/OS -II中,由于中斷的產(chǎn)生可能會(huì)引起任務(wù)切換,在中斷服務(wù)程序的最后會(huì)調(diào)用OSICntExit()函數(shù)檢查任務(wù)就緒狀態(tài)。如果需要進(jìn)行任務(wù)切換,將調(diào)用 OSIntCtxSw(),所以,OSIntCtxSw()又稱為中斷級(jí)的任務(wù)切換函數(shù)。由于在調(diào)用OSIntCtxSw()之前已經(jīng)發(fā)生了中斷, OSIntCtxSw()默認(rèn)CPU寄存器已經(jīng)保存在被中斷任務(wù)的堆棧了。OSIntCtxSw()的代碼與OSCtxSw()的大部分相同,不同之處是:第一,由于中斷已經(jīng)發(fā)生,此處不需要再保存CPU寄存器;第二,OSIntCtxSw()需要調(diào)整堆棧指針,去掉堆棧中一些不需要的內(nèi)容,以使堆棧中包含任務(wù)的運(yùn)行環(huán)境。

          _OSIntCtxSw

          ADDA #10,A7 ;忽略掉由于函數(shù)嵌套調(diào)

          ;用而壓入堆棧的內(nèi)容

          MOVE.L (_CSTCBCur),A1 ;在TCB中保存當(dāng)前

          ;任務(wù)的堆棧指針

          MOVE.L A7,(A1)

          MOVE.L (_OSTCBHighRdy),A1

          ;獲取最高優(yōu)先級(jí)就緒任務(wù)的TCB地址

          MOVE.L A1,(_OSTCBCur) ;將就緒任務(wù)設(shè)備為當(dāng)前

          ;運(yùn)行任務(wù)

          MOVE.L (A1),A7 ;取得堆棧指針

          MOVEM.L (A7)+,A0-A6/D0-D7 ;

          RTE ;中斷返回,切換任務(wù)

          (4)OSTickISR()函數(shù)

          在μ中,當(dāng)調(diào)用OSStart()啟動(dòng)多任務(wù)環(huán)境后,時(shí)鐘中斷非常重要。在時(shí)鐘中斷中處理所有與定時(shí)相關(guān)的工作,如任務(wù)的延時(shí)、等待操作等等。在時(shí)鐘中斷中將查詢處于等待狀態(tài)的任務(wù),判斷是否延時(shí)結(jié)束,以重新進(jìn)行任務(wù)調(diào)度。



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