STM32的"異常“、“中斷”和“事件”區別和理解

STM32的"異常“、“中斷”和“事件”區別和理解

1 異常與中斷(Cortex-M3)

1.1 異常與中斷

原話: 
Cortex‐M3 在核心水平上搭載了一個異常響應系統,支援為數眾多的系統異常和外部中斷。 
其中,編號為 1-15 的對應系統異常,大於等於 16 的則全是外部中斷。 
除了個別異常的優先順序被定死外,其它異常的優先順序都是可程式設計的。 
所有能打斷正常執行流的事件都稱為異常

  1. 異常的概念包含中斷的概念,即中斷是異常的子集
  2. 異常與中斷都是硬體支援的。

異常表: 
異常表

外部中斷表: 
外部中斷表
這裡的“外部中斷”不是指STM32中的EXTI中斷,而是所有中斷。

1.2 優先順序

原則上,CM3 支援 3 個固定的高優先順序和多達 256 級的可程式設計優先順序,並且支援128搶佔(preempt)優先順序128 級亞優先順序。但各廠商會做裁剪。

  1. 搶佔優先順序即搶佔優先順序任務可以打斷正在執行的搶佔優先順序任務,而讓CPU轉而執行搶佔優先順序任務。
  2. 亞優先順序則為多個相同搶佔優先順序不同亞優先順序的任務同時請求異常時,CPU會先執行亞優先順序的任務。
  3. 搶佔優先順序也有稱為“先佔優先順序”。
  4. “亞優先順序”也有會被稱為“響應優先順序”或“子優先順序”。

NVIC 中有一個暫存器是“應用程式中斷及復位控制暫存器”,它裡面有一個位段名為“優先順序組”。

優先順序組分配:(預設為7位搶佔) 
優先順序組

中斷優先順序組的配置一般在程式最初設定一次。(中途改變中斷優先順序組本人沒有試過)

1.3 中斷與懸起(掛起)

當中斷輸入腳被assert(確認有效?)後,該中斷就被懸起。即使後來中斷源取消了中斷請求,已經被標記成懸起的中斷也被記錄下來。到了系統中它的優先順序最高的時候,就會得到響應。 
但是,如果在某個中斷得到響應之前,其懸起狀態被清除了(例如,在 PRIMASK 或FAULTMASK 置位的時候軟體清除了懸起狀態標誌),則中斷被取消。 
當某中斷的服務例程開始執行時,就稱此中斷進入了“活躍”狀態,並且其懸起位會被硬體自動清除。

  1. 中斷輸入引腳有效後,中斷就被懸起,即使取消請求,也會執行。
  2. 中斷是否處於懸起狀態,中斷請求被響應的關鍵。
  3. 中斷響應之前,請求以脈衝方式呈現的話,僅看做一次請求(懸起不被軟體清除的前提下)。 
    這裡寫圖片描述
  4. 中斷被響應時,硬體清除懸起狀態。
  5. 中斷響應中,請求被釋放,但又變為有效時,會再次懸起。 
    這裡寫圖片描述

  6. 中斷響應完成之後,中斷請求仍然存在,則再次懸起,等待響應。 
    中斷懸起

1.4 SVC和PendSV

SVC(System serVice Call):系統(服務)呼叫;

SVC異常是必須立即得到響應的,若因優先順序不比當前正處理的高,或是其它原因使之無法立即響應,將上訪成硬 fault。

PendSV(Pend System serVice):可懸起系統呼叫。

PendSV 則不同,它是可以像普通的中斷一樣被懸起的。 
PendSV 的典型使用場合是在上下文切換時(在不同任務之間切換)。

多用於作業系統軟體開發中。(uC/OS-II中就用PendSV來實現任務排程)

