作者:賈水英楊建紅謝宏偉
引言
μVision是德國Keil公司開發的單片機IDE軟體,最初主要用於8051系列單片機,目前也有支援ARM系列單片機的專用版本MDK-ARM。RTX51是其內建的運行於8051系列單片機上的小型多任務即時作業系統,可用來設計具有即時性要求的多任務軟體。RTx51有2個版本:RTX51 Tiny和RTX51 Full。RTX51 Tiny是RTX51 Full的子集。RTX51 Tiny自身僅佔用900位元組左右的程式儲存空間,可以很容易地運行在沒有外部擴充儲存空間的8051單片機系統上。
目前在8051系列單片機上使用多任務即時作業系統,絕大多數應用都選擇了RTX51 Tiny。本文就其在實際應用中的一些概念和具體問題進行了探討。RTX51Tiny核心的版本為1.06,C51編譯器版本為7.50。
1 RTX51 Tiny中有沒有主程式的問題
一般來說,C語言中主程式就是指main()函數。參考文獻[3]稱RTX51 Tiny沒有主程式,其實這是一種誤解。實際上RTX51 Tiny的主程式是以彙編代碼的形式位於Rtx51tny.A51檔案中,在程式的最後:
在通常的應用中,一般都是將RTX51 Tiny核心做成lib檔案,使用的時候直接調用相應的系統函數即可,在應用程式中沒有體現,使用者也無需關心。這造成了一部分使用者的誤解,以為RTX51沒有main()函數。
另外,參考文獻[4]提到,使用RTX51 Timy時使用者程式中不需要包含main()函數,它會自動從任務0開始運行;如果使用者程式中包含main()函數,則需要利用os_cre-ate_task()函數來啟動RTX51即時作業系統。這段話前一部分是正確的,前文也對此做瞭解釋。但後一部分則值得商榷。在RTX51作業系統中,是存在main()函數的,只不過存在於庫檔案RTX51tny.lib之中,使用者的應用程式中不能再包含main()函數。任務0為應用程式的入口,所有其他任務都在任務0中建立。
2 儲存空間佔用
RTX51tiny作業系統小巧精悍,能極大地提高程式的可讀性及可維護性,但也佔用了一定的儲存空間。這是一種以空間換取效能的辦法。由於RTX51作業系統佔用了儲存空間,如果不外擴儲存空間,則至少需要8052系列以上的單片機。在Keil內建的協助檔案GS51.PDF中,對比做了詳細的介紹。其中有關儲存空間方面的資訊是:RAM需求為7位元組DATA,外加每個任務佔用3位元組IDATA空間;代碼量(即ROM)約900位元組。
3 關於使用os_wait()函數定時的問題
RTX51 Tiny核心中,TIMESHARING的預設值為5,以外部時鐘振蕩器頻率為12 MHz計算,任務輪轉時間為50 ms。如果想定時1個30 ms的時間間隔,在任務比較重時,使用os_wait(K_TMO,3,0)將得不到準確的結果。因為別的任務的執行時間已經佔據了1個任務的輪轉時間50 ms,超出了20 ms。如果任務比較多,同時任務的負擔都比較重,相應的誤差時間會更大。
RTX51 Tiny使用os_wait()函數作定時,只有當系統任務較輕時,使用os_wait(K_IVL,count,0)和os_wait(K_TMO,count,0)才能達到一致的效果;而在任務較重時,使用這2個函數所得到的結果會有很大差別。參考文獻[5]對此做了詳細介紹,此處只作簡單補充。
事實上,使用者程式的運行是陣發性的,在一段時間內任務會比較繁忙,而在另一段時間可能會處於空閑狀態。如果使用os_wait(K_TMO,count,0)函數進行定時,則在不同的時間段會得到不同的結果。所以,要實現較為精確和穩定的定時,最好還是使用os_wait(K_IVL,count,O)函數,而不是os_wait(K_TMO,count,O)。除非延時時間很長,如超過了所有任務的輪轉時間總和,os_wait(K_IVL,count,O)和os_wait(K_TM0,count,O)的延時效果才會相同。
4 INT_CLOCK的設定與延時計算
RTX5 Tiny中與延時相關的2個參數為INT_CLOCK和TIMESHARING。先來看Rtx5ltny.A51來源程式中的一段:
從上面的程式段可以看出,RTX51 Tiny核心使用Timer0作為硬體定時器,Timer0工作在方式1(16位計數方式)。因此,如果想增加定時器溢出時間,可以修改INl_CLOCK的定義。但不能無限制地增大,最大隻能到216一1,即65 535。如果單片機採用12 MHz的晶振,則每次定時器溢出的最長時間為65.535ms。如果INT_CLOCK的定義值超過了這個資料,並不能達到預期的結果。例如,把INT_CLOCK定義為100 000(Oxl86AOH),那麼實際上INT_CLOCK為34 464(Ox86AOH)。本來是想定時100
ms,實際上得到的卻是34.4 ms。因此,在設定具體延時時間時必須仔細計算。
系統的任務輪轉時間等於每次定時器溢出時間與TIMESHARING的乘積。因此,要將系統的任務輪轉時間設定為特殊的時間長度,可以通過INT_CLOCK與TIME-SHARING兩個參數的不同組合來實現。不過在一般的應用當中,都是採用其系統的預設值,無須修改。
5 修改核心配置的基本過程
RTX51TNY.A51為RTX51 Tiny的核心程式,包括所有的函數定義,不需要改動。通常改動的是配置程式CONF_TNY.A51,主要內容如下。
INT_REGBANK EQU 1:定時器中斷時使用的寄存器組預設值是寄存器組1,一般無需改動。
INT_CLOCK EQU 10000:硬體定時器零TimerO的溢出時間,即1個滴答(tick)的時間長度。預設值是10 000個機器周期。對於傳統的MCS51單片機來說,1個機器周期為12個刻度。如果採用12 MHz的晶振,那麼每個機器周期將為lμs,1個滴答的時間長度為10 ms。
TIMESHARING EQU5:定義時間片輪轉(round-robin timeout)時間,預設值為5個滴答(1個滴答為Tim—erO的1次溢出)。如果INT_CLOCK為10 000,時鐘頻率為12 MHz,則1個時間片的輪轉時間為50 ms,即每個任務每次最大可獲得的執行時間為50 ms。如果TIME-SHARING定義為O,則禁止時間片輪轉。
RAMTOP EQU 0FFH:定義CPU堆棧可使用的最高RAM地址,預設值為地址OFFH(256-1)。FREE_STACK EQU 20:配置堆棧大小為20位元組,預設值為20(經常需要改動)。使用者可根據自己的實際需要進行修改,一般情況下需要配置或修改的內容主要有INT_CLOCK、TIMESHAR-ING、FREE_STACK。
6 其他需要注意的問題
①堆棧的大小要設定得合適,太大浪費資源,太小又會出現堆棧錯誤。在系統運行中,有時會發現程式總在某一處死迴圈,而從邏輯上卻常常分析不出問題之所在,很有可能是堆疊溢位。在conf_tny.a51中有個非常重要的宏STACK_ERROR,其來源程式如下:
通過模擬發現,程式會在此處死迴圈。
(Conf_tny.a51)FREE_STACK EQU 20:配置堆棧大小為20位元組,預設值為20。選擇合適的堆棧大小,即設定合適的FREE_STACK值,可達到最佳效果。
②同堆棧一樣,輪轉時間片的長度也不宜設定得過大或過小。設定得過大,則一些期間較短的事件無法響應。如果輪轉時間設定得過小,則CPU的很大一部分功能被消耗在任務切換上了;如果任務多,處理時間長,無疑會無形中增加系統的負擔。需要根據具體的需要權衡。
結 語
本文從具體的核心分析出發,對使用RTX51 Tiny作業系統時的一些概念和應用中的問題進行了闡述和澄清,使大家對RTX5l Tiny有更為清晰的認識。RTX51 Tiny微作業系統的使用,可以使使用者把更多的精力關注在應用本身而無需考慮複雜的底層驅動。而且整個應用軟體系統結構清晰,維護方便,可節省大量的時間和人力。當程式比較複雜時,它的優點就體現得更明顯。然而,由於硬體資源及其自身的限制,對於功能複雜、要求較高的應用來說,就顯得有些吃力了,使用者需要自己編寫功能擴充程式。無論如何,它仍然是8位單片機應用中作業系統的首選。