?

基于工控單片機的嵌入式操作系統核心的設計

2010-09-03 08:25黃彩虹何明華
關鍵詞:信號量休眠狀態堆棧

陳 康, 黃彩虹, 何明華

(1.福州大學 自動化與電氣工程學院,福建 福州 350007;2.華僑大學 信息科學與工程學院,福建 廈門 361021)

嵌入式實時操作系統(real-time operating system,簡寫為RTOS)具有比較好的擴展性,且通過任務這個概念把原有的應用程序分割成若干部分。由于采用可剝奪型的內核,與前后臺系統相比,實時性得到了更好的保證,所以 RTOS在嵌入式系統中得到了廣泛的應用[1]。但現有的幾個RTOS(Linux,VxWorks,uC/OS-II)代碼量比較大,占用較多的內存資源,對CPU硬件要求較高,目前在工業控制領域中廣泛應用的CPU如8051系列由于其內存較小(片內存儲器僅128個字節),速度較慢(外接晶振為12 M),無法使用這些操作系統。為提高工控軟件的開發效率,考慮用C語言為其設計一種RTOS。

1 實 現

1.1 搶先式算法

由于目前RTOS常用算法有搶先式與非搶先式2種??紤]到自動控制領域對實時性要求較高,使用搶先式算法,它的主要特點是處于就緒態的最高優先級任務始終運行并占用著CPU,優點在于能夠迅速對外部事件做出響應。在這個內核里,可以把所有的任務分為掛起、就緒、運行、休眠、被中斷態5種狀態,這些狀態可以進行相互間的轉換,如圖1所示。某一時刻任何任務都處于5種狀態之一,操作系統就是要根據設計者的需要實現這些狀態之間的轉化,并查找就緒任務中優先級最高的使其迅速進入運行狀態。

圖1 任務狀態機

由于單片機內存容量較小,只有128字節,為盡可能地節省內存,在這個操作系統中使用函數數組定義作為基本的數據結構[2],其代碼為:

Void(*processTable[TOTALTASK])()。

這個數據結構里定義了各個任務的函數入口地址,主要是為了減少內存占用,精簡代碼量,還可通過各個任務在數組中的索引來確定它的優先級,索引值越大,優先級越高[3]。另外,為區分任務的不同狀態,建立了2個狀態表。

(1)休眠狀態表。用若干個字節來表示(取決于任務數),每位表示一個任務,0表示休眠狀態,1表示非休眠狀態(包括就緒和掛起態)。

(2)掛起任務狀態表。用若干個字節來表示,每位表示一個任務,休眠狀態表的該位為1的情況下,掛起任務狀態表中的1表示就緒狀態,0表示掛起狀態??赏ㄟ^狀態表中任務所在字節的位置來確定其優先級,位數越高的,優先級越高。

實時操作系統運行時需要找到優先級最高的就緒態任務并讓其運行,這就是任務調度,可以通過休眠狀態表與掛起狀態表相與得到任務就緒狀態表,在此表中1為就緒態,0為非就緒態。位數越高的任務代表的優先級越高(例如,bit 7所代表任務的優先級高于bit 6),可以通過函數task-Sched()查找就緒狀態表中位數最高的1以確定下一個進入運行的任務,其實現如圖2所示??驁D中的變量NextRunningTask做為全局變量代表下一個即將運行的任務。此外還需按照圖1根據實際需要對相關的任務進行切換。就是通過程序把休眠狀態表或掛起狀態表相應的位設為1或0來實現狀態的轉換,以setReady(int i)為例畫出框圖說明如何將掛起態的任務轉換為就緒態,i代表想要變成就緒態的任務號,如圖3所示。此外還有些狀態轉換的函數與此類似,8051有2個外部中斷,在中斷中可以調用這些程序來改變任務的狀態,由于篇幅的原因不具體介紹。

1.2 上下文切換方法

