- 深入理解嵌入式Linux設備驅動程序
- 曹國輝 曾志鵬
- 1964字
- 2018-12-29 12:02:38
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。

- Citrix XenApp Performance Essentials
- Linux自動化運維:Shell與Ansible(微課版)
- 嵌入式實時操作系統μC/OS原理與實踐
- 竹林蹊徑:深入淺出windows驅動開發
- Mobile First Design with HTML5 and CSS3
- Linux系統安全基礎:二進制代碼安全性分析基礎與實踐
- 網絡操作系統教程:Windows Server 2016管理與配置
- AWS Development Essentials
- Mastering Reactive JavaScript
- 完美應用RHEL 8
- 操作系統分析
- Learn SwiftUI
- Hadoop Real-World Solutions Cookbook
- Windows Server 2008組網技術與實訓(第3版)
- 嵌入式微系統