簡單的排程方式: 
1. 時間輪轉(SysTick) 
這裡寫圖片描述
2. 產生一個系統呼叫(PendSV設定為最低優先順序) 
這裡寫圖片描述

  1. 任務 A 呼叫 SVC 來請求任務切換(例如,等待某些工作完成)
  2. OS 接收到請求,做好上下文切換的準備,並且 pend 一個 PendSV 異常。
  3. 當 CPU 退出 SVC 後,它立即進入 PendSV,從而執行上下文切換。
  4. 當 PendSV 執行完畢後,將返回到任務 B,同時進入執行緒模式。
  5. 發生了一箇中斷,並且中斷服務程式開始執行
  6. 在 ISR 執行過程中,發生 SysTick 異常,並且搶佔了該 ISR。
  7. OS 執行必要的操作,然後 pend 起 PendSV 異常以作好上下文切換的準備。
  8. 當 SysTick 退出後,回到先前被搶佔的 ISR 中,ISR 繼續執行
  9. ISR 執行完畢並退出後,PendSV 服務例程開始執行,並且在裡面執行上下文切換
  10. 當 PendSV 執行完畢後,回到任務 A,同時系統再次進入執行緒模式。

1.5 CM3中斷處理特色——Tail-Chainign

兩個同優先順序中斷交接時,不執行斷點恢復和斷點資料恢復,直接轉到下一個中斷執行。

2 中斷與事件

2.1 事件、中斷事件 中斷

凡從事過ST MCU應用開發的人往往會遇到事件中斷事件 中斷三個概念或術語。這三個概念彼此關聯,有時會讓人有點混淆或犯迷糊。 
先拿一件生活中的事情打比方對上述三個概念做個基本的粗略理解,之後再分享一個STM32 GPIO外部中斷配置案例。

比如一老師在教室裡給學生們上課。課堂上的學生可能做出各種行為動作,比方做筆記、打哈氣、翻書包、講小話等,我們把這些行為統稱為事件,其中有些行為老師往往只是視而不見,繼續他的上課;而有些行為可能導致老師的上課中止,比方講小話,並對學生的相關行為予以警告、批評或糾正等,然後繼續上課。我們把老師因為學生的某些行為而中止授課,併產生後續動作,之後接著上課的這個過程理解為中斷或中斷響應。我們把可能導致老師上課中斷的學生行為理解為中斷事件。 
結合上面的比方,不難理解中斷事件是一種可以導致中斷髮生的事件中斷則是因為中斷事件的發生而導致的後續行為過程事件與中斷事件是包含關係,即事件可分為中斷事件或非中斷事件。而中斷事件與中斷之間屬於前後關聯的因果關係,雖有關聯,但二者在時序上、行為上並不一樣。 
結合具體的ST MCU執行過程,其中會有許多各種各樣的事件,比方管腳電平變化、計數器溢位、DMA空、FIFO非空、AD轉換結束、超時、外設使能、初始化等等,其中有些事件是不會導致中斷產生的,比方外設使能或部分初始化動作是不會導致中斷髮生的,有些事件就可能導致中斷髮生,比方計數器溢位,AD轉換結束等,這些就是中斷事件。當然這些中斷事件最終能否觸發後續中斷,得看是否開啟了該中斷事件的中斷使能,相關中斷向量控制器【NVIC】是否配置,最終讓CPU核心參與進來,並完成後續的中斷服務動作。 
不妨藉助STM32 MCU的GPIO的外部事件與中斷控制器的框圖來理解上述概念。 
這裡寫圖片描述 
從上圖可以看出,不論外部電平變化成為中斷事件還是非中斷事件,綠色方框部分都是一樣的,即具有相同的觸發源。差別就在後面。一般性事件要變為中斷事件,得有相關中斷使能位的允許。中斷事件再向CPU啟用相關中斷請求,在NVIC配置相應中斷向量後,CPU便參與進行後續的中斷響應服務【如儲存現場、執行中斷服務程式、恢復現場並返回】,而非中斷事件就沒有中斷事件後續的流程,只是有些硬體觸發訊號或標誌的產生。當然非中斷事件的形成也是可控的。

既然一個可以觸發中斷的事件可能被配置中斷事件或非中斷事件,那麼在相關事件的觸發配置時就出現兩種可能,即允許產生中斷或禁止產生中斷。於是乎,ST MCU參考手冊裡在談到事件的觸發方式時就引出了事件模式和中斷模式兩個概念。

比方STM32的GPIO口的電平跳變基本都是可以觸發外部中斷的。但在具體配置時,可以根據需要來決定啟用還是禁用相關腳的中斷功能,從而選擇不同的事件觸發方式,即事件模式和中斷模式。如果不希望電平跳變事件觸發中斷,就配置為事件模式,反之,配置為中斷模式。