運行的任務切換為其它狀態或其它狀態切換成運行態,不僅僅需要狀態表的變換,還需要堆棧進行上下文切換。所謂的上下文切換是指將當前任務的現場數據推入堆棧,將要運行任務的現場數據從堆棧里恢復。根據不同CPU以及片內存儲器大小的差異用不同的方法建立堆棧,一種是為每個任務建立大小相同的任務堆棧,其容量按現場數據的最大值計算。另一種是每個任務的堆棧大小根據實際需要來確定。這2種方法都需要把每個任務的棧底或棧頂的位置保存在堆棧數組stackPos中。針對2種建立堆棧的方法,其上下文切換的方法也是不同的。

方法1是推入當前任務的現場數據后,根據棧底位置+(要運行的任務號*每個任務堆棧占用的字節數),直接找到將要運行任務的堆棧地址,將堆棧指針指向該處即可推出數據。該種方法的優點是不需要移動其它任務的現場數據,其任務切換較快,缺點也很明顯,內存浪費較大,所以它比較適合TI的DSP2407等大內存系統。

圖2 任務調度

圖3 setReady框圖

方法2則將多余的內存保存在當前任務堆棧中,推入現場數據后,移動當前任務與將要運行任務之間所有的現場數據,使堆棧中的多余空間保存在將要運行的任務上,將堆棧指針指向將要運行任務的堆棧[4]。具體實現如圖 4、圖5所示。由于現場數據與CPU的型號有很大的關系,所以這一段需要用匯編語言編寫[5]。使用方法2時內存利用率較高,但是由于需要移動多個任務的現場數據,切換速度較慢,比較適合8051等小內存系統。這2種方法在系統中是通過編譯開關來實現選擇編譯的。

圖4 任務堆棧切換方法1

圖5 任務堆棧切換方法2

1.3 優先級反轉問題

對于共享設備與共享資源,信號量的操作是不可避免的。在進入共享資源前,任務必須獲取一個信號量;一旦共享設備使用完成,那么該設備必須釋放信號量[6]。其它想進入的任務必須等待,直到某個任務釋放信號量。在信號量使用時經常會遇到優先級反轉的問題。所謂優先級反轉是指高優先級任務需要等待低優先級任務釋放資源,而低優先級任務又正在等待中等優先級任務的現象叫做優先級反轉。

舉個例子,任務1優先級高于任務2,任務2優先級高于任務3。任務1和任務2處于掛起狀態,等待某一事件的發生,任務3正在運行。此時,任務3要使用其共享資源。使用共享資源之前,首先必須得到該資源的信號量(Semaphore)。任務3得到了該信號量,并開始使用該共享資源。由于任務1優先級高,它等待的事件到來之后剝奪了任務3的CPU使用權,任務1開始運行。運行過程中任務1也要使用任務3正在使用著的資源,由于該資源的信號量還被任務3占用著,任務1只能進入掛起狀態,等待任務3釋放該信號量,任務3得以繼續運行。

由于任務2的優先級高于任務3,當任務2等待的事件發生后,任務2剝奪了任務3的CPU的使用權并開始運行,處理它該處理的事件,直到處理完之后將CPU控制權還給任務3。

任務3接著運行,直到釋放該共享資源的信號量。直到此時,實時內核知道有個高優先級的任務在等待這個信號量,內核做任務切換,使任務1得到該信號量并接著運行,在這種情況下,任務1優先級實際降到了任務3的優先級水平。因為任務1要等,等到任務3釋放占有的共享資源。由于任務2剝奪任務3的CPU使用權,使任務1的狀況更加惡化,任務2使任務1增加了額外的延遲時間。任務1和任務2的優先級發生了反轉[1]。

為解決此問題,可采用優先級繼承算法來實現,就是將任務3的優先級提高到任務1來。由于是在單片機上運行這個操作系統,為減少代碼量及其內存,通過修改備份后的就緒狀態表與堆棧位置數組stackPos來實現,就是當一個任務因為信號量進入掛起狀態時,檢測是否有低優先級的任務正在占用該信號量,如果有修改堆棧位置數組中的高優先級任務的堆棧位置指向,使其指向占用該資源低優先級任務的堆棧位置,實現優先級繼承,在任務運行完后通過信號量釋放來恢復原有的堆棧位置數組,恢復原有的優先級,重新設定休眠狀態表與就緒狀態表,具體如圖6、圖7所示,該種方法只需占用極少的內存,很適合在8051這種小內存的系統上運行。另外在該操作系統中各個任務間的通信可通過信息隊列或郵箱來實現,這與信號量的實現相似。需要指出的是上述介紹的都是操作系統的臨界代碼,進入臨界代碼需要關中斷,完成臨界代碼后再打開中斷,只有這樣才能保證系統的正常運行[7,8]。

