秦玉蒙, 王婭男, 邱春玲
(吉林大學 儀器科學與電氣工程學院,吉林 長春130026)
在單片機開發系統中,經常用到定時控制,比如延遲控制、超時控制和計時控制等。尤其是多任務處理中,對定時的需求很大。為了獲得所需要的定時,需求準確而穩定的時間基準,產生這種時間準確通常有兩種方法:硬件定時器和軟件定時器。
單片機都含有硬件定時器,它通過對時鐘脈沖的計數實現定時,定時準確,使用方便,但是單片機內部的硬件定時器數量有限,軟件定時器應運而生,它以硬件定時器的定時中斷為基礎,利用軟件方法來實現,定時更長,使用更靈活。
在應用單片機進行多任務系統開發時,定時器工作方式復雜,受限于單片機內部資源數量,實時操作系統中的軟件定時器無法直接套用;多人開發時,代碼風格因人而異,定時器的管理無法統一,給多人協作開發和后期維護帶來了不便。因此,設計并實現一種軟件定時器,在單個硬件定時器上實現了多個軟件定時器,代碼經過封裝標準化,并根據單片機的特性進行了優化,可作為一個獨立模塊嵌入到單片機軟件系統中;所有代碼都符合ANSI-C 標準,易讀易用,在多任務系統開發中可以大大簡化軟件設計復雜性,方便多人協作開發和后期維護。
在實時操作系統中,硬件定時器以固定的頻率運行,形成周期性的中斷,稱之為“時鐘節拍”[1-7]。本軟件定時器以時鐘節拍為定時基準源,通過軟件計數的方式實現對時鐘節拍的累計,當達到預設值時,執行預設任務。
本軟件定時器模塊由函數、數據結構和宏組成,可作為一個獨立模塊嵌入到單片機軟件架構中,如圖1所示。硬件定時器驅動層為軟件定時器提供穩定的時鐘節拍,驅動處理算法有序運行。由于單片機的RAM容量有限,動態鏈表作數據結構顯然很不適合,選用數組、輔助變量和宏定義配合的方式作為數據結構,既滿足了軟件定時器數量可控,又滿足了動態使用需求。接口函數統一管理所有軟件定時器,方便使用。此外,考慮到數據臨界態和用戶輸入的不確定性,添加了加鎖保護和輸入校驗,提高了軟件的魯棒性[8-10]。

圖1 軟件定時器模塊架構
由于軟件定時器數量較多,所以為軟件定時器設計了一個核心數據結構SoftwareTimer,其定義如下:

每個SoftwareTimer 結構的實例定義了一個軟件定時器。其中:Count 用于設置時鐘節拍計數值;CallBackFuction 是計時時間到后執行的回調函數指針,其類型為函數指針類型,對function 的定義如下:
typedef void (* function )(void );
本軟件定時器數量缺省配置為8,通過數組進行管理,其定義如下:
struct SoftwareTimer Block[Sum];
define Sum 8 //軟件定時器數量
雖然軟件定時器從存儲結構上是靜態的,但是在設計時考慮到動態使用的需求,將軟件定時器設計為先激活后使用,用完即回收。因此,定義了一個就緒表變量,用來標記8 個定時器的ID 號和工作狀態,其定義如下:
uchar State = 0;
軟件定時器的處理算法在時鐘節拍內執行,其軟件流程圖如圖2 所示,在時鐘節拍中,對已開啟的軟件定時器的時鐘節拍計數值減1,并判斷時鐘節拍計數值是否溢出,如果溢出,表明定時時間到,立即執行回調函數,并更新就緒表,在操作就緒表時,不允許有更高級的中斷進入操作軟件定時器,所以在處理過程中需要加鎖保護。本軟件定時器的處理算法通過函數TimerTickTask 實現,通過此函數對已開啟的軟件定時器進行上述處理,其代碼定義如下:


