專注電子技術學習與研究
當前位置:單片機教程網(wǎng) >> MCU設計實例 >> 瀏覽文章

詳解基于51單片機的small rtos(2)

作者:佚名   來源:本站原創(chuàng)   點擊數(shù):  更新時間:2012年01月15日   【字體:

    我們繼續(xù)上篇。上篇我漏了個開總中斷忘說了。
  開中斷。  對了調(diào)試的時候吧任務A的睡眠給隱掉。因為一步一步來學習嘛!  當開了中斷,于是開始執(zhí)行定時器0中斷,定時器中的代碼一個是OSTimeTick();  執(zhí)行任務時間片的分配。這里注意了,我自個寫的時候調(diào)試出現(xiàn)問題才發(fā)現(xiàn)的。他是先判斷是否有時間片,有則--,然后再判斷是否為0為0則 OSIntSendSignal(TaskId)。  OSIntSendSignal就是把任務置為就緒的沒什么,有必要提的就是關中斷和開中斷。這個為了避免產(chǎn)生中斷導致不可預知的錯誤。 然后回到定時器0的中斷服務程序中,執(zhí)行OSIntExit()。然后轉(zhuǎn)到==》OSIntCtxSw ==》  C_OSCtxSw  ==》LoadCtx    然后就切換到任務B ,F(xiàn)在我開始慢慢的分析這幾個函數(shù),因為這里是需要慢慢講解的。首先從原理上講下。定時器中斷時依次把
PC+ACC+B+DPTR+PWD+r0-r7  共15個字節(jié) ,然后OSIntCtxSw 這個函數(shù)會判斷當前任務是空閑任務的還是任務ABC中一個,如果是任務函數(shù)則棧頂指針  sp=sp-4; 如果是空閑的就sp=sp-17 置相應的中斷方式標志位     OSCtxSw  內(nèi)存塊的重新布局。 LoadCtx    加載任務環(huán)境 。 
 現(xiàn)在開始從代碼調(diào)試中看下。 
定時器0中斷前                                                                               

        
 

 中斷后    然后查看  內(nèi)存 按推斷應該是sp-15 個字節(jié)  =i:0x16     如圖   你可以看出 中斷服務程序保存環(huán)境是按什么次序入棧的。帥吧~~~

然后執(zhí)行OSIntExit()壓入    0x0256  

     

 

   15+2 =17個字節(jié)然后  再跳轉(zhuǎn)到 OSIntCtxSw  

  17+2 個字節(jié) =2+13+4

 

 這里開始用51

匯編寫的,這里是經(jīng)常執(zhí)行的代碼必須有效率。 在OSIntCtxSw    判斷當前任務是什么性質(zhì)的,現(xiàn)在這個是任務A隨意是sp=sp-4 并置中斷類型標志位,清任務運行標志位,LMJP  OSCtxSw  首先壓入一個中斷計數(shù),然后開始吧 【前任務+1的存放地址 ----下個任務+1的地址】 這里有個第優(yōu)先級上還存放了個任務就是為符合這個處理方式。吧括號中的數(shù)據(jù)整個搬到上圖sp后面,然后吧修改后的函數(shù)首地址重新分配 OSTsakStackBotton存放   然后把下個任務切換成當前任務,他的內(nèi)存空間就是現(xiàn)在SP ---任務+1之間的空間。  這里的堆棧是從低到高分配的和PC里不一樣。然后還做了個清中斷標志的操作  壓入  LoadCtx    的函數(shù)地址的棧然后RETI 這個主要是清掉中斷標志,然后跳轉(zhuǎn)到環(huán)境加載函數(shù) 。然后LoadCtx    就把堆棧中下個任務的地址直接RET返回給$P于是就切換到下個任務了。 優(yōu)先級低的也差不對這樣處理的。

 

為了模擬跳轉(zhuǎn)到任務B   在中斷前加  extern uint8 OSTaskRuning;  在 OSIntExit(); 前+OSTaskRuning &=~OSMapTbl[0];  這樣就模擬跳轉(zhuǎn)到任務B

  嘿嘿,不好意思 +了那么入棧的數(shù)據(jù)就有變化了。但是數(shù)目應該沒變,我就不重新截圖了。

sp 0x28  ,

OSIntCtxSw 執(zhí)行后SP-4


 

放B的地址可以通過

 


 

看到i:0xF7是存儲的B的首地址,


 

 

數(shù)據(jù)塊應該是 【A+1】-    【B+1】之間的數(shù)據(jù)整個搬到當前sp+1后面 搬移后的內(nèi)存分布 


 

 

后面  中斷計數(shù) 00  +搬過來的B-C間的2個字節(jié) C7  03這個正好是B任務的首地重新修改存放函數(shù)首地址的數(shù)組

 

 
 

這里可以跳轉(zhuǎn)到LoadCtx     吧任務切到任務B中。 

至此通過中斷任務切換已經(jīng)完畢,此時可以向下如果任務中有數(shù)據(jù)在其中,那么這樣做會不會丟失數(shù)據(jù),其實仔細想想就可以了解,不會的。
本例源代碼下載:http://www.torrancerestoration.com/f/small_rtos1.12.1.zip


接下篇:

    這篇就講解信號來模擬軟中斷,切換任務。
     吧上篇的操作權清掉,然后程序到任務A后會通過睡眠信號,進入OSWait()處理。這里程序主動放棄任務的使用CPU的權利 OSClearSignal (),OSSched()來進入到OSCtxSw  這個函數(shù)中,然后他來設置中斷的性質(zhì)標志位。==》C_OSCtxSw  ==》LoadCtx  加載環(huán)境來達到切換任務的目的。
     這個沒上面的那個復雜,就是在LoadCtx  的時候會根據(jù)中斷的標志位來跳過寄存器的恢復。因為軟中段是不會吧寄存器的數(shù)據(jù)保存到堆棧中這是為什么呢?嘿嘿,這個讓我糾結(jié)了半小時,其實很簡單。他這個事主動放棄的,如果再次執(zhí)行就是重新運行這個任務,那么這個任務中用到得數(shù)據(jù)部就全初始化了嗎。嘿嘿,所以沒必要保存寄存器中的數(shù)據(jù)。
     呵呵這個我就不截圖也不具體說了,有了上篇這個應該很快就能看明白。信號量可能更新慢了點,因為本人自己寫的代碼才寫到這里而已,就在出差前才調(diào)試好的。當然我寫的有點亂很多變量都是自起的名字,而且還加了自己想到得一些奇怪的想法的代碼,這代碼我不提供,所以我按RTOS代碼解析每步的。

 

關閉窗口

相關文章