圖6 帶有優先級繼承的信號量掛起

圖7 信號量釋放

1.4 可重入函數

搶先式內核需要可重入的函數,所以在編寫前,還需要了解編譯環境是否易于產生可重入函數。如果采用8051的C語言編譯器KEil C作為編譯環境,一般情況下會產生不可重入函數,因為它把局部變量也放在系統內存的固定位置中,就相當于全局變量一樣,在這種情況下必須采取一些方法來產生一個可重入函數,例如減少函數自變量個數,使得KEil C將每個自變量放入寄存器,而不是放在內存中來產生可重入函數。

2 測試與結果

在8051系列單片機上使用該操作系統對房間溫度濕度控制系統編寫程序。該控制系統通過溫度與濕度傳感器檢測房間中的實際溫度,在出現偏差時通過空調與加濕機來保持房間溫度濕度恒定,并顯示溫度與濕度的實際值。在此系統中將溫度顯示、濕度顯示、溫度控制與濕度控制分別作為控制任務,按照優先級從高到低寫入到數組函數中。由于其中2個任務共用一個顯示,所以必須使用信號量函數。通過在上下文切換與信號量函數中設置斷點,觀察掛起狀態表與將要運行任務等變量,確定各個任務,可根據優先級的高低自動進行切換,堆棧中的現場數據推入與推出正確,溫度與濕度可用7段代碼依次顯示。另外為測試優先級反轉,修改了程序,將濕度顯示與溫度控制對調。在濕度顯示時觸發溫度控制使其運行,通過在信號量等待函數中設置斷點,這時觀察到優先級發生轉換,證明了優先級繼承算法使任務的實時響應獲得了極大的提高。由于該操作系統大小不到3 k字節,對硬件的要求極低,占用的系統資源較少,使該控制系統能夠順利運行,最關鍵的是由于在設計過程中使用RTOS,設計調試時間由原來的 1個月縮短為1周,提高了設計效率。

[1]Labrosse J J.嵌入式實時操作系統μ C/OS[M].邵貝貝,譯.北京:北京航天航空大學出版社,2003:120-125.

[2]譚浩強.C程序設計[M].第2版.北京:清華大學出版社,2003:102-105.

[3]馬忠梅,籍順心,張 凱,等.單片機的C語言應用程序設計[M].第 3版.北京:北京航空航天大學出版社,2003:45-47.

[4]彭良清.μ C/OS-II任務堆棧處理的一種改進方法[J].單片機與嵌入式系統應用,2008,(5):115-120.

[5]卡馬爾.嵌入式體系結構編程與設計[M].北京:清華大學出版社,2005:89-98.

[6]Allworth S T.Introduction to real-time software desig n[M].New York :Springer-Verlag,1981:31-32.

[7]Douglas C.Operating-system design:the XINU approach[M].Englewood Cliffs,New Jersey:Prentice-Hall,1984:6-9.

[8]Wood M,Barrett T.A real-time primer[J].Embedded Systems Prog ramming,1990,3(2):20-28.

猜你喜歡
信號量休眠狀態堆棧
基于行為監測的嵌入式操作系統堆棧溢出測試*
水稻種子休眠調控與破除技術的發展
癌細胞從“休眠”到“蘇醒”重大謎團獲解
Nucleus PLUS操作系統信號量機制的研究與測試
基于堆棧自編碼降維的武器裝備體系效能預測
誘導休眠狀態未來可用于幫助對抗癌癥
基于分離樹的能量有效數據轉發機制*
硬件信號量在多核處理器核間通信中的應用
μC/OS- -III對信號量的改進
Linux操作系統信號量機制的實時化改造
91香蕉高清国产线观看免费-97夜夜澡人人爽人人喊a-99久久久无码国产精品9-国产亚洲日韩欧美综合