官术网_书友最值得收藏!

1.3 嵌入式ARM系統的中斷系統

中斷機制是計算機系統中一種非常重要的外部事件處理機制。中斷機制是指在計算機執行當前任務的過程中,當外部事件發生時,計算機可以暫停當前正在執行的任務,轉去處理外部事件,待外部事件處理完成后,繼續恢復原來執行的任務。

ARM9采用二級中斷機制。所謂二級中斷,是指當外部中斷產生時,系統需要通過兩次跳轉,才能執行真正的中斷服務處理程序。下面以按鍵中斷處理過程為例來詳細說明ARM9系統中的中斷處理過程。

按鍵使用外部中斷EINT8、EINT11、EINT13、EINT14、EINT15、EINT19,它們公用一個外部中斷源EINT8_23,中斷號為5。

中斷向量:中斷服務程序的入口地址。

中斷向量地址:內存中存放中斷服務程序入口地址的地址。

1.3.1 ARM中斷機制代碼分析

外部中斷產生后,要想正確執行相應的中斷處理程序,首先需要在內存中建立中斷向量表。系統中斷向量表中存放中斷服務處理程序的起始地址。系統啟動代碼中建立的中斷向量的代碼如下所示。

                                        ; interrupt service routing start address
                                        _ISR_STARTADDRESS         EQU      0x33ffff00
                                        ; ^ is same with MAP, the following also can be:
                                        ; MAP _ISR_STARTADDRESS for define interrupt service routing service
                                        ;^_ISR_STARTADDRESS ; _ISR_STARTADDRESS=0x33FF_FF00
                                        AREA RamData, DATA, READWRITE
                                        MAP      _ISR_STARTADDRESS
                                        HandleReset               #      4
                                        HandleUndef               #      4
                                        HandleSWI                 #      4
                                        HandlePabort              #      4
                                        HandleDabort              #      4
                                        HandleReserved            #      4
                                        HandleIRQ                 #      4
                                        HandleFIQ           #   4
                                        ;Don' t use the label' IntVectorTable'
                                        ;The value of IntVectorTable is different with the address you think it may be
                                        ;IntVectorTable
                                        ;@0x33FF_FF20
                                        HandleEINT0               #      4
                                        HandleEINT1               #      4
                                        HandleEINT2               #      4
                                        HandleEINT3               #      4
                                        HandleEINT4_7             #      4
                                        HandleEINT8_23            #      4
                                        HandleCAM                 #      4          ; Added for 2440
                                        HandleBATFLT              #      4
                                        HandleTICK                #      4
                                        HandleWDT                 #      4
                                        HandleTIMER0              #      4
                                        HandleTIMER1              #      4
                                        HandleTIMER2              #      4
                                        HandleTIMER3              #      4
                                        HandleTIMER4              #      4
                                        HandleUART2               #      4
                                        ;@0x33FF_FF60
                                        HandleLCD                 #      4
                                        HandleDMA0                #      4
                                        HandleDMA1                #      4
                                        HandleDMA2                #      4
                                        HandleDMA3                #      4
                                        HandleMMC                 #      4
                                        HandleSPI0                #      4
                                        HandleUART1               #      4
                                        HandleNFCON               #      4          ; Added for 2440
                                        HandleUSBD                #      4
                                        HandleUSBH                #      4
                                        HandleIIC                 #      4
                                        HandleUART0               #      4
                                        HandleSPI1                #      4
                                        HandleRTC                 #      4
                                        HandleADC                 #      4
                                        ;@0x33FF_FFA0
                                              END

MAP用于定義一個內存表的首地址,在這里用MAP定義的首地址為_ISR_STARTADDRESS,內存表長度為0xA0,給每一個中斷源分配一個占4字節的內存單元,用來存放該中斷對應的中斷服務程序入口地址。其中標號HandleEINT8_23是存放EINT8_23中斷服務程序的入口地址的地址;標號HandleIRQ表示存放外部中斷異常處理程序的地址,即HandleIRQ本身是一個地址。在本例中,HandleIRQ的值為0x33FFFF18,內存地址0x33FFFF18開始的4字節的存儲單元存放的是外部中斷異常處理程序的地址。HandleEINT8_23的值為0x33FFFF34,內存地址為0x33FFFF34,開始的4字節的存儲單元存放外部中斷EINT8_23的中斷服務程序地址。

前面提到過在系統的啟動代碼中定義了一個HANDLER宏,該宏的作用是把中斷處理程序的入口地址加載到PC寄存器中。在接下來的代碼中,使用HANDLER宏來定義外部中斷異常處理程序的入口,代碼如下所示。

宏展開后,代碼如下所示。

                                        HandlerIRQ       HANDLER   HandleIRQ
                                        HandlerIRQ
                    sub                          sp, sp, #4              ; decrement sp(to store jump address)
                    stmfdsp! , {r0}                                      ; PUSH the work register to stack
                    ldr      r0, =HandleIRQ                              ; 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)

HandleIRQ為前面定義的一個地址,其值為0x33FFFF18,里面存放著外部中斷異常處理程序的入口地址(即IsrIRQ),在前面的中斷向量表中已經定義。

在系統的啟動代碼中定義外部中斷異常處理程序,代碼如下所示。

                IsrIRQ
                    sub   sp, sp, #4        ; reserved for PC
                    stmfd sp! , {r8-r9}

                    ldr   r9, =INTOFFSET
                    ldr   r9, [r9]
                    ldr   r8, =HandleEINT0
                    add   r8, r8, r9, lsl#2
                    ldr   r8, [r8]
                    str   r8, [sp, #8]
                    ldmfd     sp! , {r8-r9, pc}

外部中斷異常處理程序根據中斷號獲取該中斷對應的中斷服務處理程序地址,然后把該中斷號對應的中斷服務程序地址裝載到計算機PC寄存器中,使得CPU轉去執行該中斷號對應的中斷服務處理程序。

外部中斷異常處理程序根據外部中斷號(INTOFFSET)和外部中斷向量首地址(HandleEINT0)來計算對應的中斷的中斷向量地址,然后從該中斷向量地址中取出中斷向量(即中斷服務程序地址)裝到計算機中,開始執行中斷服務程序。

思考題

外部中斷異常處理程序和宏HANDLER實現的功能差不多,那為什么不用HANDLER來定義外部中斷異常處理程序呢?

原因在于HANDLER和IsrIRQ獲取中斷向量地址方式不一樣,HANDLER直接獲取中斷向量地址,而IsrIRQ是通過中斷向量基地址(HandleEINT0)和中斷號(INTOFFSET)計算出該中斷對應的中斷向量地址的。

系統啟動代碼在初始化堆棧后,開始安裝外部中斷異常處理程序,代碼如下所示。

              ; Setup IRQ handler
                  ;HandleIRQ is for save interrupt service routing address
                  ldr   r0, =HandleIRQ        ; This routine is needed
                  ldr   r1, =IsrIRQ   ; if there isn' t' subs pc, lr, #4' at 0x18,0x1c
                  str   r1, [r0]

安裝外部中斷異常的流程非常簡單,即把外部中斷異常處理程序IsrIRQ的地址存放到外部中斷異常向量表的HandleIRQ表項中,HandleIRQ表示存放外部中斷異常處理程序地址的地址。

安裝了外部中斷異常處理程序后,還要繼續安裝外部中斷EINT8_23中斷處理程序。外部中斷EINT8_23的中斷服務程序安裝在C語言源文件中,其代碼如下所示。

              #define pISR_EINT8_23    (*(unsigned*)(_ISR_STARTADDRESS+0x34))

              pISR_EINT8_23=(U32)KeyISR;// set up KeyBoard interrupt service routing

外部中斷EINT8_23中斷服務程序的安裝非常簡單,把外部中斷EINT8_23中斷服務程序的KeyISR的地址存放到外部中斷向量表的EINT8_23表項中即可。

1.3.2 ARM中斷服務處理程序的響應過程

分析完ARM中斷服務處理的相關代碼后,下面來看一下按鍵中斷的處理響應過程。

按鍵的中斷處理流程如下:

用戶按下按鍵時,通過外部中斷EINT8_23觸發外部中斷異常,計算機跳轉到異常向量表的外部中斷異常向量地址處執行。外部中斷異常向量地址里只有一條跳轉指令,于是CPU開始跳轉到HandlerIRQ處執行外部中斷異常處理程序。外部中斷異常處理程序從中斷向量表獲取外部中斷服務處理程序IsrIRQ的入口地址,開始執行外部中斷服務處理程序IsrIRQ。IsrIRQ根據外部中斷號EINT8_23和外部中斷向量表首地址計算該中斷號對應的中斷向量地址,然后從該中斷向量地址中取出該中斷向量(即該中斷服務程序的入口地址)裝載到計算機寄存器中,于是開始執行真正的中斷服務處理程序KeyISR。

主站蜘蛛池模板: 乌拉特中旗| 灵寿县| 浏阳市| 北宁市| 兴国县| 三台县| 普兰县| 牙克石市| 都昌县| 长春市| 济源市| 南康市| 兴安盟| 洛隆县| 隆德县| 青铜峡市| 玛纳斯县| 株洲市| 东源县| 拜泉县| 拉萨市| 温宿县| 遵义县| 庆安县| 唐山市| 德庆县| 安吉县| 巩留县| 彩票| 南开区| 桓台县| 新宁县| 同心县| 南涧| 沾益县| 香港| 彝良县| 资兴市| 正镶白旗| 英德市| 咸宁市|