學習筆記(五)——中斷和異常


    cm3在內核水平上支持256個系統異常和外部中斷,由內嵌向量中斷控制器(NVIC)控制標號1-15位異常,16-255則為外部中斷,由於性質類似,都是“中斷”主程序,因此后續將使用中斷來代表系統異常和外部中斷。如果一個中斷因為系統在執行 更高優先級中斷服務歷程或者被屏蔽導致除能,不能被立即響應,則稱它被“懸起(pending)”,此時會有一個懸起狀態寄存器保存其中斷請求,直到中斷能夠被響應。

  256個中斷類型如下圖所示。

一、中斷優先級

  中斷優先級決定了中斷否被立即執行,CM3中支持嵌套中斷,更高級別中斷可以搶占低優先級中斷。優先級號越小則優先級越高,復位,NMI,硬fault的優先級為負數,因而是最高優先級的中斷。雖然CM3支持8位可編程優先級,但是一般來說在設計時回裁掉幾位低端有效位,減少級數,因為級數越多會帶來額外的成本和能耗。

搶占優先級和子優先級(響應優先級,亞優先級):

  CM3中最多支持128位優先級,因為8位中至少1位需要分配給子優先級。搶占優先級是指新產生的中斷優先級大於當前運行的中斷優先級,則優先級高的將會進行搶占。搶占優先級相同的兩個中斷,若同時發生或者懸起,則子優先級高的先運行,若一個已經在運行,無論子優先級是否更高,都不會進行搶占。

  如下圖所示,設置為有4個搶占優先級和2個子優先級。

  

  優先級由寫入應用程序中斷及復位控制寄存器(AIRCR)決定。例:0x05FA0500,則[7:6]兩位為搶占優先級。

二、向量表

  向量表用於存儲中斷服務例程的入口地址,默認的向量表位於0地址處,各個向量占用3字節,其結構如下圖:

  如圖所示,對於MSP的初始值、復位向量、NMI服務歷程入口地址、硬fault服務例程的入口地址是必須包含在向量表中的。為了靈活性,向量表支持重定位(一般重定位到SRAM的一塊區域),修改NVIC中的向量表偏移量寄存器的值就能夠重新定位向量表。但要注意的是向量表的起始地址是有要求的,需要求出向量總數並向上取整到最小的2的整數次冪。

三、中斷輸入和懸起

  中斷輸入腳被置為有效后,該中斷就被懸起,即使撤銷了中斷請求,也會被記錄下來,當優先級最高的時候得到響應,只有懸起狀態清除了才會取消中斷。懸起狀態有兩種清除方法,一種是硬件清除,即當IRQ完成后,硬件自動清除懸起狀態並返回主程序,另一種是使用軟件清除中斷懸起狀態。

四、fault類異常

  fault包括總線fault、存儲器管理fault、用法fault、硬fault這幾類。

4.1 總線fault

  AHB(高性能總線)傳送數據時回復了一個錯誤信號,則會產生總線fault,一般是取指和數據讀寫時發生錯誤導致的,包括訪問地址沒有相應寄存器,SDRAM還未初始化就訪問,數據類型不匹配,設備不能被傳送數據(如用戶級下試圖訪問特權級下才能訪問的設備)。總線fault產生后,若優先級更高,則立即執行,否則被懸起。如果總線fault被除能,或者總線fault是由同優先級或者更高優先級中斷所引發的,那么總線fault會上訪稱硬fault。通過NVIC提供的“總線fault寄存器(BFSR)”,可以判斷fault出入棧,數據訪問還是取指。

4.2 存儲器管理fault

  存儲器管理fault往往是因為觸發了MPU的保護設置的保護規范引發的,訪問空地址,往只讀region寫數據,用戶級下訪問只有特權級下才能訪問的地址也可能觸發存儲器管理fault。其處理方法和總線fault類似,若硬fault和NMI的執行也導致了MemManage fault,那內核將被鎖定。同樣的,NVIC有一個“存儲器管理fault狀態寄存器(MFSR)”,通過MFSR可以知道導致fault 的原因。

4.3 用法fault

  產生的原因可能是:執行了協處理器指令,執行了未定義的指令,無效的中斷返回,使用多重加載/存儲指令時,地址沒有對齊。其他的與存儲器管理fault類似,有一個“用法fault狀態寄存器(UFSR)”。

4.4 硬fault

  硬fault是以上三個處理器“上訪”的結果,另外,取向量產生的總線fault也按硬fault處理,NVIC也有一個?硬fault狀態寄存器(HFSR)來指明產生硬fault 的原因。

五、SVC和PendSV

  SVC(系統調用)和PendSV(可懸起系統調用)用於軟件開發中,OS一般不會讓用戶程序直接訪問硬件,而是提供SVC(類似於API),用戶需要控制特定硬件時,通過產生一個SVC異常,執行SVC服務例程來間接訪問硬件。這種方式使得用戶無需復雜控制硬件程序,使系統更加健壯,見小了開發難度。SVC不能嵌套使用SVC,同優先級無法搶占自身,這樣會產生一個用法fault,在NMI中也不能使用SVC,否則會觸發硬fault。SVC異常必須在執行SVC指令后立即響應,即不可被懸起,否則也將上訪稱硬fault。

  PendSV則是可以被懸起的異常,在PendSV懸起寄存器中寫入1,若優先級不夠高,則將緩期執行。典型的使用場合是在上下文切換中。如圖所示,即使SysTick搶占了ISR,PendSV會在ISR執行完畢后再進行上下文切換。

 

 六、NVIC中斷控制

  每個中斷都使用了NVIC中的以下幾個寄存器:使能與除能寄存器、懸起和解懸寄存器、優先級寄存器、活動狀態寄存器。還有一些特殊功能寄存器對中斷可能有影響:異常掩蔽寄存器(PRIMASK,FAULTMASK,BASEPRI)、向量表偏移量寄存器、軟件觸發中斷寄存器、優先級分組位段。

