新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > ARM微處理器的編程模型之:異常中斷處理

        ARM微處理器的編程模型之:異常中斷處理

        作者: 時間:2013-09-13 來源:網絡 收藏

        本文引用地址:http://www.104case.com/article/257085.htm

        3.4.4 異常響應流程

        1.判斷處理器狀態

        當異常發生時,處理器自動切換到狀態,所以在異常處理函數中要判斷在異常發生前處理器是狀態還是Thumb狀態。這可以通過檢測SPSR的T位來判斷。

        通常情況下,只有在SWI處理函數中才需要知道異常發生前處理器的狀態。所以在Thumb狀態下,調用SWI軟中斷異常必須注意以下兩點。

        ① 發生異常的指令地址為(lr-2)而不是(lr-4)。

        ② Thumb狀態下的指令是16位的,在判斷中斷向量號時使用半字加載指令LDRH。

        下面的例子顯示了一個標準的SWI處理函數,在函數中通過SPSR的T位判斷異常發生前的處理器狀態。

        T_bit EQU 0x20 ; bit 5. SPSR中的/Thumb狀態位,

        :

        :

        SWIHandler

        STMFD sp!, {r0-r3,r12,lr} ; 寄存器壓棧,保護程序現場

        MRS r0, spsr ; 讀SPSR寄存器,判斷異常發生前的處理器狀態

        TST r0, #T_bit ; 檢測SPSR的T位,判斷異常發生前是否為Thumb狀態

        LDRNEH r0,[lr,#-2] ; 如果是Thumb狀態,使用半字加載指令讀取發生異常的指令地址

        BICNE r0,r0,#0xFF00 ; .提取中斷向量號.

        LDREQ r0,[lr,#-4] ; 如果是ARM狀態,使用字加載指令,讀取發生異常的指令地址

        BICEQ r0,r0,#0xFF000000 ; 提取中斷向量號并將中斷向量號存入r0

        ; r0 存儲中斷向量號

        CMP r0, #MaxSWI ; 判斷中斷是否超出范圍

        LDRLS pc, [pc, r0, LSL#2] ; 如果未超出范圍,跳轉到軟中斷向量表Switable

        B SWIOutOfRange ; 如果超出范圍,跳轉到軟中斷越界處理程序

        switable

        DCD do_swi_1

        DCD do_swi_2

        :

        :

        do_swi_1

        ; 1號軟中斷處理函數

        LDMFD sp!, {r0-r3,r12,pc}^ ; Restore the registers and return.

        ; 恢復寄存器并返回

        do_swi_2 ; 2號軟中斷處理函數

        :

        2.向量表

        如前面介紹向量表時提到的,每一個異常發生時總是從異常向量表開始跳轉。最簡單的一種情況是向量表里面的每一條指令直接跳向對應的異常處理函數。其中快速中斷處理函數FIQ_handler()可以直接從地址0x1C處開始,省下一條跳轉指令,如圖3.6所示。

        圖3.6 異常處理向量表

        但跳轉指令B的跳轉范圍為±32MB,但很多情況下不能保證所有的異常處理函數都定位在向量的32MB范圍內,需要更大范圍的跳轉,而且由于向量表空間的限制,只能由一條指令完成。具體實現方法有下面兩種。

        (1)MOV PC,#imme_value

        這種辦法將目標地址直接賦值給PC。但這種方法受格式限制不能處理任意立即數。這個立即數由一個8位數值循環右移偶數位得到。

        (2)LDR PC,[PC+offset]

        把目標地址先存儲在某一個合適的地址空間,然后把這個存儲器單元的32位數據傳送給PC來實現跳轉。

        這種方法對目標地址值沒有要求。但是存儲目標地址的存儲器單元必須在當前指令的±4KB空間范圍內。

        注意

        在計算指令中引用offset數值的時候,要考慮處理器流水線中指令預取對PC值的影響。



        評論


        相關推薦

        技術專區

        關閉
        主站蜘蛛池模板: 江陵县| 云霄县| 巴东县| 长寿区| 长垣县| 裕民县| 鱼台县| 宝应县| 安岳县| 柳江县| 延长县| 洛扎县| 永年县| 琼结县| 阳江市| 始兴县| 临沭县| 长宁区| 兴业县| 桐城市| 内丘县| 广平县| 洛隆县| 马鞍山市| 翼城县| 来宾市| 中西区| 九龙坡区| 武乡县| 汉寿县| 沽源县| 宿州市| 驻马店市| 桦甸市| 始兴县| 瓮安县| 高陵县| 玉龙| 东乡族自治县| 大渡口区| 嵩明县|