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