6.1中斷配置

(1)中斷使能和除能分別使用各自的寄存器來控制,若要使能和除能,只需要在寫1到相應的SETENA和CLRENA中,寫0沒有任何影響。寫0無效的的好處是每個中斷只需要去簡單設置就可以了,不必擔心破壞其他中斷的中斷設置。共240對使能位/除能位,分布在8對32位寄存器中。可以按字/半字/字節訪問。

(2)中斷的懸起狀態可以通過“中斷設置懸起寄存器(SETPEND)”和“中斷懸起清除寄存器(CLRPEND)”來讀取。懸起和解懸寄存器可以有8對,用法和使能除能寄存器差不多。

(3)優先級前面講過了。

(4)活動狀態由活動狀態寄存器(ACTIVE)來決定,執行ISR第一條指令后,活動位就被置1,直到ISR返回時才硬件清0。中斷被更高優先級搶斷時,該中斷活躍狀態仍然為1。該寄存器用法和使能除能寄存器差不多,只是不是成對的。

(5)特殊功能寄存器PRIMASK和FAULTMASK用於除能異常,PRIMASK將當前優先級設為0(可編程優先級的最高優先級),從而除能所有NMI和硬fault之外的異常。FAULTMASK則改為-1,將硬fault也除能。它們通過MRS和MSR或者CPS來訪問。

(6)BASEPRI也用於掩蔽異常,用於設定一個值,優先級低於這個值的都被屏蔽。

6.2 中斷設置示例

6.3軟件中斷和SysTick定時器

  軟件中斷最簡單的方法是使用相應的SETPEND寄存器,更好的方法即使使用軟件觸發中斷寄存器(STIR),將相應的位寫入1,則該編號的外部中斷被懸起。

  NVIC中還有一個SysTick定時器,產生SysTick異常,該定時器用於產生“滴答”中斷的時基,也是整個系統的時基。定時器將時間片分配給各個任務,實現任務的切換。有四個寄存器控制SysTick定時器,SysTick控制及狀態寄存器,SysTick重載數值寄存器,SysTick當前數值寄存器,SysTick校准數值寄存器。

七、中斷具體行為

7.1 中斷產生

  中斷產生后,將會發生以下三個操作:

(1)入棧。為了保存現場,按順序把xPSR,PC,LR,R12,R3-R0由硬件自動壓入堆棧中,若在使用PSP,則壓入PSP,使用進程堆棧,否則壓入MSP,使用主堆棧。進入ISR后,將一直使用主堆棧。堆棧順序和空間順序並不是對應的:

(2)取向量。CM3采用哈佛結構,即取指和數據操作使用不同的總線,因此在入棧的同時,I-Code總線正在從向量表中找出正確的向量,然后在入口地址處取指。

(3)更新寄存器。SP:把堆棧指針(PSP或MSP)更新到新位置。PSR:更新IPSR位段(PSR的最低部分)的值為新響應的異常編號。PC:取向量后,PC將指向ISR的入口地址。LR:出入ISR過程中,LR代表的是“EXC_RETURN”,異常進入時由系統計算賦值給LR,方便異常返回時使用LR。

7.2 異常返回

  在執行完ISR后,需要進行異常返回,以便回到被中斷的程序。異常返回的方式有三種:

 

  異常返回后,CM3將執行以下操作使被中斷的程序再次被執行:

(1)出棧:和前面入棧相對應,將保存的值恢復到寄存器。

(2)更新NVIC寄存器:將活動位清除。

7.3嵌套中斷,咬尾中斷,晚到中斷

  前面講到,CM3支持嵌套中斷,嵌套中斷發生時,被中斷的ISR的8個(或以上)寄存器值需要被保存到MSP,因此若嵌套過多,可能會導致棧溢出,因此計算MSP容量的最小安全值是很重要的。另外,相同的異常不允許重入(我覺得重入應該是指同一個ISR未完成又再次被調用,使得同一個ISR占用兩個內存空間),只能等一個ISR執行完成后,方可響應新的IRQ。

  咬尾中斷是為了縮短中斷延遲而設置的,咬尾中斷就是指若CM3執行完一個中斷,接着發生另一個中斷時,不再進行異常返回中的出棧和中斷發生時的入棧操作,因為被中斷的程序再次被中斷,得不到執行,也就沒有必要把恢復出來又保存進去。

  晚到中斷是指若在中斷產生的入棧階段,ISR尚未執行,又來了更高優先級的中斷,那么入棧后,將執行高優先級的中斷。

 7.4 異常返回值

  前面講到,中斷發生的第三步中LR將更新為“EXC_RETURN”,高28全為1,低四位有意義:

  可以看出,EXC_RETURN有以下三個合法值:

 

7.5 中斷響應延遲

  中斷延遲是指收到中斷請求,到執行ISR第一條指令時需要的時間。一般來說是12個周期,進行了上述的一系列操作,咬尾中斷則只需要6個周期。但是有些進行中的指令需要較多周期,包括除法指令、雙字傳送指令LDRD/STRD以及多重數據傳送指令LDM/STM。對於前兩者,CM3為了保證中斷的響應直接取消操作,這樣會喪失部分性能(因為中斷返回后需要從頭運行這個指令)。對於后者,CM3支持LDM/STM的中止和繼續,單這樣需要在xPSR中開出若干個ICI位,帶ISR返回后,CM3可以從中獲取LDM/STM執行的進度。

  另外,中斷響應期間可能產生多個種類的fault,這里不再贅述。

 

 

  

 


免責聲明!

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



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