ARM異常 乙個Uart中斷的觸發處理過程

2021-09-08 18:56:32 字數 4384 閱讀 2045

首先給出一些定義:

intoffset    equ  0x4a000014    ;interruot request source offset

_isr_startaddress    equ 0x33ffff00

macro

$handlerlabel handler $handlelabel

$handlerlabel

sub sp,sp,#

4;decrement sp(to store jump address)

stmfd sp!, ;push the work register to stack(lr does t push because it return

to original address)

ldr r0,=$handlelabel ;load the address of handle*** to r0

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

str r0,[sp,#

4] ;store the contents(isr) of handle*** to stack

ldmfd sp!, ;pop the work register and pc(jump to isr)

mend

下面進入正題:

preserve8

area reset,code,readonly

entry

export __entry

__entry

resetentry

b resethandler ;

0x0b handlerundef ;handler

forundefined mode

b handlerswi ;handler

forswi interrupt

b handlerpabort ;handler

forpabort

b handlerdabort ;handler

fordabort

b . ;reserved

b handlerirq ;handler

forirq interrupt

b handlerfiq ;handler

forfiq interrupt

b enterpwdn ; must be @

0x20

....

handlerirq handler handleirq

................

; setup irq handler

//建立中斷表

ldr r0,=handleirq ;this routine is

needed

ldr r1,=isrirq ;if there isn t '

subs pc,lr,#4

' at 0x18, 0x1c

str r1,[r0]

................

^ _isr_startaddress ;0x33ffff00

handlereset #

4handleundef #

4handleswi #

4handlepabort #

4handledabort #

4handlereserved #

4handleirq #

4handlefiq #

4 ;0x33ffff1c

;intvectortable

;@0x33ff_ff20

handleeint0 #

4 ;0x33ffff20

handleeint1 #

4handleeint2 #

4.................................

handleuart1        #   4            ;0x33ffff7c

.................................

uart是乙個外部中斷,走的是fiq.

外部中斷 --> b    handlerfiq ;

看**發現handlerfiq在init.s中進行了巨集定義,展開之後得到:

//

展開巨集 handlerirq  handler  handleirq

handlerirq

sub sp,sp,#

4;decrement sp(to store jump address)

stmfd sp!, ;push the work register to stack(lr does t push because it return

to original address)

ldr r0,=$handleirq ;load the address of handle*** to r0

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

str r0,[sp,#

4] ;store the contents(isr) of handle*** to stack

ldmfd sp!, ;pop the work register and pc(jump to isr)

可以看到,handlerirq是乙個標準的中斷處理過程(正因如此使用了巨集進行封裝): 首先儲存現場,然後跳轉到handleirq,從handleirq回來之後恢復現場.

handleirq其實是乙個函式指標,它可以在程式中被我們指向某乙個處理函式. 這裡我們指向了isrirq. 在isrirq裡,我們讀取intoffset暫存器的值,加上外部中斷的起始值handleeint0,這樣我們就獲得了世紀的中斷入口handleuart1. 通過ldmfd sp!,

,我們跳轉進入了handleuart1

對應的實際的中斷處理函式(見後面的分析).

isrirqsub sp,sp,#4 ;reserved forpc

stmfd sp!,ldr r9,=intoffset

ldr r9,[r9]

ldr r8,=handleeint0

add r8,r8,r9,lsl #2 ;//r8=r8+(r9*4) ldr r8,[r8] str r8,[sp,#8]ldmfd sp!,

上面說到,"通過ldmfd sp!,,我們跳轉進入了handleuart1對應的實際的中斷處理函式.

" 怎麼跳轉的呢,在**裡,我們又實現並繫結了handleuart1

的處理函式uart1_txrxint:

//

2440addr.h

#define pisr_uart1 (*(unsigned *)(_isr_startaddress+0x7c))

pisr_uart1=(unsigned)uart1_txrxint;

extern unsigned char uartbuf1[256

];void __irq uart0_txrxint(void)//

這裡只處理了接收中斷

*pbuf = '\0'

;

rintsubmsk &= ~bit_sub_rxd0;

rsrcpnd |=bit_uart0;

rintpnd |=bit_uart0;

rintsubmsk &= ~(bit_sub_txd0);

}}

arm中斷保護和恢復 ARM中斷異常處理的返回

舉個小例子,下面是一段arm彙編 0x3000bl add 0x3004mov r0,0 0x3008mov r1,1 0x300cmov r2,2 area test,code,readonly entry start mov r0,1 mov r1,1 bl add mov r0,0 mov r...

arm中斷保護和恢復 ARM中斷異常處理的返回

舉個小例子,下面是一段arm彙編 位址指令 0x3000 bl add 0x3004 mov r0,0 0x3008 mov r1,1 0x300c mov r2,2 area test,code,readonly entry start mov r0,1 mov r1,1 bl add mov r...

ARM中的異常和中斷

arm處理器中主要有7個異常 2個中斷異常 1 復位異常 在以arm為核的微控制器中,常把下列事件作為引起復位的原因。上電復位 在上電後,復位使內部達到預定的狀態,特別是程式跳到初始入口 復位引腳上的復位脈衝 這是由外部其他控制訊號引起的 對系統電源檢測發現過壓或欠壓 時鐘異常復位。arm處理器復位...