改進(jìn)型時(shí)間觸發(fā)嵌入式系統編程模式
摘要:對于成本敏感的嵌入式系統,通常因為資源有限而難以采用搶先式實(shí)時(shí)多任務(wù)操作系統。傳統的基于超級循環(huán)的前后臺編程方法和基于時(shí)間觸發(fā)的合作式多任務(wù)編程方法對任務(wù)的劃分需要較高的技巧。本文通過(guò)對基于時(shí)間觸發(fā)合作式調度器的改進(jìn),建立了一種適用于小型嵌入式系統的通用編程模式,使這類(lèi)系統的編程變得清晰、簡(jiǎn)單。
關(guān)鍵詞:時(shí)間觸發(fā);合作式調度器;多任務(wù);嵌入式系統;單片機
引言
目前,RTOS特別是搶先式RTOS在嵌入式系統中的應用越來(lái)越廣泛,但是還有很大一部分產(chǎn)品使用是小型單片機。這些系統由于成本的限制,通常資源非常有限,比如ROM往往小丁32 KB,RAM小于2 KB,由于RTOS對每個(gè)任務(wù)都要開(kāi)辟單獨內存區域,存放任務(wù)的上下文和各任務(wù)獨立的堆棧,所以在這種系統中使用RTOS非常勉強。對于這些低成本資源受限系統通常采用“前后臺”(或者叫“超級循環(huán)”)結構進(jìn)行編程,這實(shí)際上是一種事件觸發(fā)的編程模式,當中斷數目較多且系統完成的功能相對復雜時(shí),就會(huì )使系統的程序編寫(xiě)變得非常復雜并使系統運行的可預測性迅速下降。
針對這個(gè)問(wèn)題,Michael J.Pont提出了一種“基于時(shí)間觸發(fā)的編程模式”,這種方法有助于降低CPU的負荷并減少存儲器的使用量,提高系統行為的可預測性,并使程序的結構變得簡(jiǎn)潔。但是在實(shí)際使用中,當系統中不同的任務(wù)對時(shí)間要求差異較大時(shí),“基于時(shí)間觸發(fā)的編程模式”難以給出簡(jiǎn)單有效的解決方案。為此,對“基于時(shí)間觸發(fā)的編程模式”進(jìn)行了改進(jìn),使之適應性更強,可以為成本和資源受限的小型嵌入式系統提供統一且有效的編程模式。
1 傳統編程結構的局限性
當不使用RTOS時(shí),嵌入式軟件通常采用兩種傳統的編程結構進(jìn)行編程,一種叫“前后臺廳式”或者叫“超級循環(huán)結構”,本質(zhì)上是事件觸發(fā)的編程方式;另一種叫時(shí)間觸發(fā)編程模式,Michael J.Pont的“基于時(shí)間觸發(fā)的編程模式”即屬于此。
在實(shí)際工作中,當系統稍微復雜時(shí),會(huì )發(fā)現這兩種方式都有一定局限性,下面以一個(gè)實(shí)際產(chǎn)品設計中遇到的問(wèn)題為例來(lái)說(shuō)明。在設計一個(gè)用于配電柜的壁裝式智能配電儀表時(shí),CPU的程序設計需完成以下任務(wù):
①每半秒對前顯示屏的顯示數據進(jìn)行一次刷新。
②每0.1 s對DI/DO進(jìn)行一次刷新。
③每0.2 s對鍵盤(pán)進(jìn)行一次掃描。
④每半秒對測量數據進(jìn)行一次重新采集和計算。
⑤異步串行口與上位機使用Modhus通信,速率最高1 9 200 bps。
⑥CPU通過(guò)I2C總線(xiàn)與時(shí)鐘芯片和EEPROM通信。
⑦CPU通過(guò)SPI總線(xiàn)與LED數碼管及采集芯片通信。
⑧CPU要對所采集的6路信號進(jìn)行FFT變換。
⑨當系統掉電時(shí),CPU要能快速響應,把當前的電度底數寫(xiě)入EEPROM中。
上述任務(wù)中,任務(wù)⑤和任務(wù)⑨是強實(shí)時(shí)性的,如果對串口的收發(fā)事件得不到及時(shí)響應,接收時(shí)會(huì )導致字節丟失,發(fā)送時(shí)會(huì )導致字節間時(shí)間間隔太大,造成接收方的Modbus幀定界錯誤,對系統掉電事件如果不能及時(shí)響應會(huì )造成EEPROM的寫(xiě)入失敗。其他任務(wù)只要在指定的周期內能得到執行就行,但是任務(wù)⑧比較特殊,使用通常的8位CPU進(jìn)行6種信號的FFT變換,哪怕每種信號只做128點(diǎn)的FFT,運算一次也要好幾秒。下面來(lái)看用傳統編程結構實(shí)現上述設計時(shí)遇到的困擾。
1.1 使用“前后臺方式”進(jìn)行編程
使用“前后臺方式”進(jìn)行編程時(shí),為保證任務(wù)⑤的及時(shí)性,使用了UART中斷,當UART完成一個(gè)字節的收發(fā)后產(chǎn)生中斷,在中斷程序中將接收到的字符保存在接收緩沖區或從發(fā)送緩沖區取下一個(gè)待發(fā)字符裝入UART進(jìn)行發(fā)送,對Modbus協(xié)議的處理可以單獨用一個(gè)任務(wù)在中斷外處理,這保證了巾斷程序的簡(jiǎn)短。為保證任務(wù)⑨響應的及時(shí)性,也必須為它安排一個(gè)中斷。因為當系統掉電時(shí),系統只有不到10 ms的過(guò)渡時(shí)間,系統如果不能在這個(gè)時(shí)間內完成相關(guān)的操作,系統電壓將跌落至有效電壓以下而喪失工作能力。
安排好了后臺的中斷任務(wù)后再來(lái)看看前臺的任務(wù)如何完成。這里遇到的最大的挑戰是對任務(wù)⑧的處理,因為任務(wù)⑧需要的執行時(shí)間太長(cháng)了,簡(jiǎn)單的把它當成一個(gè)任務(wù)處理將影響系統對其他任務(wù)的響應,在超級循環(huán)中的代碼結構如下:
while(1){
任務(wù)①;
任務(wù)②;
……
任務(wù)⑧;
}
評論