圖2 軟件定時器處理算法流程圖
本軟件定時器提供了標準的接口函數,軟件定時器接口函數包括軟件定時器啟動函數SoftwareTimerStart 和軟件定時器關閉函數SoftwareTimerStop。SoftwareTimerStart 函數流程如圖3所示,通過該函數可以開啟一個軟件定時器,如果無可用軟件定時器,即開啟失敗,返回錯誤碼。如果開啟成功,進行時鐘節拍計數值和回調函數初始化,并把該軟件定時器在就緒表中的位置作為ID 號返回。

圖3 啟動流程圖
通過SoftwareTimerStop 函數可以對該軟件定時器進行關閉操作,并返回已計量的時鐘節拍數,其執行流程如圖4 所示。

圖4 關閉流程圖
注意,軟件定時器受時鐘節拍驅動,節拍精度直接影響軟件定時器的精度。回調函數直接在時鐘節拍中運行,如果回調函數執行時間超過時鐘節拍間隔時長,就會造成后續節拍的滯后,不僅影響定時精度,而且影響系統正常運行。所以回調函數的執行時間不能超過時鐘節拍間隔時長,如果回調函數需要較長時間運行,可以在回調函數中置位一個標志位,在大循環中掃描該標志位執行所需任務。
軟件定時器開啟和關閉的理想時間段為時鐘節拍所用硬件定時器的中斷處理函數執行期間[11-12]。但實際上軟件定時器的開啟和關閉時刻是隨機的,在操作某個軟件定時器時,由于開啟時刻和關閉時刻與時鐘節拍沒有對準,會存在誤差,且其值可能是一個時鐘節拍內的任意值,該誤差稱為啟動誤差和關閉誤差。如圖5 所示,時刻1 和時刻3 為時鐘節拍所用硬件定時器的中斷處理起始時刻。如果在時刻2 開啟了一個軟件定時器,其啟動誤差即為時刻1 與時刻2 之間的時間差值。如果在時刻4 停止了該軟件定時器,其關閉誤差即為時刻3 與時刻4 之間的時間差值。

圖5 誤差分析
啟動誤差和關閉誤差無法完全消除,可以采用更快的時鐘節拍來減小誤差,但是這樣會導致CPU 頻繁進出中斷,CPU 利用率不高,應根據實際應用的需要,選擇合適的時鐘節拍,將這兩種誤差控制在可接受的范圍內。
在基于時鐘節拍的前后臺軟件架構中,兩個時鐘節拍之間的時間間隔稱為“時間片”[13],為了分析軟件定時器的算法效率,以“時間片占用率”來進行衡量。可以根據時間片占用率及應用需求設定合適的時鐘節拍,獲取更高的定時精度[14-16]。
時間片占用率 = TimerTickTask 函數運行時間/時間片。
測試環境:Keil C51 V4.11,芯片類型AT89C55,時鐘頻率設置為24 MHz。
測試方法:時間片設置為5 ms。在開啟時鐘節拍所用硬件定時器之前,開啟軟件定時器,定時時間設置為5 ms,回調函數為空函數。時鐘節拍中只有TimerTickTask 函數。使用KEIL 軟件仿真得到測試結果如表1 所示。
由測試結果可知,每增加一個軟件定時器,TimerTickTask 函數運行時間增加約為45 μs,時間片占用率增加約為0.9%;AT89C55 在24 MHz 時鐘下的指令處理速度為2 MIPS,性能有限,在8 個軟件定時器全部開啟的極端情況下,時間片占用率不到8%,可見該軟件定時器算法具有較高的執行效率。在更高級的單片機中可將時間片進一步縮小,保證性能的同時可獲得更高的定時精度。

表1 性能測試
本軟件定時器使用靈活,應用場合廣泛,例如,按鍵音、串口讀超時判斷和界面顯示超時判斷等。如果兩個軟件定時器嵌套使用,還可實現不等長度的周期性定時。
在單片機開發系統,尤其是51 內核單片機,在串口開發中,需要一個硬件定時器提供波特率,還需要一個硬件定時器用于串口讀超時判斷,造成硬件定時器資源緊張,本軟件定時器可以很好解決這個問題,首先根據需要編寫ReadTimerOut 函數,此函數時是在串口讀超時后要執行的任務。設時間片為1 ms,串口數據流中斷10 ms 即認為超時,其判斷代碼如下:

