揭毅
(德賽工業(yè)研究院,惠州 516000)
在MCU系統(tǒng)程序設(shè)計(jì)中,常常遇到測試工程師反映我們的按鍵反應(yīng)不靈敏,或是系統(tǒng)對外部的信號(hào)響應(yīng)慢,實(shí)時(shí)性差。如果不是程序模塊設(shè)計(jì)問題,那我們就要考慮系統(tǒng)程序設(shè)計(jì)上的實(shí)時(shí)性問題了。但是如果僅僅在系統(tǒng)程序設(shè)計(jì)上片面地考慮實(shí)時(shí)性問題,而忽略了任務(wù)均衡性問題,那么系統(tǒng)又可能出現(xiàn)有的模塊程序響應(yīng)快、有的模塊程序反應(yīng)慢的問題。為了解決這些問題,下面就我在車載娛樂系統(tǒng)程序設(shè)計(jì)工作中的經(jīng)驗(yàn)與大家聊聊。
實(shí)時(shí)性很容易被多數(shù)人誤認(rèn)為就是“快”的意思。其實(shí),“快”只是實(shí)時(shí)性的一個(gè)特征,而且是相對的——是相對于任務(wù)需求而言的。
無論你的個(gè)人電腦是采用了何種“奔X”CPU,也無論該CPU的主頻是幾個(gè)G,只要你安裝的是XP操作系統(tǒng),那么它就是一個(gè)非實(shí)時(shí)系統(tǒng)。相反,一個(gè)8位的MCU,哪怕主頻只有4MHz,也可以構(gòu)成一個(gè)實(shí)時(shí)系統(tǒng)。
實(shí)時(shí)或是非實(shí)時(shí),與CPU的速度并無直接關(guān)系,而完全取決于操作系統(tǒng)或程序架構(gòu)。眾所周知,操作系統(tǒng)(OS)主要包括三大組成部分:進(jìn)程調(diào)度、內(nèi)存管理和文件系統(tǒng)。其中,進(jìn)程調(diào)度決定了系統(tǒng)的實(shí)時(shí)性。
實(shí)時(shí)系統(tǒng)的本質(zhì)特征在于:所有任務(wù)的響應(yīng)時(shí)間和執(zhí)行時(shí)間都是可以根據(jù)各任務(wù)的需求進(jìn)行設(shè)計(jì),并且事先就能被預(yù)知。在一個(gè)實(shí)時(shí)系統(tǒng)上,我們可以根據(jù)需求分析的結(jié)果,對各個(gè)任務(wù)進(jìn)行合理的、滿足要求的“實(shí)時(shí)性”設(shè)計(jì),使得最終完成的程序能夠按照預(yù)定規(guī)則運(yùn)行,并達(dá)到各種實(shí)時(shí)性指標(biāo)的要求。基于這種定位,我認(rèn)為在程序設(shè)計(jì)時(shí),不頻繁使用“計(jì)算器”的工程師通常不會(huì)有“實(shí)時(shí)性”的概念,這種工程師設(shè)計(jì)出的系統(tǒng)也很難講是實(shí)時(shí)系統(tǒng),至少,實(shí)時(shí)性指標(biāo)是不能足以保證的。至此,大家應(yīng)該可以理解我為何經(jīng)常會(huì)問一些同事:你有無購買計(jì)算器?微軟的工程師編程時(shí)無需使用計(jì)算器——因?yàn)樗麄冊O(shè)計(jì)的是非實(shí)時(shí)系統(tǒng),但我們卻需要——因?yàn)槲覀冊O(shè)計(jì)的是實(shí)時(shí)系統(tǒng)。區(qū)別就在于此!
在單片機(jī)系統(tǒng)中,很多情況下是不使用OS的。實(shí)際上,在沒有OS的多任務(wù)系統(tǒng)中,進(jìn)程調(diào)度的工作是由應(yīng)用軟件工程師自身編制程序來實(shí)現(xiàn)的。那么,自身編制的進(jìn)程調(diào)度系統(tǒng)是否一定就是實(shí)時(shí)系統(tǒng)呢?我的回答是:不一定!關(guān)鍵在于你如何設(shè)計(jì)進(jìn)程調(diào)度程序和如何合理安排各種任務(wù)。
如果你設(shè)計(jì)出的系統(tǒng)是非實(shí)時(shí)的,而實(shí)際各個(gè)任務(wù)的需求又是實(shí)時(shí)的,那么,系統(tǒng)就一定會(huì)存在問題。特別是在“任務(wù)并發(fā)”時(shí),程序一定會(huì)出問題,甚至出現(xiàn)一些稀奇古怪的現(xiàn)象。
我經(jīng)常聽到軟件部的兄弟抱怨:MCU的速度不夠快;內(nèi)存沖突;需要提高主頻等等。
實(shí)際上,大家可以測試一下我們目前系統(tǒng)程序中MCU的平均運(yùn)行效率。我可以肯定地說,在我們目前的系統(tǒng)中,MCU的平均運(yùn)行效率絕沒有超過60%,很可能為20%~30%,甚至在10%左右。由于MCU的主振蕩器一直在工作,它的ALU一刻也不會(huì)停止運(yùn)行,那么,它在干什么呢?實(shí)際上,MCU在反復(fù)執(zhí)行著一個(gè)沒有任何實(shí)際任務(wù)的“死循環(huán)”,等待中斷和時(shí)隙的到來——在絕大部分時(shí)間,MCU被閑置。
工程師所抱怨的速度不夠,通常是指在任務(wù)并發(fā)時(shí),發(fā)生消息丟失、內(nèi)存/堆棧溢出或任務(wù)執(zhí)行被延遲等現(xiàn)象。
通常,單片機(jī)系統(tǒng)是一個(gè)多任務(wù)系統(tǒng)。這里的多任務(wù)總是表現(xiàn)為“多功能”,而非“高性能”。否則,我們就不會(huì)選擇采用MCU,尤其是8位MCU——因?yàn)?位MCU的性能總是不會(huì)太高的。基于MCU的這種低性能,通常不會(huì)將其用于大流量信號(hào)的處理,而是只作控制用。控制類信號(hào)的處理不同于大流量信號(hào)的處理,它僅需占用極少的ALU資源。
對于上面講到的這種“忙的時(shí)候忙不過來,閑的時(shí)候閑得要命”的情況,就引出了“任務(wù)均衡”的問題。任務(wù)均衡性設(shè)計(jì),是任何實(shí)時(shí)嵌入式系統(tǒng)設(shè)計(jì)的關(guān)鍵工作之一。
在與軟件工程師討論一些程序設(shè)計(jì)細(xì)節(jié)時(shí),發(fā)現(xiàn)我們的工程師們總是追求“快”。其實(shí),如果每個(gè)任務(wù)的處理都要“快”,而且是無量綱的“快”,那么任務(wù)均衡性問題也就無從談起了。進(jìn)行任務(wù)均衡性設(shè)計(jì)的實(shí)質(zhì)是:讓真正需要快速處理的任務(wù)快起來,讓無需快速處理的任務(wù)慢下來,最終達(dá)到任務(wù)均衡的目的,從而提高M(jìn)CU的使用效率。這里的“慢”就是為了“快”,沒有“慢”也就沒有“快”。
無論是處理“快”的任務(wù),還是處理“慢”的任務(wù),都需要滿足系統(tǒng)性能的要求,否則所實(shí)現(xiàn)的系統(tǒng)就是一個(gè)不合格的系統(tǒng),或是一個(gè)不健康的系統(tǒng)。因此,在需求分析和程序架構(gòu)設(shè)計(jì)階段,對各個(gè)任務(wù)的時(shí)間指標(biāo)作出恰當(dāng)?shù)姆治龊秃侠淼亩x就顯得非常重要。下面我舉幾個(gè)例子來說明。
根據(jù)人的反應(yīng)速度和操作特點(diǎn),對于儀表類設(shè)備,按鍵的捕獲時(shí)間在30~50ms左右已經(jīng)足夠。如果一味地追求“快”,不僅浪費(fèi)系統(tǒng)資源,而且還會(huì)對鍵抖性能要求過高。一般,我們會(huì)設(shè)計(jì)一個(gè)20ms的鍵掃描周期,用兩次鍵掃值進(jìn)行按鍵消抖,那么鍵捕獲時(shí)間不會(huì)超過40 ms——你會(huì)發(fā)現(xiàn)此時(shí)的按鍵操作已經(jīng)很靈敏了。在任務(wù)比較繁重的系統(tǒng)中,我們還可以將鍵捕獲和鍵響應(yīng)的處理節(jié)拍區(qū)分開來。通常,鍵響應(yīng)時(shí)間只要能保持在100~200ms以內(nèi),已經(jīng)不會(huì)使人感受到慢,有時(shí)這種延遲反而會(huì)給人更舒適的感受。
但是,對于旋轉(zhuǎn)編碼器這類器件,雖然我們可以將其歸并為“鍵輸入”范疇,但是它的脈沖寬度是比較窄的(可能會(huì)到幾百個(gè)μs),建議采用中斷的方式加以捕捉。但是,必須充分注意的是,檢測速度快,并不意味著接收脈沖的速度也需要快;否則,在測試者高速旋轉(zhuǎn)編碼器時(shí),會(huì)產(chǎn)生頻繁中斷,很可能會(huì)影響到其他任務(wù)的實(shí)時(shí)性。實(shí)際上,我們接收的旋轉(zhuǎn)脈沖是用于數(shù)值增減和顯示Level的,每100ms跳動(dòng)一格已經(jīng)是“目不暇接”了。因此,每中斷一次時(shí),最好能將該中斷關(guān)閉,然后再在100ms時(shí)隙中將該中斷打開。
我們都清楚,通信接收的響應(yīng)速度都是要求很高的,通常都是用中斷來進(jìn)行接收處理。但是,一個(gè)完整報(bào)文(幀)的解析就不需要處理得很快了,完全可以安排在一個(gè)相對空閑的時(shí)隙中進(jìn)行處理,而無需在中斷服務(wù)程序中加以處理。中斷服務(wù)程序執(zhí)行時(shí)間的加長,將帶來整個(gè)系統(tǒng)性能的下降。
ACC——對“下升沿”的響應(yīng),要盡量地快(500μs以內(nèi)),最好使用優(yōu)先級(jí)最高的中斷。因?yàn)椋枰獞?yīng)用于快速M(fèi)ute,否則易產(chǎn)生點(diǎn)火POP-NOISE。但是,對“上降沿”的響應(yīng),就無需那么快,500ms就已滿足要求。
Parking——只要求檢測高低電平,而無需檢測邊沿,100ms的掃描周期已經(jīng)足夠。
Illuminance——只要求檢測高低電平,而無需檢測邊沿。由于部分車輛采用了PWM調(diào)光,PWM的頻率也沒有統(tǒng)一標(biāo)準(zhǔn),建議硬件上采用檢波電路,以減小對MCU資源的占用。在采用硬件檢波電路以后,軟件的檢測掃描周期為100ms就已足夠。
Tele-Mute——只要求檢測高低電平,而無需檢測邊沿。100ms的掃描檢測周期已經(jīng)足夠。
Reverse——同Tele-Mute。
下面介紹一種在無OS環(huán)境下,實(shí)現(xiàn)實(shí)時(shí)性和任務(wù)均衡性的設(shè)計(jì)方法。
首先介紹一下“時(shí)隙”的概念,時(shí)隙的英文叫法是“Time slot”,也就是“時(shí)間間隙”的意思。我們通常會(huì)選擇一個(gè)基本時(shí)隙去掃描并執(zhí)行任務(wù),有些任務(wù)每個(gè)基本時(shí)隙都去掃描,有些任務(wù)則無需每個(gè)基本時(shí)隙都去掃描,而是若干個(gè)基本時(shí)隙再去掃描一次。用時(shí)隙去同步任務(wù)的執(zhí)行,用時(shí)隙的長短來區(qū)分任務(wù)的輕重緩急。
基本時(shí)隙用定時(shí)器中斷來產(chǎn)生,其他時(shí)隙用基本時(shí)隙的整數(shù)倍來產(chǎn)生,并盡量在中斷服務(wù)程序中實(shí)現(xiàn)。時(shí)隙定時(shí)器是最重要的系統(tǒng)定時(shí)器,不僅要保持它的準(zhǔn)確性,還需盡量簡潔,使其保持最高效運(yùn)行。
基本時(shí)隙的設(shè)計(jì)最為重要,它與其他各時(shí)隙的設(shè)計(jì)都須根據(jù)實(shí)際系統(tǒng)的要求來進(jìn)行。基本時(shí)隙的長度決定了任務(wù)的最快掃描周期,從實(shí)時(shí)性要求來講,很顯然是越短越好。但是,基本時(shí)隙的過短將會(huì)對整個(gè)軟件系統(tǒng)的架構(gòu)和性能產(chǎn)生重大不利影響,限制系統(tǒng)整體性能的發(fā)揮。
基本時(shí)隙的選擇原則是,在滿足實(shí)時(shí)性要求的前提下,盡量長一些。對于個(gè)別需要更快響應(yīng)速度的激勵(lì),采用中斷的方式來響應(yīng)。
這里已經(jīng)引發(fā)了程序架構(gòu)設(shè)計(jì)中的一個(gè)矛盾,即:基本時(shí)隙盡量長,盡量少開中斷,中斷服務(wù)程序盡量短。其實(shí),這完全符合技術(shù)的特點(diǎn),需要全方位地綜合考慮。選擇不是唯一性的,但是,對一個(gè)具體的系統(tǒng),最佳方案可能只有一個(gè)。
以上是筆者對實(shí)時(shí)性和任務(wù)均衡性程序設(shè)計(jì)上的一些看法。基于以上方法來編寫MCU程序可以大大提高程序的運(yùn)行效率和系統(tǒng)實(shí)時(shí)性,改善任務(wù)的均衡性,并減少程序異常運(yùn)行等問題的發(fā)生。