天天看點

嵌入式開發基礎之中斷管理

嵌入式開發基礎之線程間通信

  • ​​引言​​
  • ​​基本概念​​
  • ​​Cortex-M 中斷​​
  • ​​中斷和異常的差別​​
  • ​​中斷的優勢及劣勢​​
  • ​​中斷相關的硬體​​
  • ​​中斷延遲​​
  • ​​中斷的運作機制​​
  • ​​RTOS的中斷管理​​
  • ​​中斷向量表​​
  • ​​使用者中斷服務程式​​
  • ​​中斷與輪詢​​
  • ​​後續​​

引言

中斷就是系統正在處理某一個正常事件,忽然被另一個需要馬上處理的緊急事件打斷,系統轉而處理這個緊急事件,待處理完畢,再恢複運作剛才被打斷的事件。

無論在單片機開發還是嵌入式開發中,中斷都是一個非常重要的概念。而重要的原因,是中斷的概念符合我們普世生活的場景。

你正在上班努力程式設計,卻有一通電話打了進來,而不得不停止工作,接通完電話後,發現隻是外賣到了樓下,這時候你又恢複到工作的狀态,這是短期中斷。

你大學畢業,因為第一年的工作經驗的優先級高于考研是以你去找了份工作,幹了一年後,去考研,回到學校繼續學習,對你的學業來說,這也是中斷,無非是中斷處理時間長而已。

本文将會介紹嵌入式開發中,中斷管理的概念,及基于RTOS的一些例子。

基本概念

Cortex-M 中斷

中斷是微控制器一個很常見的特性,中斷由硬體産生,當中斷産生以後 CPU 就會中斷目前的流程轉而去進行中斷服務,Cortex-M 核心的 MCU 提供了一個用于中斷管理的嵌套向量中斷控制器(NVIC)。 Cotex-M3 的 NVIC 最多支援 240 個 IRQ(中斷請求)、1 個不可屏蔽中斷(NMI)、1 個 Systick(滴答定時器)定時器中斷和多個系統異常。

Cortex-M 是一個家族系列,其中包括 Cortex M0/M3/M4/M7 多個不同型号,每個型号之間會有些差別,例如 Cortex-M4 比 Cortex-M3 多了浮點計算功能等,但它們的程式設計模型基本是一緻的。

Cortex-M 處理器有多個用于管理中斷和異常的可程式設計寄存器,這些寄存器大多數都在NVIC 和系統控制塊(SCB)中,CMSIS 将這些寄存器定義為結構體。NVIC 和 SCB 都位于系統控制空間(SCS)内,SCS 的位址從 0XE000E000 開始,SCB 和 NVIC的位址也在 core_cm3.h 中有定義。

嵌入式開發基礎之中斷管理

當多個中斷來臨的時候處理器應該響應哪一個中斷是由中斷的優先級來決定的,高優先級的中斷(優先級編号小)肯定是首先得到響應,而且高優先級的中斷可以搶占低優先級的中斷,這個就是中斷嵌套。Cortex-M 處理器的有些中斷是具有固定的優先級的,比如複位、NMI、HardFault,這些中斷的優先級都是負數,優先級也是最高的。

Cortex-M 處理器有三個固定優先級和 256 個可程式設計的優先級,最多有 128 個搶占等級,但是實際的優先級數量是由晶片廠商來決定的。但是,絕大多數的晶片都會精簡設計的,以緻實際上支援的優先級數會更少,如 8 級、16 級、32 級等,比如 STM32 就隻有 16 級優先級。在設計晶片的時候會裁掉表達優先級的幾個低端有效位,以減少優先級數,是以不管用多少位來表達優先級,都是MSB 對齊的。

STM32 的中斷向量具有兩個屬性,一個為搶占屬性,另一個為響應屬性。分别是搶占優先級(分組優先級)和亞優先級(子優先級)。搶占,是指打斷其他中斷的屬性,即因為具有這個屬性會出現嵌套中斷(在執行中斷服務函數A 的過程中被中斷B 打斷,執行完中斷服務函數B 再繼續執行中斷服務函數A),搶占屬性由NVIC_IRQChannelPreemptionPriority 的參數配置。而響應屬性則應用在搶占屬性相同的情況下,當兩個中斷向量的搶占優先級相同時,如果兩個中斷同時到達, 則先處理響應優先級高的中斷, 響應屬性由NVIC_IRQChannelSubPriority 參數配置。

若核心正在執行C 的中斷服務函數,則它能被搶占優先級更高的中斷A 打斷,由于B和C 的搶占優先級相同,是以C 不能被B 打斷。但如果B 和C 中斷是同時到達的,核心就會首先響應響應優先級别更高的B 中斷。

中斷和異常的差別

中斷(interruption)也稱外中斷,指來自CPU執行指令以外的事件的發生,如裝置發出的I/O結束中斷,表示裝置輸入/輸出處理已經完成。時鐘中斷表示一個固定的時間片已到,讓處理機處理計時等。這一類中斷通常是與目前指令執行無關的事件,即他們與目前處理機運作的程式無關。

