新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > ARM中斷宏定義

        ARM中斷宏定義

        作者: 時間:2016-11-11 來源:網絡 收藏
        MACRO

        $HandlerLabel HANDLER $HandleLabel

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

        $HandlerLabel

        sub sp,sp,#4 ;decrement sp(to store jump address) 存貯PC跳轉地址

        stmfd sp!,{r0} ;PUSH the work register to stack(lr does not push because it return to original address)

        ldr r0,=$HandleLabel ;load the address of HandleXXX to r0

        ldr r0,[r0] ;load the contents(service routine start address) of HandleXXX

        str r0,[sp,#4] ;store the contents(ISR) of HandleXXX to stack

        ldmfd sp!,{r0,pc} ;POP the work register and pc(jump to ISR)

        MEND

        MACRO相當于c中的#define

        而$HandlerLabel 和 $HandleLabel是兩個參數,大家注意,第一個參數和第二個參數是不一樣的,中間少了個r

        而第一個參數在本宏中是一個標號,而第二個函數是一個入口地址

        以下有定義:

        HandlerFIQ HANDLER HandleFIQ

        HandlerIRQ HANDLER HandleIRQ

        HandlerUndef HANDLER HandleUndef

        HandlerSWI HANDLER HandleSWI

        HandlerDabort HANDLER HandleDabort

        HandlerPabort HANDLER HandlePabort

        拿HandlerSWI HANDLER HandleSWI說明:把它用宏給替換下來以后是:

        $HandlerSWI

        1:sub sp,sp,#4 ;decrement sp(to store jump address) 存貯PC跳轉地址

        2:stmfd sp!,{r0} ;PUSH the work register to stack(lr does not push because it return to original address)

        3:ldr r0,=$HandleSWI ;load the address of HandleXXX to r0

        4:ldr r0,[r0] ;load the contents(service routine start address) of HandleXXX

        5:str r0,[sp,#4] ;store the contents(ISR) of HandleXXX to stack

        6:ldmfd sp!,{r0,pc} ;POP the work register and pc(jump to ISR)

        這段宏定義的作用是什么呢?是安裝SWI中斷,如何安裝的呢?

        sub sp,sp,#4 是把SP的地址減4字節,而這個地方需要存放跳轉地址也就是第5行的HandleSWI指向的內容(ISR)

        接下來是壓棧所需要的寄存器r0,因為接下來需要使用r0所以先壓棧r0,這也是為什么剛剛先把SP加四字節的原因,第6句話就是跳轉到剛剛第5句所壓棧的地址處,也就是HandleSWI指向的內容(ISR)處

        這里有一句話不是很明白,就是r0,這樣壓棧又出棧,跟沒有壓和出有什么區別,也就是說,上下文的內容一樣了,破壞了中斷前的r0,返回后的r0不再是原先的r0了,不理解?

        VectorsAddr

        LDR PC, Reset_Addr

        LDR PC, Undefined_Addr

        LDR PC, SWI_Addr

        LDR PC, Prefetch_Addr

        LDR PC, Abort_Addr

        NOP ; Reserved vector

        LDR PC, IRQ_Addr

        LDR PC, FIQ_Addr

        EXPORT VectorsAddr

        Reset_Addr DCD ResetHandler ;第一次地址轉換

        Undefined_Addr DCD HandlerUndef

        SWI_Addr DCD HandlerSWI

        Prefetch_Addr DCD HandlerPabort

        Abort_Addr DCD HandlerDabort

        IRQ_Addr DCD HandlerIRQ

        FIQ_Addr DCD HandlerFIQ

        按照我的想法執行中斷時是這樣的:

        首先PC->0x30000000比如說這個地址是IRQ_Addr ,因為DCD是接下來的連續的4字節,PC需要執行

        PC->0x30000004這個地址就是執行的HandlerIRQ,而這個地址根據上面安裝好的中斷,它應該是一個指針,也就是說PC執行的這一句話是一個跳轉指令,因為HandlerIRQ是一個指針,那么應該跳到HandlerIRQ所指地方處運行,HandlerIRQ所指的就是真正的中斷程序IRQ_ISR,大家看這里使用了兩次地址轉換,第一次是順序執行,第二次才是真正的跳轉,那么我們在安裝中斷時就是在第二次的地方改變HandlerIRQ所指向的函數就可以控制中斷函數的不同。

        MACRO ;宏定義開始
        MOV_PC_LR ;宏的名字
        [THUMBCODE ;表示在Thumb工作狀態
        bxlr ;分支到 Thumb 代碼 lr
        |
        movpc,lr ;把lr 保存到PC指針
        ]
        MEND ;宏定義結束

        ;arm處理器有兩種工作狀態
        1.arm:32位 這種工作狀態下執行字對準的arm指令

        2.Thumb:16位 這種工作狀態執行半字對準的Thumb指令


        ;因為處理器分為16位 32位兩種工作狀態 程序的編譯器也是分16位和32兩種編譯方式 所以下面的程序用于根據處理器工作狀態確定編譯器編譯方式
        ;code16偽指令指示匯編編譯器后面的指令為16位的thumb指令
        ;code32偽指令指示匯編編譯器后面的指令為32位的arm指令
        ;這段是為了統一目前的處理器工作狀態和軟件編譯方式(16位編譯環境使用tasm.exe編譯)

        另外
        [ =if
        | =else
        ] =end if



        關鍵詞: ARM中斷宏定

        評論


        技術專區

        關閉
        主站蜘蛛池模板: 博罗县| 吉木萨尔县| 武川县| 句容市| 霍林郭勒市| 确山县| 探索| 桂平市| 泰兴市| 资兴市| 得荣县| 安庆市| 钟祥市| 固安县| 新密市| 濮阳县| 三亚市| 同仁县| 华蓥市| 壤塘县| 时尚| 台东市| 乌恰县| 江孜县| 南丹县| 上犹县| 南通市| 保山市| 株洲市| 南宫市| 庄浪县| 社旗县| 宕昌县| 乌拉特后旗| 万山特区| 天长市| 彭泽县| 新营市| 福安市| 内乡县| 揭东县|