在上述代碼中TimerID 變量有兩個作用,一是記錄定時器ID,二是用來判斷串口數據流的起始字節。如果是起始字節,開啟一個軟件定時器,再次讀串口時關閉上一次開啟的軟件定時器,開啟一個軟件定時器重新開始計時。
本軟件定時器靈活使用,會把復雜設計變得簡單,在工控領域,經過用到不等長周期性定時用于測試設備。設時間片為1 ms,利用本軟件定時器實現工作1 s停3 s 這樣的不等長周期性定時的代碼如下:

TaskStart 函數開啟任務后,開啟一個軟件定時器,定時1 s 后回調TaskSop 函數,TaskSop 函數關閉任務,開啟一個軟件定時器,定時3 s 后調TaskStart 函數。如此循環嵌套實現所需功能。
將實時操作系統中的定時器軟件管理思想引入單片機前后臺軟件架構中,設計并實現了一個軟件定時器模塊,本模塊邏輯清楚,分層設計,并針對單片機進行了特殊優化;采用動態激活的方式使用,軟件定時器用完即回收,便于重復使用。誤差分析和性能測試表明本軟件定時器實用高效。利用本軟件定時器開發多任務系統,不僅可以節約硬件定時器資源,而且可以大大加快單片機系統的開發進程。
[1] Labrosse J. Inside Real-Time Kernels[C]//Conference Proceedings of Embedded Systems Conference East. 1997:205-214.
[2] Labrosse J J. Microc/OS-II[M]. R & D Books,1998.
[3] Krishna C M. Real ‐ Time Systems[M]. John Wiley & Sons,Inc.,1999.
[4] Pont M J. Patterns for time-triggered embedded systems[J]. New York:Person Edueation,2001.
[5] Dick R P,Lakshminarayana G,Raghunathan A,et al. Analysis of power dissipation in embedded systems using real-time operating systems[J]. Computer-Aided Design of Integrated Circuits and Systems,IEEE Transactions on,2003,22(5):615-627.
[6] 李小群,趙慧斌,葉以民,等. RFRTOS:基于Linux 的實時操作系統[J].軟件學報,2003,14(7):203-1212.
[7] Love R,Are S H W,Linus A C,et al. Linux Kernel Development Second Edition[M]. 2004.
[8] 李 凡,盧社階,邱 鵬,等. 在嵌入式應用中增強Linux 實時性的方法研究[J]. 華中科技大學學報:自然科學版,2005,33(2):82-85.
[9] 嚴蔚敏,吳偉民. 數據結構[M]. 北京:清華大學出版社,1992.
[10] Shaffer C A. Solutions Manual:A Practical Introduction to Data Structures and Algorithm Analysis[M]. N. J.:Prentice Hall,1997.
[11] 趙 霞,郭 耀,雷志勇,等. 基于模擬器的嵌入式操作系統能耗估算與分析[J]. 電子學報,2008,36(2):209-215.
[12] 周 博,王石記,邱衛東,等. SHUM-UCOS:基于統一多任務模型可重構系統的實時操作系統[J]. 計算機學報,2006,29(2):208-218.
[13] 徐久強,劉 輝,朱 劍,等. 一種基于時間片的搶占控制模型[J]. 東北大學學報(自然科學版),2009,11:1570-1573.
[14] 陳 俐,殷承良. 基于混合定時調度的車輛AMT 控制系統的實時性分析[J]. 上海交通大學學報,2008,41(2):256-261.
[15] 郭占社,孟永鋼,蘇才鈞. 基于Windows 的精確定時技術及其在工程中的應用[J]. 哈爾濱工業大學學報,2005,37(12):1717-1720.
[16] Holenderski M,van den Heuvel M,Bril R J,et al. Grasp:Tracing,visualizing and measuring the behavior of real-time systems[C]//International Workshop on Analysis Tools and Methodologies for Embedded and Real-time Systems (WATERS). 2010:37-42.