異常也稱内中斷、例外或陷入(trap),指源自CPU執行指令内部的事件,如程式的非法操作碼、位址越界等。對異常的處理一般要依賴于目前程式的運作現場,而且異常不能被屏蔽,一旦出現應立即處理。

中斷的優勢及劣勢

通過中斷機制,在外設不需要 CPU 介入時,CPU 可以執行其他任務,而當外設需要CPU 時通過産生中斷信号使 CPU 立即停止目前任務轉而來響應中斷請求。這樣可以使CPU 避免把大量時間耗費在等待、查詢外設狀态的操作上,是以将大大提高系統實時性以及執行效率。

eRTOS 源碼中有許多處臨界段的地方,臨界段雖然保護了關

鍵代碼的執行不被打斷,但也會影響系統的實時,任何使用了作業系統的中斷響應都不會比裸機快。比如,某個時候有一個任務在運作中,并且該任務部分程式将中斷屏蔽掉,也就是進入臨界段中,這個時候如果有一個緊急的中斷事件被觸發,這個中斷就會被挂起,不能得到及時響應,必須等到中斷開啟才可以得到響應,如果屏蔽中斷時間超過了緊急中斷能夠容忍的限度,危害是可想而知的。是以,作業系統的中斷在某些時候會有适當的中斷延遲,是以調用中斷屏蔽函數進入臨界段的時候,也需快進快出。

中斷相關的硬體

與中斷相關的硬體可以劃分為三類:外設、中斷控制器、CPU 本身。

外設:當外設需要請求 CPU 時,産生一個中斷信号,該信号連接配接至中斷控制器。

中斷控制器:中斷控制器是 CPU 衆多外設中的一個,它一方面接收其他外設中斷信号的輸入,另一方面,它會發出中斷信号給 CPU。可以通過對中斷控制器程式設計實作對中斷源的優先級、觸發方式、打開和關閉源等設定操作。在 Cortex-M 系列控制器中常用的中斷控制器是 NVIC(内嵌向量中斷控制器 Nested Vectored Interrupt Controller)。

CPU:CPU 會響應中斷源的請求,中斷目前正在執行的任務,轉而執行中斷處理程式。NVIC 最多支援 240 個中斷,每個中斷最多 256 個優先級。

中斷延遲

即使作業系統的響應很快了,但對于中斷的處理仍然存在着中斷延遲響應的問題,我們稱之為中斷延遲(Interrupt Latency) 。

中斷延遲是指從硬體中斷發生到開始執行中斷處理程式第一條指令之間的這段時間。

也就是:系統接收到中斷信号到作業系統作出響應,并完成換到轉入中斷服務程式的時間。也可以簡單地了解為:(外部)硬體(裝置)發生中斷,到系統執行中斷服務子程式(ISR)的第一條指令的時間。

中斷延遲可以定義為,從中斷開始的時刻到中斷服務例程開始執行的時刻之間的時間段。中斷延遲 = 識别中斷時間 + [等待中斷打開時間] + [關閉中斷時間]。

注意:“[ ]”的時間是不一定都存在的,此處為最大可能的中斷延遲時間。

中斷的運作機制

不同計算機的中斷處理過程各具特色,大緻可分為如下流程:

  1. 關中斷:CPU響應中斷後,首先要保護程式的現場狀态,在保護現場的過程中,CPU不應響應更高優先級中斷源的中斷請求。
  2. 儲存斷點:為保證中斷服務程式執行完畢後能正确地傳回到原來地程式,必須将原來地程式地斷點儲存起來。
  3. 中斷服務程式尋址:其實質就是取出中斷服務程式入口位址送入程式計數器PC。
  4. 儲存現場和屏蔽字:進入中斷服務程式後,首先要儲存現場,現場資訊一般是指程式狀态字PSWR和某些通用寄存器地内容。
  5. 開中斷:允許更高優先級地中斷請求得到響應
  6. 執行中斷服務程式:這是中斷請求地目的
  7. 關中斷:保證在回複現場和屏蔽字時不被中斷。
  8. 恢複現場和屏蔽字:将現場和屏蔽字恢複到原來地狀态
  9. 開中斷、中斷傳回。中斷服務程式地最後一條指令通常是一條中斷傳回指令,使其傳回到原來程式地斷點處,以便繼續執行原程式。

如果專注于單片機,我們可以簡潔的說,當中斷産生時,處理機将按如下的順序執行:

  • 儲存目前處理機狀态資訊
  • 載入異常或中斷處理函數到 PC 寄存器
  • 把控制權轉交給處理函數并開始執行
  • 當處理函數執行完成時,恢複處理器狀态資訊
  • 從異常或中斷中傳回到前一個程式執行點

中斷使得 CPU 可以在事件發生時才給予處理,而不必讓 CPU 連續不斷地查詢是否有相應的事件發生。通過兩條特殊指令:關中斷和開中斷可以讓處理器不響應或響應中斷,在關閉中斷期間,通常處理器會把新産生的中斷挂起,當中斷打開時立刻進行響應,是以會有适當的延時響應中斷,故使用者在進入臨界區的時候應快進快出。

