合理設(shè)置MCU滴答 千萬不要累著它
2017年盛夏,北京街頭,晴空萬里,無風。
本文引用地址:http://butianyuan.cn/article/201808/391345.htm近乎凝滯的空氣中一點風都沒有,惱人的知了無停無休地叫著,不疲也不厭,讓人很是懷疑它們的居心。被太陽曬得發(fā)焦的柏油路面熱氣騰騰,像被曬干了肚皮的魚兒一樣無聲地嘶嚎著。呼嘯而過的汽車排著滾燙的尾氣,急匆匆地想要逃離這個世界,偶爾響起的一聲喇叭,就像向太陽求饒一般。地鐵站和周圍的建筑被曬得無精打采的,無可奈何地矗立在似火驕陽的暴曬之下。剛從地鐵站出來的人們行色匆匆,難得悠閑從容的面孔,筆者被裹挾在滾滾人流之中,不由自主地加快著腳步。站在十字路口,一股股熱浪撲面而來,我頂著發(fā)燙的頭皮,在心中一片哀號,“北京真熱??!”
筆者這次頂著大熱天來帝都,是帶著莊嚴而神圣的任務(wù)過來的:給一個車廠做了一款PEPS,領(lǐng)導讓過來做總線測試。
出師不利,測試遇阻
整車廠進行的總線測試包括通信測試、網(wǎng)路管理測試和診斷協(xié)議測試三大塊,通信測試主要包括工作電壓、上升沿、下降沿、采樣點、報文周期準確性、Bus-off后的快速恢復和慢速恢復等測試項,網(wǎng)絡(luò)管理測試主要包括CAN節(jié)點的網(wǎng)絡(luò)建環(huán)、掉線、Bus-off、協(xié)同休眠、本地喚醒和遠程喚醒等測試項,診斷協(xié)議測試主要包括多幀收發(fā)、響應(yīng)超時、診斷會話切換、診斷服務(wù)等測試項。
筆者其實是帶著輕松愉快的心情過來測試的,因為做這款PEPS產(chǎn)品之前做了一款BCM,當時這款BCM已經(jīng)量產(chǎn),而且也在汽車廠進行過總線測試,對比來看,這兩家車廠的測試條目差不多,筆者就把當時BCM上的代碼移植到了這款PEPS上,根據(jù)不同之處進行了相應(yīng)修改。按照紅芯瀏覽器聯(lián)合創(chuàng)始人的說法,雖然用的是開源代碼,但是了解每一行代碼的含義并知道怎么修改,就是自主可控,筆者盤算著,既然BCM的總線測試都通過了,而且我不僅知道怎么修改這些代碼,這些代碼還完全是我自己寫的,所以PEPS這次測試也絕對是可控的,應(yīng)該比較順利。
等到看測試結(jié)果的時候,興沖沖的我仿佛被澆了一頭冷水,有兩項測試沒通過,這兩項測試分別是用優(yōu)先級最高和優(yōu)先級最低的報文填充CAN總線帶寬,讓總線負載率達到100%,在全負荷的情況下檢測PEPS周期發(fā)送報文的時間準確性。我扒拉著這兩項測試條目的測試數(shù)據(jù),眼睛都快看花了,終于發(fā)現(xiàn),確實有一個周期為50ms的報文出現(xiàn)過一次報文漏發(fā)的情況,測試軟件的判斷條件是檢查每個報文連續(xù)兩次發(fā)送的時間間隔,如果時間間隔在45-55ms(報文周期的正負10%)之間,測試通過,反之測試失敗。
中斷頻繁,MCU不堪重負
“不一樣”的宮斗劇《延禧攻略》最近火得不得了,自帶無敵光環(huán)的延禧宮主子魏瓔珞說過,事情來了就不要怕!但是,當我發(fā)現(xiàn)報文周期準確性測試失敗時,心中還是怕怕的,因為我本能地意識到,旅游計劃肯定是泡湯了,總線負載率100%意味著CAN總線接收中斷過于頻繁,測試失敗不是邏輯上的錯誤導致,而是MCU性能限制導致的系統(tǒng)性問題。在換不了MCU的情況下,需要做大量優(yōu)化才能降低MCU的負荷,將有限的性能用在CAN報文接收中斷的處理上和周期報文的發(fā)送上。
科學研究工作是嚴謹?shù)模a(chǎn)品開發(fā)亦是如此,為了更好地量化MCU的負荷,我做了如下分析:
整車廠規(guī)定所有總線報文的數(shù)據(jù)場長度為8個字節(jié),根據(jù)CAN報文格式,一個8字節(jié)數(shù)據(jù)場的CAN報文的位數(shù)為1(幀起始)+ 12(仲裁場)+ 6(控制場)+ 64(數(shù)據(jù)場)+ 16(CRC場)+ 2(應(yīng)答場)+ 7(幀結(jié)尾)=108位。報文之間存在幀間空間INTERFRAME SPACE。幀間包括間歇場、總線空閑的位場。間歇場包括3 個“隱性”的位??偩€空閑的(時間)長度是任意的。
所以,一個8字節(jié)的數(shù)據(jù)幀至少需要(108+3+1)* 位時長的時間,總線波特率為125KHz,位時長為8us,經(jīng)計算得知,一條總線報文的最短時間長度為0.896ms,為了計算方便,按0.9ms計。
在這次測試中,PEPS發(fā)送報文消耗的總線帶寬大約為3%,這就意味著,在總線負載率是100%的情況下,CAN報文接收中斷的周期為0.9/0.97=0.93ms,即,PEPS每隔0.93ms都會觸發(fā)一次CAN接收中斷,執(zhí)行一次中斷服務(wù)程序。由于成本限制,這款PEPS選擇的MCU是一款中檔16位單片機,主頻不過25MHz,卻需要應(yīng)付這么頻繁的中斷,心疼MCU三秒鐘。。。
降低滴答中斷頻率
腫么辦?CAN報文接收中斷服務(wù)程序?qū)懙梅浅:啙?,根本不存在任何?yōu)化空間,這條測試項目制造出100%總線負載率,CAN報文接收中斷頻率就是那么慘無人道地頻繁,也是不可更改,因此,只能從別處下手。
嵌入式系統(tǒng)有大量定時應(yīng)用,所以無論用不用操作系統(tǒng),都會有一個“系統(tǒng)滴答”,它以固定的時間間隔觸發(fā)中斷,為各種定時應(yīng)用提供時間基準。這也是一個頻繁發(fā)生的中斷,我檢查了這款PEPS上的滴答,發(fā)現(xiàn)其周期設(shè)定為了2ms,之所以選擇2ms,主要是出于代碼復用,之前我在BCM上選擇的系統(tǒng)滴答為2ms,它會牽扯到好多定時參數(shù)的設(shè)置,為了把BCM上的一些代碼直接拿到到PEPS上來用,于是也原封不動地把系統(tǒng)滴答設(shè)置成了2ms。
CAN接收中斷周期為0.93ms,滴答中斷周期為2ms,假設(shè)不存在其它任何中斷,系統(tǒng)的綜合中斷周期為0.64ms,那款BCM的MCU主頻為64MHz,是現(xiàn)在這款MCU的25MHz主頻的2.56倍,64MHz 主頻可以順利處理0.64ms周期性中斷,25MHz主頻就卡了殼了。
順著這條思路,筆者將系統(tǒng)滴答設(shè)置成了10ms,在CAN接收中斷周期0.93ms,滴答中斷周期為10ms的條件下,系統(tǒng)綜合中斷周期為0.85ms,將中斷負荷降低了33%。系統(tǒng)滴答修改后好多地方需要進行相應(yīng)修改,這么折騰了兩天,再次進行通信測試,報文周期準確性測試通過,筆者懸著的心才放了下來,至于是不是堪堪通過,MCU負荷的余量是否其實已經(jīng)非常小了,那就非筆者水平能夠判斷了。
滴答更改的性能比較
為了量化滴答由2ms提高至10ms帶來的性能提升,筆者定義了一個32位全局變量,在程序的主循環(huán)體中累加,每執(zhí)行一次主循環(huán)體,該變量加一,然后根據(jù)單位時間(1秒)內(nèi)的主循環(huán)執(zhí)行次數(shù),判斷采用不同滴答的兩個程序的運行效率。
測試發(fā)現(xiàn),滴答設(shè)置為2ms時,每秒執(zhí)行大約22200次循環(huán),滴答設(shè)置為10ms時,每秒執(zhí)行大約25100次循環(huán),效率大約提升了13個百分點。
至于10ms的滴答是否合理,筆者接觸過的ucos和FreeRTOS中的好多移植例程中都把系統(tǒng)滴答設(shè)置成了10ms,足可見10ms的滴答滿足大多數(shù)嵌入式系統(tǒng)的需求。
后記
歸程依然酷暑難耐,由于沒有完成既定的旅游計劃,筆者心中多多少少有那么一丟丟的小遺憾,但是這次測試讓我對中斷、MCU性能又有了更加深刻的認識,也算是收獲滿滿不虛此行了。高鐵窗外的景色飛速向后退去,眼前只模模糊糊地留下一片綠色的影像,旁邊座位上的小姑娘正在嘰嘰喳喳地和媽媽嬉笑打鬧,“如果人們像愛護小孩子那樣愛護MCU,通過合理的設(shè)計減輕它的工作負荷,讓它不要累著,那該是多么美好的機器世界啊。”我不禁暗暗想到。
評論