新聞中心

        EEPW首頁 > 設計應用 > ARM中斷實現過程的個人筆記

        ARM中斷實現過程的個人筆記

        ——
        作者: 時間:2006-06-12 來源: 收藏
        決定開始學習嵌入式后,最先做的事情就是要熟悉ARM指令及其偽指令偽操作。ARM指令的助記符其實都是其具體功能的單次縮寫,所以學習的過程中最好利用網絡,從一些文獻或書籍中找到ARM指令助記符的全稱,這樣方便記憶。學完之后,我做了整理了一個有關這方面的筆記,有需要的朋友請郵件聯系:gmman@163.com
         
            接下來的學習過程中,比較難以理解的是ARM的中斷過程和存儲系統。ARM中斷的實現有些書上看一兩遍也不見得能夠完全理解,當然可能只對于像我一樣跨專業的朋友來說存在這個問題。這次只談中斷。由于是初學者,難免會出錯,敬請各位指正。
         
            當一個程序正常執行過程中,CPU可能檢測到有某個中斷源發出中斷請求,這時ARM硬件實現了程序強制跳轉,在這之前保存了相關信息,以便程序正常返回。如果是發生了Reset中斷,程序實現系統初始化設置。
            開始比較難以理解的是中斷產生后,程序都進行了哪些操作。我就從跟蹤PC作為分析的主線。以發生FIQ中斷為例。(只以ROM起始地址為0為例,不為0的情況參照存儲地址映射)
            最簡單的是中斷發生后,PC=0x08,在此地址處存放一個跳轉指令,跳轉到相關處理程序。當然多數情況中斷處理程序可能比較復雜,并且要處理多種中斷的情況下,采用一步映射兩步跳轉(我自己起的名字,不一定妥當)。如下圖所示:
            
        一步映射指,在RAM地址中建立一個中斷向量表,圖中該表起始地址為0x400000,在該表中存放的是中斷處理函數的入口地址。兩步跳轉是指,當中斷發生時,由于系統硬件強制程序跳轉到了0x08處,在該地址處是一個跳轉指令,跳轉到中斷函數地址解析程序IRQ_Handler,完成一步跳轉。解析程序(IRQ_Handler)的作用無非是把中斷向量表內中斷處理函數(SystemIrqHandler)的入口地址賦值給 PC,如圖所示PC=0x003000280,完成第二步跳轉,開始處理中斷。在中斷處理函數的最后,恢復中斷開始時保存的相關寄存器的值,完成中斷。
         
        下面以一個實例來具體說明中斷建立及實現的過程。
         
        首先通過偽指令建立一個中斷向量表,用于存放中斷程序的入口地址(如上圖中的中斷向量表,注意,此時表中還未賦值): 
        ;/* EXCEPTION HANDLER VECTOR TABLE */ 
         
        ^ DRAM_BASE 
        HandleReset # 4 
        HandleUndef # 4 
        HandleSwi # 4 
        HandlePrefetch # 4 
        HandleAbort # 4 
        HandleReserv # 4 
        HandleIrq # 4 
        HandleFiq # 4 
         
         
        然后定義一個連續的數據段,并把中斷處理函數的入口地址值賦給各字單元
        ExceptionHandlerTable 
        DCD UserCodeArea 
        DCD SystemUndefinedHandler 
        DCD SystemSwiHandler 
        DCD SystemPrefetchHandler 
        DCD SystemAbortHandler 
        DCD SystemReserv 
        DCD SystemIrqHandler 
        DCD SystemFiqHandler 
         
         
        下面從程序的開始處分析: 
        AREA Init, CODE, READONLY 
        ENTRY 
        /* ROM起始地址向量表 */
        B Reset_Handler 
        B Undefined_Handler 
        B SWI_Handler 
        B Prefetch_Handler 
        B Abort_Handler 
        NOP Reserved vector 
        B IRQ_Handler 
        B FIQ_Handler 
        /* B跳轉范圍限于+ -32M內*/
         
         
        /* 以下是地址解析程序 */
        IRQ_Handler 
        SUB sp, sp, #4 
        STMFD sp!, {r0} FD滿遞減堆棧 執行寄存器壓棧操作. 
        LDR r0, =HandleIrq  //對應程序開始處以偽指令定義的向量表
        LDR r0, [r0]  //中斷處理函數的地址賦給R0. 
        STR r0, [sp, #4]  //中斷處理函數的地址入棧 
        LDMFD sp!, {r0, pc} //實現程序跳轉,目前沒明白為什么又給r0賦值? 
         
         
        上面提到了還沒有給中斷向量表賦值,下面代碼把中斷處理函數的地址放到DRAM中斷向量表里
        EXCEPTION_VECTOR_TABLE_SETUP 
        LDR r0, =HandleReset 
        LDR r1, =ExceptionHandlerTable 
        MOV r2, #8 
        ExceptLoop 
        LDR r3, [r1], #4 
        STR r3, [r0], #4 
        SUBS r2, r2, #1 Down Count 
        BNE ExceptLoop ;; 
         
         
        下面是中斷處理函數 
        SystemIrqHandler 
        IMPORT ISR_IrqHandler 
        STMFD sp!, {r0-r7, lr} 
        BL ISR_IrqHandler 
        LDMFD sp!, {r0-r7, lr} 
        SUBS pc, lr, #4 
         
        它實際上只調用了下面的C語言的中斷處理函數,其他什么也沒做。 
        void ISR_IrqHandler(void) 

        IntOffSet = (U32)INTOFFSET; 
        (IntOffSet>>2) 
        (*InterruptHandlers[IntOffSet>>2])(); // Call interrupt service routine 

         
        以上編程思路是,先在系統初始化時重新建立一個中斷向量表,并把相關的中斷處理函數的地址放到中斷向量表中。當系統監測到有中斷源請求服務后,硬件實現pc跳轉到地址0x08處,執行一個跳轉指令B IRQ_Handler  , 然后執行地址解析程序,把中斷向量表中的中斷處理函數的入口地址賦給pc,開始響應中斷。在中斷處理函數的最后,執行
        LDMFD sp!, {r0-r7, lr} 
        SUBS pc, lr, #4 
        實現中斷的返回。


        評論


        相關推薦

        技術專區

        關閉
        主站蜘蛛池模板: 晋城| 白玉县| 柯坪县| 甘孜| 探索| 始兴县| 鄱阳县| 会理县| 白山市| 沙洋县| 抚顺县| 延津县| 义马市| 新津县| 鄂伦春自治旗| 闽清县| 新巴尔虎左旗| 筠连县| 资源县| 花垣县| 建湖县| 大田县| 体育| 仁寿县| 江山市| 清河县| 蓬安县| 绥江县| 洞头县| 综艺| 南城县| 山西省| 漯河市| 汉中市| 祁门县| 富顺县| 镇原县| 黎城县| 临猗县| 梅河口市| 驻马店市|