?? ucosii操作系統移植筆記.txt
字號:
uCOSII操作系統移植筆記
筆記一:
今天粗略的看了一下周立功關于uc/osII在lpc2104上的移植方面的說明,這之中印象最深的應該是irq中斷和軟中斷方面的處理,由于arm芯片的特殊性(擁有7種處理器模式),即每種處理器模式都有自己的堆棧,這樣在處理堆棧的時候就會相應的麻煩一些。
在響應異常時,該移植計劃在初始代碼里面比在沒有操作系統的初始代碼多了irq的處理,移植里面的irq處理多了由匯編語言編寫的對任務環境的保存,沒操作系統的中的任務環境的保存都是由在產生irq中斷是用c語言聲明的__irq關鍵字來完成了,移植中irq中斷不能采用__irq關鍵字,因為c語言不能保證堆棧結構,而uc/osII必須要保證堆棧結構。除此之外,相對于沒操作系統的初始代碼,基本上是沒有什么改變。
在uc/osII的任務切換中,采用了arm里面的軟中斷指令swi來執行,對于非中斷性的任務切換(如掛起和等待信號量的時候)uc/osII是采用了宏os_task_sw()來執行的,然后聯系到osctxsw()函數來完成任務切換,而遇到中斷情況時在返回是需要任務切換是則采用了osintctxsw()來執行的,在周立功的移植當中,他把osctxsw()與osintctxsw()合二為一了,統一采用osintctxsw()來實現。之所以這樣搞的原因是任務進行切換的時候,都必須進入軟中斷的狀態,而對于軟中斷的異常響應代碼已經將任務的環境變量進行了保存,從而也不需要像osctxsw()里面規定的那樣對將環境變量進行保存。
這是我看今天看了移植說明后所理解的東西,當然還得細致的對代碼進行分析,特別是osintctxsw()代碼的分析,雖然移植的代碼大體是遵從了uc/osII的編碼規范,但對于arm的多種處理器模式移植代碼有特別的改變,以實現cpu時間和ram的利用。
筆記二:
感覺osintctxsw()這個函數需要進行仔細的解讀,好多其他函數都與他由關聯,而在uc/osII中的原型是沒有這樣的情況的,我想出現這個現象的原因是由于arm芯片的特殊性(擁有7種處理器模式),這樣在處理堆棧的時候就會相應的麻煩一些。
移植的osintctxsw()函數由兩個部分,以標號osintctxsw_1作為分界點。
關于osintctxsw_1以下的程序,LPC2100_FAQ.pdf文檔里面的第126問作了詳細的解釋,即實現的是任務的恢復運行。
而osintctxsw_1以上的程序段的功能如周立功的移植說明里面的解釋:前面的關于中斷與c語言的接口已經說明,寄存器應當保存到任務的堆棧中,但為了節省cpu時間和ram的空間,僅在必要的時候才將寄存器保存到任務的堆棧,OSTCBCur->OSTCBStkPtr=SP也是在必要的時候才執行,這一段代碼就是來處理這兩件事情的。(即將任務的環境變量由模式堆棧復制到當前任務的任務堆棧中,對照周立功書上374頁與378頁的兩個堆棧圖來理解這部分代碼就很清晰明了了)。
理解了以上關于osintctxsw()兩個部分代碼的解釋,也就不難理解為什么有些函數都來引用osintctxsw()了,就以__OSStartHighRdy中引用osintctxsw_1為例來說明,他在代碼的末尾最后引用osintctxsw_1,就是要實現任務的恢復運行(從新任務堆棧中恢復所有寄存器,執行中斷返回指令)。
最后對于osintctxsw()要注意的是,這個函數的移植并非是簡單的ucos中的osintctxsw()原型的聲明,因為在移植的代碼中,要用到osintctxsw()必須得引用OS_TASK_SW()宏才可以,這樣就引出了在ucos的c代碼函數osintexit()時調用osintctxsw()函數該怎么辦這個問題了。
周立功的移植是在includes.h中定義一個宏osintctxsw(),由于這個宏在c語言中使用,所以不會與匯編的函數osintctxsw沖突,宏定義如下所示:
#define osintctxsw()
{
OSEnterSum=0;
return;
}
而中斷返回時要執行的任務切換這一行為實際上已經在irq異常響應代碼中由它來完成了,也就是說移植完成后osintctxsw()起的作用已經不是ucos的作者想起的作用了。
現在感覺有點不明白的是OSEnterSum所起的作用,ucos原型中并不存在這一變量。
筆記三:
今天接著昨天的疑問看的,OSEnterSum所起的作用也搞清楚了,周立功的移植中對于開關中斷,即OS_ENTER_CRITICAL()與OS_EXIT_CRITICAL()選用的方法是2(即OS_CRITICAL_METHOD=2),而在ucos的原型中關于OS_CRITICAL_METHOD=2的說明可以清楚的知道,它是想實現在先將關中斷前將中斷狀態保存到內存中,然后關中斷,爾后,恢復保存在堆棧中的關中斷之前的中斷狀態,這樣的說明清楚的說明了關中斷是可以嵌套的,而參數OSEnterSum的出現正是為了實現關中斷的嵌套而設計的。移植的關于OS_ENTER_CRITICAL()與OS_EXIT_CRITICAL()的說明周立功的書上說的很清楚了。而昨天看的定義的宏osintctxsw()之所以要用OSEnterSum是因為調用osintctxsw()的肯定是osintexit()函數,而調用osintexit()肯定是處于開中斷狀態的,則OSEnterSum肯定等于0。所以這個時候必須把OSEnterSum調整為0(看到這里我又產生了另外的一個問題,就是還有其他的地方引用OSEnterSum變量嗎?不然,即使不將OSEnterSum也應該沒什么關系)。
今天看到關于OSTaskInit()的移植有值得注意的地方,堆棧必須按設計好的進行初始化(周立功書上374頁堆棧圖)。還有任務的數據指針是由r0來傳遞的。
還有移植增加的特點的函數,感覺還是很好理解的。
至此,移植的理論部分基本上完成,接下來的應該是實踐環節了,即進行操作系統在板上的調試。
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -