關於44b0的中斷呼叫的問題

2021-04-12 16:36:43 字數 3525 閱讀 1205

關於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 ...