[IC]淺談嵌入式MCU軟件開發之中斷優先級與中斷嵌套


轉自:https://mp.weixin.qq.com/s?__biz=MzI0MDk0ODcxMw==&mid=2247483680&idx=1&sn=c5fd069ab3f17c61f98d6b967b9c819f&chksm=e91245a6de65ccb0758e25c88a9f43f9bd4da57e0b783bd34b0aaa8ce220b81d7f3decb04d4d&mpshare=1&scene=24&srcid=0509ZYDoU7okj7W4JKxeLdmC&key=8da6ecf36bb695ea1394c258413d6c190c76a1e616d9d0e2e2f926ecb8a6927cc232066b5c117df4c6a3f66103e27ab8731d5244b268ea8db0768590c085665c11450834aa8359c5b87396757ac898c4&ascene=1&uin=ODU2NTk0MTA0&devicetype=Windows+7&version=62060739&lang=zh_CN&pass_ticket=ihrPgtqioh4TqFCi6Q3Th7BBCwqw%2FJVjx4Z8FlVdBpFrDtdX3hHuE2A7Jm0fHoLI

關鍵詞:中斷工作機制、中斷優先級、中斷實時性、中斷嵌套

 

引言

        眾所周知,一方面,MCU在嵌入式系統中的廣泛使用的一個重要原因就是其相對於MPU和通用CPU的時效性優勢。而低延遲的外設中斷和中斷嵌套正是MCU實時性的最大保障。另一方面,在嵌入式系統MCU軟件開發中,隨着系統功能的日益復雜,不論是否采用RTOS,多任務都是不可避免的。在裸奔系統中,為了讓時間關鍵的任務得到最先響應,往往需要通過外設中斷嵌套來實現,屬於基於外設的硬件中斷嵌套,而在RTOS中,則給所有系統任務,都賦以具體的優先級,由內核根據優先級高低來進行調度,實際上是實現了一套基於優先級的軟件中斷嵌套。RTOS中的任務軟件嵌套通過內核tick定時器中斷不斷查詢RTOS任務就緒表中各任務的優先級高低來實現任務切換,其外設硬件中斷未必需要嵌套。

        本文旨在給大家介紹嵌入式MCU的中斷處理相關知識,幫助大家理解中斷,並使用好中斷。

        既然中斷嵌套對於嵌入式系統設計如此重要,具體什么是中斷嵌套呢?在具體解釋中斷嵌套之前,有必須要先講一下嵌入式MCU的中斷工作機制和中斷優先級

        寫過裸奔程序的工程師都知道,一個內核CPU同一個時刻只能執行一個任務/程序代碼/指令,比如數據計算,與片上外設進行交互通信等。代碼的執行順序是用戶自己首先寫好的,CPU逐行取指、譯碼、執行即可。產品功能的實現就是在main函數的while(1)循環中(常稱作主程序),不斷的調用其他功能函數實現的。但實際工作環境中、很多事件是隨機發生的,比如網絡通信,外部IO輸入等不確定事件,這個時候CPU就不得不放下當前正在執行的工作,卻響應這些緊急事件,及時讀取網絡報文、處理並回復網絡通信需求,及時外部IO請求。這樣的處理就叫做中斷

        嵌入式MCU中內核CPU異常和各種外設工作都能夠產生響應的中斷,且通過中斷控制器統一進行管理。這樣CPU在中斷未產生時就可以專心處理順序執行的任務,而只有在中斷產生時才通過中斷控制器中斷CPU(通過產生一個高電平/低電平信號給CPU,這個過程被稱為中斷請求),如果此時CPU全局中斷處於使能狀態,則CPU會結合中斷向量表和中斷優先級配置,根據中斷優先級高低(如果同時有多個外設中斷發生),從中斷向量表中取出優先級最高的中斷服務程序ISR地址,將當前CPU的運行時環境壓棧,之后跳轉至該中斷ISR地址運行;若此時CPU全局中斷處於關閉狀態,則忽略當前中斷請求。

        下圖為典型CPU正常主程序處理流程與外設中斷響應的關系圖:

        S12內核CPU的中斷/異常處理流程圖如下:

 

 

 

中斷響應--中斷ISR與中斷實時性

        當中斷產生后,中斷控制器就會請求內核CPU進行中斷響應,其典型的響應就是CPU運行事先准備好的中斷ISR。

