全局中断_实时性迷思(3)——80%时间屏蔽了中断,实时性还有救么?
【寫在前面的話】
在本系列的第一篇文章《實時性迷思(1)——快是優點么?》中,我們介紹了實時性的基本模型:
并得出兩個重要的結論:
實時性只關注“是否能在實時性窗口內完成對應事件的處理”,而與事件處理的快慢無直接關系;
從應用整體的角度來看,實時性窗口內越靠前的時間越珍貴;
當應用在運行時有大比例的時間屏蔽了中斷,系統的實時性還有救么?
當應該頻繁的開關中斷,系統的實時性還有救么?
【從一個例子開始】
復雜的理論不必多說,我們首先來看一個極端的例子:int?main(void){ ... while(1) {????????__disable_irq();??????//!?關閉全局中斷????????do_some_work();???????//!?經過測量,占用了7個周期????????__enable_irq(); //! 開啟全局中斷????}}
這個代碼本身并不復雜,事實上,它在前后臺系統中非常典型。作為例子,這里有幾個要點需要首先明確:
這只是一個例子,它存在的意義是為我們提供一個討論的起點,請不必在意和猜測它在實際應用中的意義;
假設 __disable_irq() 消耗一個周期;當它執行完成后,全局中斷會被關閉;
假設 __enable_irq() 消耗一個周期;當它執行完成后,全局中斷會被打開;
假設 這里的 while(1) {} 導致的循環跳轉(無條件跳轉)會消耗一個周期(其實Cortex-M3/M4就是這樣);
函數 do_some_work() 消耗7個周期。
從執行 do_some_work() 開始到 __enable_irq() 執行結束,總共 7+1=8 個周期——在這期間,中斷都是被屏蔽的;
自從“無條件跳轉”開始到 __disable_irq() 執行結束,總共 1+1=2 個周期——在這期間,全局中斷是可以被響應的;
整個循環占用10個周期:其中8個周期中斷被屏蔽。又由于這是main函數內的超級循環,因此可以大體推斷出:在整個應用執行期間 80% 的時間中斷是被屏蔽的。
這符合本文一開頭所提出的兩個問題的條件,即:大比例的時間屏蔽了中斷?和?頻繁的開關中斷。
【是時候搬出模型了……】
那么,在這個例子中,實時性會受到怎樣的影響呢?我們不妨結合模型,看一個最壞情況,即,剛開始執行 do_some_work() 的時候,某一事件發生——實時性窗口開始計時:再圖中,由于中斷被屏蔽而導致事件無法被響應,這段時間被稱為“事件無法響應時間”,結合模型容易得出:結論1:
只要“事件無法響應時間”與“處理事件所需時間”的總和超過了“實時性窗口”,當前事件處理的實時性就無法保證了。
正如前面幾篇文章一再強調的那樣,時間的實時性窗口是來自物理世界的,基于物理時間計算的絕對值。這里CPU周期其實是一個相對值——系統頻率越高,8個周期對應的物理時間就越短;系統頻率越低,8個周期對應的物理時間就越長(當然還要考慮處理事件所需的時間也會隨著頻率的變化而變化)。對現今大部分動輒幾十兆赫茲,或者上百兆赫茲的單片機系統來說,8個周期可能連1us都不到(作為參考當系統是 8MHz時,8個周期正好1us)。結論2:
當且僅當系統頻率已知時,我們才能根據CPU的周期數計算出“事件無法響應時間”和“處理時間所需時間”——也只有都換算成相同單位時,與實時性窗口的比較才有意義。
一個應用中往往有多個具有實時性要求的事件,在已知系統頻率的情況下,我們可以將“事件無法響應時間” 拉到每一個實時性窗口中一一比較,只要任何一個不滿足,我們就可以宣告整個系統實時性的破產。然而,如果所有單獨比較的結果都令人滿意,我們是否就可以宣告:由屏蔽中斷所導致的“事件無法響應時間”足夠短,不會對系統的實時性造成影響呢?——高興的太早了。
【CPU資源磨刀霍霍……】
一個實時性應用中往往不止一個事件有實時性要求,因此,判斷系統的實時性是否所有保證從來都不是只單純的在每一個實時性窗口內做比較就能解決的。就像上面所說的那樣,由于屏蔽中斷的時候,任何事件都可能發生,因此,由屏蔽導致的“事件無法響應時間”必須帶入到每一個實時性窗口中去進行比較。僅僅只是這樣,仍然不夠。由于CPU資源有限,我們還必須確認在“最差情況下”扣除了中斷屏蔽期間所占用的CPU資源后,仍然有足夠的CPU資源來滿足其它實時性窗口的需求。關于如何計算每個實時性任務的CPU資源占用,可以通過文章《實時性迷思(2)——“時間片輪轉”的沙子》來復習,仍然有印象的同學可以直接看下面這張圖片來喚醒記憶:這里有一個誤區非常值得闡明:即,在前面的例子中,我們說“系統有80%的時間都在屏蔽中斷”,這是否意味著,屏蔽中斷占用了 80%的CPU資源——只剩下20%的CPU時間用于實時性處理了呢?也許你愣住了。但答案很類似腦經急轉彎——并不是這樣,因為在我們討論的前后臺系統中,其實隱含了一個假設——實時性的響應是通過中斷來進行的——既然是中斷,就是可搶占的,因此,即便8個周期內無法響應,只要那一個周期開了口子,CPU的資源就被實時性處理程序搶走了。
思考這個問題,實際上直接引出了第三個重要的結論:
結論3:
“事件無法響應時間” 不看積累下來的總量,而只看單次最大能連續拖延實時性相應多久。
要理解這個結論,其實并不困難。這就好比PWM,在較長的時間內,占空比相同而頻率不同的PMW,其高電平的總時間是相同的(占空比相同);但頻率不同的PMW實際上每次高電平的持續時間是不同的——頻率越低,當然每個周期內高電平時間越長。套用到屏蔽中斷對實時性的影響上來說:推論1:
屏蔽中斷并不可怕,哪怕積累下來的時間占比很大,只要每次屏蔽的時間足夠短,就能有效的減小對系統實時性的影響——換句話說,高頻率的開關中斷很可能還是有益實時性的(關鍵還看推論2)。
推論2:
如果系統中存多個對實時性響應的屏蔽(比如裸機中的屏蔽中斷、RTOS中的關閉調度),根據木桶原理,只以單次屏蔽時間最長的那個來評估對系統實時性的影響。
【問出正確的問題】
文章的開始部分,我們提出了兩個問題:
當應用在運行時有大比例的時間屏蔽了中斷,系統的實時性還有救么?
當應該頻繁的開關中斷,系統的實時性還有救么?
已知當前系統中,最大的中斷屏蔽時間長度為 Tmask;系統頻率為 F;對已有的實時性事件處理來說,系統的實時性是否仍然能夠得到保證?
對每一個具體的系統來說,求解過程也很簡單:
由于屏蔽中斷的時候,任何實時性事件都有可能發生,因此我們要重新計算系統的CPU資源占用——評估它是否接近或超過了 100%
計算每一個實時性任務的CPU占用時,都要把“事件無法響應”Tmask?加到 “處理事件所需時間” 里——作為分子去除以作為分母的“實時性窗口”:
【小結】
如果上述討論讓你頭疼,那么記住下面的內容基本都不會有錯:
頻繁開關中斷并不可怕;
別管關閉中斷的時間總比例是多大,這沒意義;
找到系統中關閉中斷時間最長的那個代碼,測量它占用的時間——它才是罪魁禍首;
使用“以小換大策略”——借助一切可能的手段,使用小的屏蔽來替換掉長時間的屏蔽——無論是屏蔽中斷還是RTOS里的屏蔽調度,道理都是一樣的。
RTOS里盡可能用 mutex,而不要長時間關調度——因為mutex幾乎是RTOS可以提供的屏蔽時間最短的手段了。
裸機自求多福。
總結
以上是生活随笔為你收集整理的全局中断_实时性迷思(3)——80%时间屏蔽了中断,实时性还有救么?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 发那科机器人寄存器Ar_发那科机器人与T
- 下一篇: 破拆机器人_灭火体验,消防炮、排烟机器人