在STM32相關參考手冊裡,涉及中斷【INTERRUPT】和事件【EVENT】二詞表述的地方比較多,加上這兩個詞的含義比較寬泛。手冊裡可能會用interrupt或interrupt event表述同一東西,或者說interrup泛指中斷事件及後續中斷響應全過程。比方類似下面語句的地方: 
這裡寫圖片描述

有時用Interrupt event明確出來。比方下面表格中提到interrupt event. 
這裡寫圖片描述

這裡寫圖片描述 
總之,不管手冊上怎麼寫,不必拘泥於字詞符號,結合上下文弄清怎麼回事就好。

2.2 外部中斷線或外部事件線示例分析

這裡寫圖片描述 
這張圖是一條外部中斷線或外部事件線的示意圖,圖中訊號線上劃有一條斜線,旁邊標誌19字樣的註釋,表示這樣的線路共有19套.圖中的藍色虛線箭頭,標出了外部中斷訊號的傳輸路徑,首先外部訊號從編號1的晶片管腳進入,經過編號2的邊沿檢測電路,通過編號3的或門進入中斷掛起請求暫存器,最後經過編號4的與門輸出到NVIC中斷檢測電路,這個邊沿檢測電路受上升沿或下降沿選擇暫存器控制,使用者可以使用這兩個暫存器控制需要哪一個邊沿產生中斷,因為選擇上升沿或下降沿是分別受2個平行的暫存器控制,所以使用者可以同時選擇上升沿或下降沿,而如果只有一個暫存器控制,那麼只能選擇一個邊沿了. 
按下來是編號3的或門,這個或門的另一個輸入是軟體中斷/事件暫存器,從這裡可以看出,軟體可以優先於外部訊號請求一箇中斷或事件,即當軟體中斷/事件暫存器的對應位為”1”時,不管外部訊號如何,編號3的或門都會輸出有效訊號. 
一箇中斷或事件請求訊號經過編號3的或門後,進入掛起請求暫存器,到此之前,中斷和事件的訊號傳輸通路都是一致的,也就是說,掛起請求暫存器中記錄了外部訊號的電平變化. 
外部請求訊號最後經過編號4的與門,向NVIC中斷控制器發出一箇中斷請求,如果中斷遮蔽暫存器的對應位為”0”,則該請求訊號不能傳輸到與門的另一端,實現了中斷的遮蔽. 
明白了外部中斷的請求機制,就很容易理解事件的請求機制了.圖中紅色虛線箭頭,標出了外部事件訊號的傳輸路徑,外部請求訊號經過編號3的或門後,進入編號5的與門,這個與門的作用與編號4的與門類似,用於引入事件遮蔽暫存器的控制;最後脈衝發生器的一個跳變的訊號轉變為一個單脈衝,輸出到晶片中的其它功能模組.從這張圖上我們也可以知道,從外部激勵訊號來看,中斷和事件的產生源都可以是一樣的.之所以分成2個部分,由於中斷是需要CPU參與的,需要軟體的中斷服務函式才能完成中斷後產生的結果;但是事件,是靠脈衝發生器產生一個脈衝,進而由硬體自動完成這個事件產生的結果,當然相應的聯動部件需要先設定好,比如引起DMA操作,AD轉換等; 
簡單舉例:外部I/O觸發AD轉換,來測量外部物品的重量;如果使用傳統的中斷通道,需要I/O觸發產生外部中斷,外部中斷服務程式啟動AD轉換,AD轉換完成中斷服務程式提交最後結果;要是使用事件通道,I/O觸發產生事件,然後聯動觸發AD轉換,AD轉換完成中斷服務程式提交最後結果;相比之下,後者不要軟體參與AD觸發,並且響應速度也更塊;要是使用事件觸發DMA操作,就完全不用軟體參與就可以完成某些聯動任務了。 
總結: 
可以這樣簡單的認為,事件機制提供了一個完全由硬體自動完成的觸發到產生結果的通道,不要軟體的參與,降低了CPU的負荷,節省了中斷資源,提高了響應速度(硬體總快於軟體),是利用硬體來提升CPU晶片處理事件能力的一個有效方法;

參考:

1、Cortex-M3權威指南(中文)

2 、STM32參考手冊中文版(第10版)

3、http://blog.csdn.net/tanyjin/article/details/53359883

4、http://blog.csdn.net/u010315587/article/details/50086395