中斷ISR不同於其他用戶軟件程序,屬於一類特殊的函數,原因入下:

        1. 中斷ISR必須是void型的無參數傳遞函數--無形參無返回值;

        2.中斷ISR由硬件外設觸發,而非其他函數調用,其運行時機具有隨機不確定性和硬件實時性

        3.中斷ISR運行時間必須盡量短,以保證外設中斷的實時性;

在中斷ISR中需要完成以下工作:

        1. 將引起該中斷請求的外設中斷標志清除,保證外設不因該中斷ISR運行而丟失下一次中斷,而CPU在中斷退出后可以處理其他任務;

        2. 處理外設中斷事件,典型如定時計數,通信外設RX數據接收或者TX數據buffer填充等;

        為了保證中斷的實時性,中斷ISR程序要盡量短,不能條件等待語句甚至將死循環語句放在中斷ISR內。建議用戶一般只把關鍵處理放在中斷ISR中,其他相關的一般性工作放在主程序中執行。典型例子如CAN的數據接收放在CAN RX 中斷ISR中,而通過全局變量通知主程序執行相關的診斷協議(如UDS)。

中斷優先級與中斷嵌套

        中斷優先級是指內核CPU在響應硬件外設中斷時的先后順序,當不同的硬件外設中斷產生時,高優先級的外設其中斷ISR最先被內核執行;

        中斷嵌套是指在外設中斷具有不同的優先級,在CPU響應低優先級中斷的時候(也就是運行中斷ISR時),打開CPU全局中斷,如果此時有更高優先級的中斷到來,CPU能夠停下當前的中斷處理區響應優先級高的中斷,從而保證高優先級任務外設響應實時性的情況:

        一個三級中斷優先級嵌套的典型嵌套流程如下所示:

 

總結一下中斷嵌套發生的必要條件:

        1. 不同的外設中斷源必須有不同的優先級

        一些MCU的中斷優先級時固定不可配置的,如S12G系列MCU,其外設中斷優先級固定,中斷向量地址越高的優先級越高);而另外一些MCU的中斷優先級是可以靈活配置的,如S12XE系列MCU的外設中斷具有8個優先級設置和Qorivva MPC56xx系列MCU的外設中斷有16個優先級可以配置,此類MCU其默認所有外設優先級相同,所以要進行中斷嵌套,需要根據外設任務的重要性對相應外設配置不同的優先級

        2. 在中斷ISR中必須打開CPU全局中斷

幾乎所有嵌入式MCU的默認在進中斷壓棧的時候都是關閉CPU全局中斷的,也就是默認禁止中斷嵌套的,要使能中斷嵌套,用戶必須在可以被嵌套的外設中斷ISR中手動打開CPU的全局中斷。

        下圖為S12內核CPU中斷壓棧過程,壓棧CCR寄存器,關閉全局中斷的處理,箭頭所指紅圈中,硬件置位 I-BIT(禁止I-bit外設中斷)、S-BIT(禁止STOP低功耗指令)和X-BIT(禁止XIRQ中斷)(注:該過程是用戶不可控且不可中斷的"原子"操作)

 

        打開全局中斷的時機需要根據具體任務來決定,一般建議在中斷ISR中,清除當前外設中斷標志后打開即可。

注意,在一些高級MCU中,比如Qorivva MPC56xx和基於ARM Cortex M4F內核的最先汽車級MCU--S32K系列MCU中還集成了DMA,其也可以響應大部分的片上外設中斷,這時,外設中斷標志就由DMA來清除,然后完成外設數據的搬移(無需編寫外設中斷ISR了),從而減少了CPU被外設中斷的頻次,提高CPU的工作效率。

        另外, 通過以上分析結合上一篇分享文章--淺談嵌入式MCU軟件開發之應用工程的堆與棧,嵌入式MCU中斷嵌套需要較大的堆棧(stack)消耗,所以嵌入式MCU中斷嵌套層數不宜過多,否則容易出現堆棧溢出。

 

   如果你喜歡本公眾號的文章,請點擊文章最開始的公眾號關注,或者在微信添加朋友-->公眾號-->輸入"汽車電子expert成長之路"搜索-->點擊關注。若對本文觀點有任何意見和建議也歡迎留言指出。你的點贊/關注/轉發分享是對我辛勤寫作的最大支持和肯定!

胡恩偉

NXP汽車電子FAE

2017年7月21日於山城·重慶


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM