S3C44B0的中斷模式

2021-06-20 07:04:24 字數 4736 閱讀 3576

對於各種中斷源的響應,s3c44b0有兩種中斷模式:向量中斷模式和非向量中斷模式,這就導致在軟體處理上,可以很靈活的處理中斷請求。一般來說做如下處理:

如果系統採用的rom定位在位址0x00,則中斷向量標應該包含一系列分支語句,跳轉到相應的中斷處理程式(這也是s3c44b0所支援的模式)

如果rom定位到別的位址處,向量必須由初始化**進行動態定位。

一般把這部分功能放在bootloader中處理,對於這一點來說初學者很容易搞混,下面就詳細解釋中斷處理的幾種實現方式。

一、中斷處理的實現方式

1、向量中斷模式(也叫向量中斷模式)

irq

支援,

fiq

不支援)

為了縮短中斷模式在進入所需的服務前所需要的中斷響應時間,s3c44b0提供了一種新的中斷模式——向量中斷模式。當多重中斷源請求中斷時,硬體優先順序邏輯會判斷哪乙個中斷將會被執行,同時,硬體邏輯自動執行由0x18位址到各個中斷源向量位址的跳轉指令,然後再由中斷源向量進入相應的中斷處理程式。簡單的說,每個中斷源對應乙個記憶體位址,只要在對應的位址上設定一條到中斷服務程式的跳轉指令,cpu自動跳轉到響應的中斷處理函式。和原來的軟體實現方式相比,這種方式可顯著縮短中斷響應時間。

當系統發生

irq中斷時候,

cpu的

pc會讀取位於

0x18

處的irq

中斷指令(也就是說跳到位址

0x18

處去執行指令),然後

cpu自動讀取對應於該中斷源確定位址上的指令取代

0x18

處的指令(這個過程是由系統自動完成的,不需要使用者程式設計),通過跳轉指令,系統就直接跳轉到對應位址,這樣節省了中斷處理時間,提高中斷處理速度。——通俗點說,如果採用了向量中斷模式,一旦發生中斷,

cpu就會跳到相應的位址來執行指令。

例如adc

中斷的向量位址為

0xc0,

一旦發生

adc中斷,

pc就先跳到了位址

0x18

再跳到0xc0

上來執行命令,但對於使用者來說,就跟一發生中斷就直接跳到了

0xc0

上沒有區別,這個先跳到

0x18

的過程可以忽略不計,由系統自動完成。如果在

0xc0

處放如下**:

ldr pc , =handleradc

,當adc

中斷產生的時候系統會自動跳轉到

handleradc

函式中。

2、非向量中斷模式

這種模式處理方式是一種傳統的中斷處理方法,當系統產生中斷的時候,系統將

interrupt pending

暫存器中對應標誌位置位(當然向量中斷模式也有這步發生),然後跳轉到位址

0x18

處。使用者需要在位址

0x18

處寫乙個統一中斷函式,該函式通過讀取

interrupt pending

暫存器中對應標誌位,來判斷中斷源,並根據優先順序關係再跳到對應中斷源的處理**中。

在非向量中斷模式下,有兩種方式可以使pc指向相應的中斷處理程式。

第一種方法,可以通過對i_ispr/f_ispr暫存器的分析判斷出中斷的型別,然後再把pc指向相應的中斷處理程式。其中handler***實際上是一段跳轉程式,執行這段程式將把handle***指向的內容值賦給pc。由於handle***所對應的位址中,存放的是每個相應的isr的起始位址,這樣就完成了向特定isr的調轉。這些isr位址存放在handle***指向的表項中,該錶一般定位在ram高階,基位址為isr_startaddress。

第二種方法,對於irq處理程式可以通過對i_cmst暫存器的分析來判斷中斷源的型別,然後再把pc指向相應當中斷處理程式。

之所以被稱為向量中斷模式,是因為它不需要用程式判斷中斷源,通過硬體實現直接跳轉到相應isr。而非向量中斷必須在中斷服務程式中判斷中斷**,進而跳轉到不同的處理程式。

在非向量中斷模式下,中斷響應流程如下:

1、通常情況下,cpu核心收到來自中斷控制器的irq中斷請求,會在0x00000018處執行一條指令,在從0x00000018處取指令時,中斷控制器會在資料匯流排上載入分支指令。這些分支指令使程式計數器能夠對應到每乙個中斷源的向量位址。所以,一般會在從0x00處到0xa0處放置跳轉指令,跳轉到handler***處。

2、handler***處一般放置彙編下面的一段中斷處理巨集(一般定義為handler),入口是跳轉位址,

主要流程:

棧空間遞減儲存跳轉位址

儲存工作暫存器r0到棧

載入中斷入口位址所在位置到r0

載入中斷入口位址到r0

儲存中斷入口位址到棧

二、向量中斷模式的啟動**分析及程式設計。

1、

中斷向量模式中,具體實現如下:

中斷服務入口位址處,寫入乙個呼叫巨集的指令(類似於子程式),這個巨集是乙個「引導程式」,把中斷服務的首位址裝載於

pc中。具體呼叫乙個框圖來表示

,結合以下的程式理解,接下來還有乙個針對框圖的具體的講解。以

adc中斷為例子:

啟動**

44binit.s

定義了乙個巨集:

$handlerlabel handler。

啟動**

44binit.s

把「ldr

pc , =handler***

」裝入了對應的位址中(在

0x0為首的一系列位址中),例如「

ldrpc , =handleradc

」這條指令被裝入了

0x000000c0

位址中。

啟動**

44binit.s

開闢了一些在

sdram

(>0x0c000000

)上的以

_isr_startaddress

(我的板子程式定義為

0x0c7fff00

)為基址的一些位址中,每個位址用乙個標號表示,用於存放中斷服務程式的位址。例如,「

handleadc

# 4」,可以

handleadc

認為是_isr_startaddress+0x20

的這個位址的標號。詳見**。

在main.c包含的標頭檔案44b.h中,對於

「_isr_startaddress+0x20

」有如下定義,

#define

pisr_adc

(*(unsigned *)(_isr_startaddress+0x20))

,pisr_adc

這是乙個指標,在上乙個步驟中,開闢出來空間就是給這個指標用的。

在main.c或者其他的c檔案裡,包含44b.h這個標頭檔案的前提下,可以編寫乙個中斷處理函式,void

__irq

isr_adc

(),然後再加入語句

pisr_adc=

(unsignde

)isr_adc

,這樣就把

isr_adc

()這個函式的位址寫入了

_isr_startaddress+0x20)

這個位址中。值得注意的是,是位址被寫入了位址。 ⑥

adc中斷發生,

pc跳轉到執行

0x 000000c0處。

cpu

執行存放在位址

0x000000c0

上的「ldr

pc , =handleradc

」這條指令。

pc

再跳至執行巨集指令「

handleradc

handler

handleadc

」,此巨集指令(實質上就是乙個子程式)執行完的結果,就是把

(_isr_startaddress+0x20)

這個位址上存放的子程式

isr_adc

()位址給pc,

pc就執行

isr_adc

()。

執行完畢,返回。

注:(1)步驟

①②③在出現在

44binit.s

,詳見我的啟動**中的注釋。  (

2)_isr_startaddress

的定義在

option.inc

中:_isr_startaddress

equ0xc7fff00  (

3)步驟

④在44b.h中定義:

#define

pisr_adc

(*(unsigned *)(_isr_startaddress+0x20))

(4)在main.c或者其他的c檔案裡,寫入:

void

__irq

isr_adc()和

pisr_adc=

(unsignde

)isr_adc

(5)必須加入在中斷服務程式中

__irq

,以高速編譯器這個是乙個中斷服務程式,這樣編譯器會在編譯時候加上返回使用者模式的**,以實現中斷後程式的自動返還。

U Boot在S3C44B0上的移植方法

bootloader 給嵌入式作業系統提供板上硬體資源資訊,並進一步載入 引導嵌入式作業系統。由於bootloader 的功能直接與cpu和微處理器系統相關,所以不同的cpu體系將需要不同的bootload er。除了依賴於cpu的體系結構外,bootloader 實際上也依賴於具體的嵌入式板級裝置...

S3C44B0的初始化程式的理解(ran

s3c44b0的初始化程式就是初始化各個關鍵的暫存器,建立中斷向量,然後轉移到主函式去執行程式。不過s3c44b0不支援位址對映,所以程式不copy到ram種執行。s3c44b0初始化對我們廣大初學者來說,比較難理解的是中斷的處理和一些少見的操作符號,s3c44b0的中斷子程式位址存放在初始化程式最...

S3C44B0的初始化程式的理解(ran

s3c44b0的初始化程式就是初始化各個關鍵的暫存器,建立中斷向量,然後轉移到主函式去執行程式。不過s3c44b0不支援位址對映,所以程式不copy到ram種執行。s3c44b0初始化對我們廣大初學者來說,比較難理解的是中斷的處理和一些少見的操作符號,s3c44b0的中斷子程式位址存放在初始化程式最...