關於44b0的中斷呼叫的問題:
下面的**因為44b0中的各個中斷型別相似的,所以只是以timer為例。
在init.s中有這樣的**:
首先是乙個巨集的定義:
macro
$handlerlabel handler $handlelabel
$handlerlabel
sub sp,sp,#4 ;decrement sp(to store jump address)
stmfd sp!, ;push the work register to stack(lr doest 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
然後有乙個vector_branch
......
entry
......
vector_branch
......
ldr pc,=handlertimer1
......
irq_handler
import isr_irqhandler
stmfd sp!,
bl isr_irqhandler
ldmfd sp!,
subs pc, lr, #4
export irq_handler
......
handlertimer1 handler handletimer1
......
;setup irq handler
ldr r0,=handleirq ;this routine is needed
ldr r1,=irq_handler ;=isrirq,if there isn't 'subs pc,lr,#4' at 0x18,
0x1c
str r1,[r0]
然後,在另外的檔案isr_address.s中有下面的語句:
area isr_startaddress, data, noinit
......
export handletimer1
......
handletimer1 space 4
......
end另外,在scat_ram.scf中對儲存空間的分配有:
ram_load 0x00008000
ram 0x0x00100000
heap +0 uninit
stacks 0x0020000 uninit
isr_startaddress 0x0020000
}在uhalr_interruptrequestinit()中,有定義下面的東西
void uhalr_interruptrequestinit()
然後,在檔案isr.c和isr.h中定義下面的函式和資料結構。
void (*interrupthandlers[maxhndlrs])(void)=;
有函式void setisr_interrupt(int vector, void (*handler)(), int exint)
在說的理解之前,要謹記44b0提供了兩種向量和非向量的中斷mode。
下面是我的理解:
(1)在向量中斷時採取的操作
從scat_ram.scf和isr_address.s中,可以得到從0x0020000處開始的位置,為每乙個中斷留出了4個位元組
的空間,其中包括timer1.這些空間應該是用來儲存isr的位址(指標)的。
繼續,從scat_ram.scf也可以得到,從0x00008000開始存放init.s的資料。
將handlertimer1 handler handletimer1的巨集展開,得到
handlertimer1
sub sp,sp,#4
stmfd sp!,
ldr r0,=handletimer1
ldr r0,[r0]
str r0,[sp,#4]
ldmfd sp!,
這裡結合vector_brach中的**
ldr pc,=handlertimer1
來看,假設現在timer1中斷到來,那麼執行該ldr命令,pc值指向sub處開始執行。ldr
r0,=handletimer1會將isr_address.s中export的handletimer1載入到r0中,這裡的r0中所放的實際上也
是乙個位址,指向相應isr指標的指標,執行ldr r0,[r0]後,r0中才是指向isr的指標(位址),通過
堆疊的巧妙操作,pc指向了isr,開始執行相應的isr。這個isr怎樣是怎樣和相應的handle對應的呢?在
函式uhalr_interruptrequestinit()中,有pisr_undef= (unsigned) debugundef等,這些的意思是在
pisr_undef所代表的位址處放置指向debugundef的指標(位址)。
(2)非向量中斷下的操作
回到init.s中,有語句
;setup irq handler
ldr r0,=handleirq ;this routine is needed
ldr r1,=irq_handler ;=isrirq,if there isn't 'subs pc,lr,#4' at 0x18,
0x1c
str r1,[r0]
這裡要注意了,handleirq也是isr_address.s中的那個,只是這裡將irq_handler的位址放到handleirq預
留的空間中。
同樣,如果在這種mode下,有乙個irq中斷到來,那麼首先系統也會像(1)那樣找到handleirq,但是現在
那裡放置的是irq_handle的位址,所以轉向irq_handle,繼而轉向isr_irqhandler。在isr_irqhandler中
,利用i_ispc暫存器找到中斷源,然後呼叫相應源的處理函式。
借用linux的概念,這個執行的isr應該在系統初始化的時候被註冊。這個任務應該是由函式
setisr_interrupt完成的,在setisr_interrupt中,呼叫了(*interrupthandlers[maxhndlrs])(void),
有interrupthandlers[vector] = handler;這個vector明顯是44b0定義的若干irq中斷的相對偏移。
44B0的向量中斷
44b0 的向量中斷響應過程是中斷發生後晶元會自動跳轉到 0x00000018 處執行指令 entry b resethandler 0x00 b handlerundef 0x04 b handlerswi 0x08 b handlerpabort 0x0c b handlerdabort 0x1...
44b0實驗 中斷實驗
之前也提到的過,區區乙個簡單的中斷實驗竟然讓我大動干戈,費了n久才搞定。現在把具體實驗寫寫吧。先把 貼出來吧 include include inc 44b.h include inc option.h include inc def.h include eint.h void irq eint45...
如何在44B0板子的RAM中執行uclinux
1 將編譯好的uclinux rom.bin放在tftpd32的預設傳輸目錄下,在uboot中輸入命令tftp 0x0c booting image at 0c208000 image name uclinux hfrk www.21spacetime.net created 2009 01 15 ...