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