中斷發生的環境有兩種情況:在任務的上下文中,在中斷服務函數處理上下文中。

  • 任務在工作的時候,如果此時發生了一個中斷,無論中斷的優先級是多大,都會打斷目前任務的執行,進而轉到對應的中斷服務函數中執行。
  • 在執行中斷服務例程的過程中,如果有更高優先級别的中斷源觸發中斷,由于目前處于中斷處理上下文環境中,根據不同的處理器構架可能有不同的處理方式,比如新的中斷等待挂起直到目前中斷處理離開後再行響應;或新的高優先級中斷打斷目前中斷處理過程,而去直接響應這個更高優先級的新中斷源。後面這種情況,稱之為中斷嵌套。在硬實時環境中,前一種情況是不允許發生的,不能使響應中斷的時間盡量的短。而在軟體處理(軟實時環境)上,RTOS 允許中斷嵌套,即在一個中斷服務例程期間,處理器可以響應另外一個優先級更高的中斷。

RTOS的中斷管理

ARM Cortex-M 系列核心的中斷是由硬體管理的,而 無論是RT-Thread還是FreeRTOS,這些各類RTOS 是軟體,它并不接管由硬體管理的相關中斷(接管簡單來說就是,所有的中斷都由 RTOS 的軟體管理,硬體來了中斷時,由軟體決定是否響應,可以挂起中斷,延遲響應或者不響應),隻支援簡單的開關中斷等,是以 RTOS 中的中斷使用其實跟裸機差不多的,需要我們自己配置中斷,并且使能中斷,編寫中斷服務函數,在中斷服務函數中使用核心 IPC 通信機制,一般建議使用信号量、消息或事件标志組等标志事件的發生,将事件釋出給處理任務,等退出中斷後再由相關處理任務具體進行中斷。

中斷向量表

中斷向量表是所有中斷處理程式的入口, Cortex-M 系列的中斷處理過程:把一個函數(使用者中斷服務程式)同一個虛拟中斷向量表中的中斷向量聯系在一起。當中斷向量對應中斷發生的時候,被挂接的使用者中斷服務程式就會被調用執行。

在 Cortex-M 核心上,所有中斷都采用中斷向量表的方式進行處理,即當一個中斷觸發時,處理器将直接判定是哪個中斷源,然後直接跳轉到相應的固定位置進行處理,每個中斷服務程式必須排列在一起放在統一的位址上(這個位址必須要設定到 NVIC 的中斷向量偏移寄存器中)。中斷向量表一般由一個數組定義或在起始代碼中給出。

在 ARM Cortex-M 系列處理器上,所有中斷都采用中斷向量表的方式進行處理,即當一個中斷觸發時,處理器将直接判定是哪個中斷源,然後直接跳轉到相應的固定位置進行處理。而在 ARM7、ARM9 中,一般是先跳轉進入 IRQ 入口,然後再由軟體進行判斷是哪個中斷源觸發,獲得了相對應的中斷服務例程入口位址後,再進行後續的中斷處理。ARM7、ARM9 的好處在于,所有中斷它們都有統一的入口位址,便于 OS 的統一管理。而ARM Cortex-M 系列處理器則恰恰相反,每個中斷服務例程必須排列在一起放在統一的位址上(這個位址必須要設定到 NVIC 的中斷向量偏移寄存器中)。中斷向量表一般由一個數組定義(或在起始代碼中給出)。

使用者中斷服務程式

在使用者中斷服務程式(ISR)中,分為兩種情況,第一種情況是不進行線程切換,這種情況下使用者中斷服務程式和中斷後續程式運作完畢後退出中斷模式,傳回被中斷的線程。另一種情況是,在中斷處理過程中需要進行線程切換,這種情況會調用函數(比如RT-Thread是 rt_hw_context_switch_interrupt() 函數)進行上下文切換。

中斷與輪詢

當驅動外設工作時,其程式設計模式到底采用中斷模式觸發還是輪詢模式觸發往往是驅動開發人員首先要考慮的問題,并且這個問題在實時作業系統與分時作業系統中差異還非常大。因為輪詢模式本身采用順序執行的方式:查詢到相應的事件然後進行對應的處理。是以輪詢模式從實作上來說,相對簡單清晰。例如往序列槽中寫入資料,僅當序列槽控制器寫完一個資料時,程式代碼才寫入下一個資料(否則這個資料丢棄掉)。

在實時系統中輪詢模式可能會出現非常大問題,因為在實時作業系統中,當一個程式持續地執行時(輪詢時),它所在的線程會一直運作,比它優先級低的線程都不會得到運作。而分時系統中,這點恰恰相反,幾乎沒有優先級之分,可以在一個時間片運作這個程式,然後在另外一段時間片上運作另外一段程式。

是以通常情況下,實時系統中更多采用的是中斷模式來驅動外設。當資料達到時,由中斷喚醒相關的處理線程,再繼續進行後續的動作。

後續

繼續閱讀