[ARM Cortex-A8]S5PV210(ARM-Cortex A8)中斷過程圖解
本文將講述三星S5PV210 SOC晶片(ARM-Cortex A8核心)裸板的中斷髮生和處理過程。
關於中斷的說明:
中斷:指當出現需要時,CPU暫時停止當前程式的執行轉而執行處理新情況的程式和執行過程。ARM的中斷比較複雜,與其它的處理器一樣,ARM的中斷可分為外部中斷和內部中斷。
中斷的三個關鍵部分包括:中斷源、中斷處理程式和中斷服務程式。以下將依據這幾個關鍵部分對S5PV210的中斷進行說明。
外部中斷源的配置:
1. 如圖的最右,首先應該配置GPIO引腳的相應暫存器為外部中斷源模式。
2. 然後需要配置外部中斷控制器EXT_C,共有2個暫存器,分別為控制暫存器和中斷掩碼。
3. 配置中斷向量控制器VIC,此處共需要配置3個暫存器,S5PV210共有VIC[0-3]四個中斷向量控制器。
內部中斷源的配置:
1. 內部中斷不經過外部中斷控制器,但仍需要經過中斷向量控制器VIC,S5PV210共有VIC[0-3]四個中斷向量控制器。
到此為止,外部中斷訊號終於可以送到A8處理器中了。
程式狀態暫存器的配置:
不管是外部中斷還是內部中斷,都需要配置程式狀態暫存器CPSR,把IRQ模式開啟,才能正常觸發中斷。關於CPSR如下圖所示:
中斷處理程式的配置:
需要把中斷處理程式存放到iRAM中去,中斷髮生後SOC晶片會根據廠家的定義自己跳轉到這裡。中斷處理程式包括兩部分,進入中斷部分和退出中斷部分。其功能應該包括:
- 把公共的通用暫存器的內容壓入記憶體棧中(請參閱下文的ARM處理器模式介紹)
- 跳轉到中斷服務程式當中
- 把記憶體棧中的暫存器內容恢復到公共暫存器中
- 跳轉回發生中斷的地方並把CPU狀態切換回去(請參閱下文的ARM處理器模式介紹)
中斷服務程式的配置:
這個由程式設計師自己定義。
需要把中斷服務程式的地址存放到對應的中斷向量地址暫存器當中,這個在晶片的Datasheet中可以查到。例如:VIC0的第16箇中斷的處理程式,就放置在VIC0ADDRESS16這個暫存器當中。當發生中斷時,這個暫存器裡面的值會自動裝載到VIC0ADDRESS這個暫存器中,在中斷處理程式中取出這個暫存器的值然後跳轉到中斷服務程式中去。
------------------------------------------------------------------------------------------------------
ARM的處理器模式介紹
瞭解ARM處理器的模式,有助於我們更深入地瞭解中斷。ARM共有以下7種工作模式,本次講解使用的是IRQ模式。
- 使用者模式(User): ARM處理器正常的程式執行狀態
- 快速中斷模式(FIQ): 用於高速資料傳輸或通道處理
- 外部中斷模式(IRQ): 用於通用的中斷處理
- 管理模式(Supervisor): 作業系統使用的保護模式
- 資料訪問終止模式(Abort): 當資料或指令預取終止時進入該模式,可用於虛擬儲存及儲存保護
- 系統模式(System): 執行具有特權的作業系統任務
- 未定義指令中止模式(Undifined): 當未定義的指令執行時進入該模式,可用於支援硬體協處理器的軟體模擬
ARM處理器有7種不同的處理器模式,在每一種處理器模式中有一組相應的暫存器組。任意時刻(也就是任意的處理器模式下),可見的暫存器包括15個通用暫存器(R0~R14)、一個或兩個狀態暫存器及程式計數器(PC)。
在所有的暫存器中,有些是各模式共用的同一個物理暫存器,有些是各模式自己擁有的獨立的物理暫存器,如圖所示。
我們從圖中可以看出普通使用者模式(Systen and User)、超級使用者模式(Supervisor)、和普通中斷模式(FIQ)的R0-R12暫存器是共用的,這樣也就不難理解為何要在中斷處理程式中把這13個暫存器和LR(R14)暫存器儲存到記憶體棧中了。
對於FIQ模式的R8~R14暫存器是獨有的,FIQ處理程式可以不必執行儲存和恢復中斷現場的指令,從而使中斷處理過程非常迅速。
幾個特殊的通用暫存器:
R13
每一種異常模式擁有自己的物理的R13。應用程式初始化該R13,使其指向該異常模式專用的棧地址。當進入異常模式時,可以將需要使用的暫存器儲存在R13所指的棧中;當退出異常處理程式時,將儲存在R13所指的棧中的暫存器值彈出。這樣就使異常處理程式不會破壞被其中斷程式的執行現場。
R14
R14又被稱為連線暫存器(Link Register,LR),在ARM體系中具有下面兩種殊的作用:
第1種:
每一種處理器模式自己的物理R14中存放當前子程式的返回地址。當通過BL或BLX指令呼叫子程式時,R14被設定成該子程式的返回地址。在子程式中,當把R14的值複製到程式計數器PC中時,子程式即返回。
第2種:
當異常中斷髮生時,該異常模式特定的物理R14被設定成該異常模式將要返回的地址,對於有些異常模式,R14的值可能與將返回的地址有一個常數的偏移量。具體的返回方式與子程式返回方式基本相同。
R15
R15用於程式計數器(PC),儲存了當前的程式跑到哪裡。
中斷觸發時到底發生了什麼?
首先處理器會回到ARM公司定義好的相應的異常地址去。
然後根據該地址中的內容進行下一步跳轉,這個跳轉地址是ARM公司定義好的,半導體廠商可以把這個地址設計為一個iROM或iRAM的地址,繼續進行下一步跳轉;也可以直接把這個地址設計為記憶體DRAM的地址。
S5PV210這塊晶片三星公司把IRQ跳轉的地址設定為iROM的地址,處理器會根據三星公司固化好的iROM程式,跳轉到相應的iRAM地址,三星公司在這個位置又定義了一個異常向量表,程式設計師編寫好的中斷處理程式碼就存放在這裡,然後根據中斷處理程式碼的邏輯進行下一步跳轉,最後到達中斷服務程式中。
最後附上一段中斷處理程式的程式碼:
.text
.extern uart_init
.extern printf
.extern Start_Arm
.global _start
_start:
mov r10,lr @把程式的入口放到R10暫存器中
bl uart_init @跳到串列埠初始化程式中,初始化串列埠主要是方便除錯
ldr r0,=fmt1 @初始化好之後列印一句話,這些都無關重要
bl printf
bl cpsr_init
bl vector_table_init
bl Start_Arm
cpsr_init: @設定cpsr暫存器
mrs r0,cpsr
bic r0,r0,#0x80
msr cpsr_c,r0
bx lr
vector_table_init: @初始化iRAM中的異常向量表,把中斷處理程式放到這個表中
ldr r0,=handle_irq
ldr r1,=0xd0037418
str r0,[r1]
bx lr
handle_irq: @中斷處理程式
sub lr,lr,#4
stmfd sp!,{r0-r12,lr}
ldr lr,=return_irq
ldr r1,=0xf2000000 @VIC0IRQSTATUS
ldr r2,[r1]
cmp r2,#0
beq return_irq
ldr r1,=0xf2000f00 @VIC0ADDRESS
ldr pc,[r1] @跳轉到中斷服務程式當中
return_irq:
ldmfd sp!,{r0-r12,pc}^
fmt1:
.asciz ">>> welcome to MyCode! <<<\n"
.end