- 嵌入式系統應用開發基礎
- 楊斌編著
- 3644字
- 2018-12-27 15:17:57
2.4 ARM體系結構中的異常
非預知的引發處理器暫時脫離正常指令序列并轉到另外的程序段去運行的現象,稱之為異常(Exceptions),所運行的程序段稱為異常處理程序。當異常處理程序結束之后,多數情況下處理器需要返回脫離點繼續執行后續的程序。
ARM體系結構中的異常與X86體系結構的中斷和異常有很大的相似之處,但異常與中斷的概念并不完全等同。
異常和中斷都是因某種因素(內部或外部)導致程序流暫時脫離當前指令序列轉到另外的一個指令序列去執行的現象。中斷及其響應過程通常是由電信號(處理器內部或外部的引腳信號)觸發的,屬硬件觸發,而且通常可以通過對中斷屏蔽位的設置禁止或允許對其的響應;而異常則是因指令的執行而產生的,屬于軟件觸發,且大部分是不可屏蔽的。由于在處理器內部對于中斷或異常的管理都采用了相同的機制,所以統稱為異常。
為了保證處理器執行完異常處理程序后能夠正確的返回脫離點,必須要在進入異常處理程序前保存好處理器先前的工作環境,即處理器內部可能被異常處理程序使用的那些寄存器內容,它們是操作系統中稱為上下文(Context)的重要部分。當異常處理完成之后,還要將這些寄存器內容恢復到原來的寄存器內,從而保證處理器在一個正確的環境下運行。處理器允許多個異常同時發生,但任意時刻只能處理一個。不同的異常具有不同的優先級,處理器會在多個異常同時發生的情況下,選擇優先級最高的一個加以處理。
2.4.1 ARM體系結構所支持的異常類型
ARM體系結構所支持的異常及具體含義如表2-9所示。
表2-9 ARM體系結構所支持的異常
2.4.2 ARM處理器對異常的響應過程
當一個異常出現以后,ARM微處理器會按圖2-15所示的流程進入異常處理程序。

圖2-15 ARM處理器自動完成的異常響應過程
ARM微處理器對異常的響應過程也可用偽碼描述為:
R14_<Exception_Mode>=Return Link ;自動將當前PC值-4后存入LR寄存器 SPSR_<Exception_Mode>=CPSR ;自動將CPSR存入本異常模式對應的SPSR CPSR[4:0]=Exception Mode Number ;自動將CPSR中的工作模式設為本異常模式 CPSR[5]=0 ;自動將CPSR[5]清零,異常只能運行于ARM狀態 If <Exception_Mode>==Reset or FIQ then ;判斷是否為復位或FIO異常 CPSR[6]=1 ;當響應FIQ異常時,禁止響應新的FIQ異常 else CPSR[6]=不變 ;當響應IRQ異常時,允許嵌套響應FIQ異常 CPSR[7]=1 ;當響應某個異常時,禁止響應IRQ異常 PC=Exception Vector Address ;最后將PC設為本異常對應的異常向量地址
說明:對R14_xxx內地址值的設置,根據不同的異常而不同,具體見表2-10。
表2-10 各種異常對各自R14值的設置
2.4.3 異常向量表
與X86中斷向量表不同的地方是,ARM的異常向量(Exception Vectors)表內的每個表項內容不是處理程序的入口地址,而是一條跳轉到異常處理程序的跳轉指令。要使處理器轉入異常處理程序去運行,只要將PC值設置為異常向量對應的地址值,處理器執行里面的調轉指令即可進入異常處理程序運行。ARM處理器一共只有8個異常向量表項,有定義的為7個,另一個為保留項。與X86中斷向量表相同的地方是,ARM的異常向量也固定的設置在存儲空間起始地址區域內,一共32B,比X86的1KB少許多。具體的向量分配見表2-11。
表2-11 異常向量表
2.4.4 從異常返回
異常處理完畢之后,ARM微處理器會執行以下幾步操作從異常返回。
①將連接寄存器LR的值直接送到PC或者減去相應的偏移量后送到PC中。
說明:異常返回是通過直接向PC中注入返回地址實現的,但由于不同的異常需要返回的地址不一樣。有的異常在LR中保存的就是返回地址值,而有的異常則需要在LR中保存的地址值基礎上再減去1或2條指令的偏移量才是真正的返回地址。表2-12是各類異常的返回地址設置表。關于返回所需設置的PC值為什么不同,請參見后續內容。
表2-12 異常返回時需要由程序向PC值設置的地址值
②將SPSR復制回CPSR中。
③若在進入異常處理時設置了中斷禁止位,要在此清除。
由于程序總是從復位異常處理程序開始執行的,因此復位異常處理程序不需要返回。
2.4.5 各類異常有關說明
1.快中斷(Fast Interrupt Request,FIQ)
FIQ異常是為了支持外設的快速響應而設計的,利用在ARM狀態下配備較多的私有寄存器,可在保存和恢復現場信息時避免對慢速的存儲器操作,減少系統上下文切換時間。
若將CPSR的F位置為1,則會禁止FIQ中斷,若將CPSR的F位清零,處理器會在指令執行時檢查FIQ的引腳輸入,如果有請求信號將給予響應。可由外部通過對處理器上的nFIQ引腳輸入低電平產生FIQ。注意只有在特權模式下才能改變F位的狀態。
當處理器即將響應中斷時,由于取指令流水線的并行操作,程序指針PC的內容已經是當前指令后第3條指令的地址,即當前指令地址加12(對于Thumb指令則是當前指令地址加6)。在進入中斷時處理器會自動將PC內容減4保存到R14_fiq中。該地址是當前指令地址后第2條指令的地址,所以在返回斷點時還需要將R14_fiq的值減4,如圖2-16所示。

