1.中斷概述
“中斷”就是當前的任務被更緊要的事件打斷。這些事件如不及時處理可能導致系統(tǒng)故障:
- 例如,UART收到數(shù)據(jù)后不及時取走導致數(shù)據(jù)丟失
- 再來一個更嚴重的:電源故障中斷不及時處理導致系統(tǒng)意外關機
- 話說回來,并不是所有中斷都必須實時響應。例如,UART發(fā)送完畢后會發(fā)中斷通知CPU,但是晚些處理也只是導致吞吐能力降低。
中斷也是一種CPU時間復用模型
- CPU暫停當前正執(zhí)行的程序(后臺)并保存反映當前CPU處理狀態(tài)的一些寄存器——“中斷現(xiàn)場”(Context),轉而處理待響應的事件(前臺),處理完成后恢復“現(xiàn)場”并繼續(xù)原先執(zhí)行的程序。
- 因為CPU很快,所以看起來像是并行地處理了后臺與前臺任務
中斷的概念源于生活,低于生活:
- 放學回家做作業(yè)->吃晚飯->接電話->繼續(xù)吃晚飯->吃完晚飯繼續(xù)做作業(yè)
- 其中,“接電話”就是所謂的嵌套中斷
2.中斷響應全過程模式圖
3.為什么需要中斷
3.1 對突發(fā)情況緊急處理 (電話是你正在追的女孩打來的)
3.2 因為CPU相對人來說還是非??斓模瑢崿F(xiàn)宏觀上的并行多任務。
(你在晚上做了作業(yè),吃了飯,還接了電話。因為你的一天只是天上1秒,于是玉皇大帝很高興他一眨眼的工夫你已經(jīng)”并行”地做好了三件事)
例如,一邊計算一邊采集一邊執(zhí)行
3.3 解決CPU與慢速外設和偶發(fā)事件速度不一致的矛盾(你不用流著口水在廚房等飯熟了)
- CPU平時可處理其它工作
- 僅當事件發(fā)生時再處理
- 如果沒有中斷系統(tǒng),CPU需要不停循環(huán)查詢標志位/引腳電平,浪費大量處理資源
4.常見的使用中斷的場合
4.1 引腳狀態(tài)變化產(chǎn)生中斷,也是常見的“外部中斷”
一般是反映外部產(chǎn)生的事件,例如按鈕按下、片外外設通知事件等
4.2 通信接口的收到數(shù)據(jù)與發(fā)送完畢中斷
- 一個數(shù)據(jù)單位發(fā)送完畢時,產(chǎn)生中斷,通知應用邏輯繼續(xù)提供數(shù)據(jù)
- 進一步地,發(fā)送器閑置中斷可使應用邏輯更早地注入新數(shù)據(jù)
- 接收器中有數(shù)據(jù)時,產(chǎn)生中斷,通知應用邏輯取走數(shù)據(jù)
4.3 定時器溢出/倒數(shù)至0時,產(chǎn)生中斷,通知時間到
4.4 模擬比較器結果翻轉時產(chǎn)生中斷
4.5 模數(shù)轉換器采樣完畢時產(chǎn)生中斷
4.6 其它一些緊急的偶發(fā)事件:
- 沒有及時喂狗時的看門狗中斷
- 供電電壓不足產(chǎn)生中斷
5.中斷服務例程 (ISR, Interrupt Service Routine)
5.1 響應中斷時,CPU將會例行地調用一段程序,用以執(zhí)行中斷發(fā)生后需要立即處理的事。這段程序即為“中斷服務例程”。ISR常見的例行工作包括:清除中斷事件標志
5.2 ISR因為打斷了當前的工作,所以要盡量短小精焊,只做必須馬上處理的事
6.中斷延遲
6.1從中斷請求發(fā)起到ISR得到執(zhí)行所花費的時間,稱為中斷延遲
- 現(xiàn)場保存(最少24周期)
- 如果此時中斷被關閉(臨界區(qū)),需要待中斷重新打開后才能響應
- 如果此時正在服務同等或更高優(yōu)先級的中斷,需待其ISR退出
7.中斷的代價
7.1 現(xiàn)場需要額外的棧空間來保存:LPC82x需要32字節(jié)保存現(xiàn)場
7.2 現(xiàn)場保存和恢復需要額外的時間:LPC82x需要約24周期
7.3 打亂了程序執(zhí)行順序,可能導致錯綜復雜的潛在問題。
- 執(zhí)行流程變得不可預測,變數(shù)增加,時序難保證,故障難復現(xiàn)。
- 需要保證ISR與其它程序段互斥訪問全局變量,尤其是復合型全局變量(struct)。如果處理不當會導致難以調試的競爭條件,可能導致數(shù)據(jù)紊亂的問題
- 競爭條件舉例:假如后臺程序和ISR都要執(zhí)行”a++;”語句,a初始值為0
- 后臺程序讀取a到寄存器,得到0
- 后臺程序在寄存器中把0加到1,然后,早不來晚不來,中斷偏偏這個時候來了:
- ISR讀取a到寄存器,也得到0
- ISR在寄存器中把0加到1
- ISR把寄存器中的1寫回a,a現(xiàn)在等于1
- 后臺程序也把寄存器中的1寫回a,a現(xiàn)在還等于1
- 看到?jīng)],執(zhí)行了兩次a++后,a實際上只被++了一次!
- 競爭條件舉例:假如后臺程序和ISR都要執(zhí)行”a++;”語句,a初始值為0
8.臨界區(qū)與需要關閉中斷的場合
有些場合必須關中斷,必須在關中斷時執(zhí)行的代碼又稱為“臨界區(qū)”(critical section), 有以下典型情況:
8.1 當后臺程序與ISR均要更改同一位置的數(shù)據(jù)時,要先關中斷,待改完后再開中斷。否則會導致競爭冒險的情況,可能使數(shù)據(jù)紊亂
8.2 當后臺程序與ISR均要操控同一外設時,要先關中斷,待訪問完畢后再開中斷,否則輕則使外設輸出混疊,重則使外設功能混亂。
- 例如,后臺程序和ISR都要使用同一個UART,后臺程序要輸出”I love u!”,ISR要輸出”Anna Li”, 若后臺程序在輸出期間未關中斷,可能輸出“I love Anna Liu!”
- 又如,在調用IAP函數(shù)擦寫Flash時,如果未關中斷,可能導致擦寫期間又從Flash取指令(ISR的指令)的情況,導致死機
8.3 當控制對時序有嚴格要求的器件時,需要關中斷以保證確定性
8.4 以上注意事項也適用于低優(yōu)先級ISR與高優(yōu)先級ISR之間。
8.5 使用RTOS時,多任務的調度修改了中斷的返回地址,使得以上注意事項擴展到RTOS管理的任務間。
9.臨界區(qū)未關中斷的示意效果演示
10.Cortex-M0+上中斷系統(tǒng)的增強功能
10.1 自動保存和恢復共計32字節(jié)的中斷現(xiàn)場 (8個CPU寄存器)
- 當前RAM和Flash的內容則不屬于“現(xiàn)場”
- 事實上,它們不是CPU的組成部分
10.2 使用普通的函數(shù)調用方式返回,不需要專用的返回指令
10.3 自帶中斷控制器NVIC管理外設和外部中斷。
10.4 因為以上的優(yōu)點,中斷處理無需使用匯編,也無需使用特殊的編譯器擴展功能,寫法和普通的程序相同
- 這并不意味著ISR變成普通程序了,中斷處理的注意事項仍需遵守。