圖2-16 ARM指令中斷產生和返回地址示例圖
可以采用以下指令實現斷點的返回。
SUBS PC, R14_fiq,#4
該指令將寄存器R14_fiq的值減去4后,復制到程序計數器PC中,從而實現從異常處理程序中的返回,同時將SPSR_fiq寄存器的內容恢復到當前程序狀態寄存器CPSR中。
2.普通中斷(Interrupt Request,IRQ)
IRQ異常屬于正常的中斷請求,可通過對處理器的nIRQ引腳輸入低電平產生,IRQ的優先級低于FIQ,即當IRQ和FIQ同時產生時先響應FIQ。當程序執行進入FIQ異常時,IRQ將被屏蔽,禁止在FIQ內嵌套IRQ。
若將CPSR的I位置為1,則會禁止IRQ中斷,若將CPSR的I位清零,處理器會在指令執行完之前檢查IRQ的輸入。注意只有在特權模式下才能改變I位的狀態,用戶模式則不可以。
如同圖2-16所示FIQ的中斷響應過程一樣,IRQ將采用如下指令返回斷點。
SUBS PC , R14_irq , #4
該指令將寄存器R14_irq的值減去4后,復制到程序計數器PC中,從而實現從異常處理程序中的返回,同時將SPSR_irq寄存器的內容復制到當前程序狀態寄存器CPSR中。
例如,整個地址空間的起始位置(地址0x00000000開始)有以下指令,一旦發生外部中斷請求,處理器首先自動保存當前狀態(PC-4送R14,CPSR送SPSR),進入外部中斷模式,接著執行地址0x00000018處的指令(b IRQ_SVC_HANDLER)跳轉到標號IRQ_SVC_HANDLER處開始執行。
b SYS_RST_HANDLER ;地址=0x00000000 b UDF_INS_HANDLER ;地址=0x00000004 b SWI_SVC_HANDLER ;地址=0x00000008 b INS_ABT_HANDLER ;地址=0x0000000c b DAT_ABT_HANDLER ;地址=0x00000010 b . ;地址=保留 b IRQ_SVC_HANDLER ;地址=0x00000018 b FIQ_SVC_HANDLER ;地址=0x0000001c
通常情況下IRQ_SVC_HANDLER處的代碼為:
IRQ_SVC_HANDLER sub lr, lr, #4 ;修正返回地址值 stmfd sp!, {r0-r3, lr} ;保存r0,r1,r2,r3及lr的值 ldr r0,=IRQ_SVC_Vector ;將中斷處理程序地址的指針值存入r0 ldr pc, [r0] ;從IRQ_SVC_Vector存儲單元取地址值送pc
處理器將通用寄存器和返回地址壓入堆棧,接著跳轉到外部中斷請求的中斷服務程序中。IRQ_SVC_Vector為外部中斷請求的中斷向量。
3.指令預取中止(Instruction Prefetch Abort)
指令預取中止是由存儲器系統向ARM處理器發出的存儲器中止(Abort)信號觸發的,產生的原因是由于處理器讀取的是一個無效的存儲單元,這將導致存儲系統將取到的內容標記為無效指令。但只有當處理器試圖執行該指令時,指令預取中止異常才會發生。如果指令的前一條指令是轉移指令則不會發生預取指令中止。指令預取中止在異常返回后通常將繼續讀取該指令。該過程如圖2-17所示。

圖2-17 ARM指令集指令預取中止產生和返回地址示意圖
指令預取中止異常處理程序可執行以下指令從異常返回,該指令同時實現從SPSR_abt恢復CPSR內容的功能。
SUBS PC, R14_abt, #4
4.數據中止(Data Abort)
數據中止也是由存儲器系統向ARM處理器發出的存儲器中止(Abort)信號觸發的,產生的原因是由于正在執行的指令訪問的(采用Load/Store指令)是一個無效的存儲單元,這將導致存儲系統將取到的數據標記為無效數據。數據異常會在后續指令或異常改變CPU狀態前產生。由于數據中止異常處理程序通常會重新建立有效的數據,所以返回后將繼續執行原指令。該過程如圖2-18所示。

圖2-18 ARM指令集數據中止異常產生和返回地址示意圖
如果希望異常返回后繼續執行原來產生數據中止的指令,異常處理程序可安排執行以下指令從異常返回,該指令同時實現從SPSR_abt恢復CPSR內容的功能。
SUBS PC, R14_abt, #8 ;繼續執行原產生數據中止的指令
但是如果不需要再次執行原先產生數據訪問中止的指令,則可按以下指令返回。
SUBS PC, R14_abt, #4 ;從原先產生數據訪問中止指令的下條指令開始執行
5.軟件中斷(Software Interrupt Instruction,SWI)
軟件中斷指令(SWI)用于實現由用戶模式進入管理模式,以獲得那些由特權模式才能使用的資源和服務。由于SWI指令是在指令譯碼時就被識別并做好了準備,一旦前條指令執行完就轉入異常處理程序,所以返回地址是其下一條指令。該過程如圖2-19所示。

圖2-19 ARM指令集軟件中斷產生和返回地址示意圖
軟件中斷處理程序無論是在ARM狀態還是Thumb狀態都可執行以下指令從SWI對應的軟件中斷服務程序返回SWI的下一條指令。
MOV PC , R14_svc
6.未定義指令(Undefined Instruction)
未定義指令異常發生在ARM處理器外部配置了協處理器的系統結構中。當ARM處理器執行了一條協處理器指令并得不到外部協處理器正確的應答時將產生未定義指令異常。
未定義指令異常也可以用于在沒有協處理器的系統中通過軟件模擬協處理器的功能,或者用于擴展ARM或Thumb指令集。未定義指令由于異常的產生在指令譯碼階段就被識別并在前條指令執行完后馬上進入異常。而異常返回后需要跳過該指令,所以返回地址是未定義指令的下條指令地址。該過程如圖2-20所示。

圖2-20 ARM指令集未定義指令異常產生和返回地址示意圖
在仿真未定義指令后可執行以下程序返回。
MOVS PC, R14_und
以上指令恢復PC(從R14_und)和CPSR(從SPSR_und)的值,并返回到未定義指令后的下一條指令。
2.4.6 異常優先級(Exception Priorities)
由于ARM處理器內的異常都是相互獨立的,所以可能會碰到同時發生多個異常的情況。由于處理器任意時刻只能處理一個異常請求,故將這些異常設置了如表2-13所示的固定優先級,處理器總是先處理優先級最高的異常。
表2-13 異常優先級
- 我的J2EE成功之路
- AWS:Security Best Practices on AWS
- Dreamweaver CS3網頁設計與網站建設詳解
- iClone 4.31 3D Animation Beginner's Guide
- 樂高機器人—槍械武器庫
- 運動控制系統應用與實踐
- JRuby語言實戰技術
- 計算智能算法及其生產調度應用
- 中小型網站建設與管理
- Hands-On Artificial Intelligence for Beginners
- 淘寶網店頁面設計、布局、配色、裝修一本通
- 細節決定交互設計的成敗
- Adobe Edge Quickstart Guide
- 數字中國:大數據與政府管理決策
- Arduino創意機器人入門:基于Mixly