新聞中心

EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計應(yīng)用 > S3C2440中斷體系結(jié)構(gòu)

S3C2440中斷體系結(jié)構(gòu)

作者: 時間:2016-11-13 來源:網(wǎng)絡(luò) 收藏
一、S3C2440中斷體系結(jié)構(gòu)

1)ARM體系CPU的7種工作模式

本文引用地址:http://butianyuan.cn/article/201611/316269.htm

用戶模式(usr):ARM處理器正常的程序執(zhí)行狀態(tài)

快速中斷模式(fiq):用于高速數(shù)據(jù)傳輸或通道處理

中斷模式(irq):用于通用的中斷處理

管理模式(svc):操作系統(tǒng)使用的保護模式

數(shù)據(jù)訪問終止模式(abt):當(dāng)數(shù)據(jù)或指令預(yù)取終止時進入該模式,可用于虛擬存儲及存儲保護

系統(tǒng)模式(sys):運行具有特權(quán)的操作系統(tǒng)任務(wù)

未定義指令中止模式(und):當(dāng)未定義的指令執(zhí)行時進入該模式,可用于支持硬件協(xié)處理器的軟件仿真

除用戶模式外,其他6種工作模式都屬于特權(quán)模式,大多數(shù)程序運行于用戶模式,進入特權(quán)模式是為了處理中斷、異常,或者訪問被保護的系統(tǒng)資源。

ARM體系的CPU有以下兩個工作狀態(tài)

ARM狀態(tài):此時處理器執(zhí)行32位的字對齊的ARM指令

Thumb狀態(tài):此時處理器執(zhí)行16位的、半字對齊的Thumb指令

ARM920T有31個通用的32位寄存器和6個程序狀態(tài)寄存器。這37個寄存器分為7組,如下圖所示:

圖中R0-R15可以直接訪問,這些寄存器除了R15外都是通用寄存器,既可以保存地址也可以保存數(shù)據(jù)。

R13稱為棧指針寄存器,通常用于保存棧指針

R14稱為程序連接寄存器(LR),當(dāng)執(zhí)行BL子程序調(diào)用指令時,R14得到R15(程序計數(shù)器PC)的備份。

而當(dāng)發(fā)生中斷或異常時,對應(yīng)的R14_svc,R14_irq,R14_abt或R14_und中保存R15的返回值

R15是程序計數(shù)器

快 速中斷模式有7個備份寄存器R8_fiq-R14_fiq,這使得進入快速中斷模式執(zhí)行很大部分程序時(不改變R0-R7),不需要保存任何寄存器。用戶 模式、管理模式、數(shù)據(jù)訪問終止模式和未定義指令中止模式都含有兩個獨占的寄存器副本R13、R14,這樣令每個模式擁有自己的棧指針寄存器和連接寄存器。

每種工作模式還有寄存器CPSR(當(dāng)前程序狀態(tài)寄存器),它被用于標(biāo)識各種狀態(tài)和當(dāng)前處于哪種工作模式,如下圖所示:


當(dāng)一個異常發(fā)生時,將切換進入相應(yīng)的工作模式,這是ARM920T CPU將自動完成如下工作:

①在異常工作模式的連接寄存器R14中保存前一個工作模式的下一條即將執(zhí)行的指令地址。對于ARM狀態(tài),這個值是當(dāng)前PC值加4或加8

②將CPSR的值復(fù)制到異常模式的SPSR

③將CPSR的工作模式位設(shè)為這個異常對應(yīng)的工作模式

④令PC值等于這個異常模式在異常向量表中的地址,即跳轉(zhuǎn)去執(zhí)行異常向量表中的相應(yīng)指令

從異常工作模式回到之前的工作模式時,需要通過軟件完成如下事情:

①前面進入異常工作模式時,連接寄存器中保存了前一工作模式的一個指令地址,將它減去適當(dāng)?shù)闹岛筚x值給PC寄存器

②將SPSR的復(fù)制回CPSR

異常模式退出異常模式時PC的計算方法進入異常模式時R14中保存的值
管理模式(SWI指令進入)MOVS PC, R14PC+4(1)
未定義指令終止模式MOVS PC, R14PC+4(1)
快速中斷模式SUBS PC, R14, #4PC+4(2)
中斷模式SUBS PC, R14, #4PC+4(2)
數(shù)據(jù)訪問終止模式

異常原因:指令預(yù)取終止

SUBS PC, R14, #4

PC+4(1)

異常原因:數(shù)據(jù)訪問終止

SUBS PC, R14, #8

PC+8(3)

注:

(1)PC為這些指令的地址:SWI、未定義的指令、在預(yù)取指時就失敗的指令

(2)PC為這些指令的地址:進入快速中斷模式、中斷模式前,被打斷而未執(zhí)行的指令

(3)PC為這些指令的地址:導(dǎo)致數(shù)據(jù)訪問終止的加載/存儲指令(LDR、STR、LDM和STM)

二、S3C2440中斷控制器

當(dāng)某事件發(fā)生時,硬件會設(shè)置某個寄存器,CPU在執(zhí)行完一個指令時,通過硬件查看這個寄存器,如果發(fā)現(xiàn)所關(guān)注的事件發(fā)生了,則中斷當(dāng)前程序流程,跳轉(zhuǎn)到一個固定的地址處理這個事件,最后返回繼續(xù)執(zhí)行被中斷的程序。

中斷處理的過程:

①中斷控制器匯集各類外設(shè)發(fā)出的中斷信號,告訴CPU

②CPU保存當(dāng)前程序的運行環(huán)境,調(diào)用中斷服務(wù)程序(ISR)來處理這些中斷

③在ISR中通過讀取中斷控制器、外設(shè)的相關(guān)寄存器來識別時哪個中斷,并進行相應(yīng)處理

④清除中斷:通過讀寫中斷控制器和外設(shè)的相關(guān)寄存器來實現(xiàn)

⑤最后恢復(fù)被中斷程序的運行環(huán)境(恢復(fù)寄存器),繼續(xù)執(zhí)行

s3c2440的中斷控制器結(jié)構(gòu)如上圖所示:

①request sources(without sub-register)中的中斷源被觸發(fā)后,SRCPND寄存器中相應(yīng)位被置1,如果此中斷沒有被INTMSK寄存器屏蔽或者快速中斷的話,它將被進一步處理。

② 對于request sources(with sub-register)中的中斷源被觸發(fā)后,SUBSRCPEND寄存器中的相應(yīng)位被置1,如果此中斷沒有被INTSUBMSK寄存器屏蔽的話,它在 SRCPND寄存器中的相應(yīng)位也被置1,以后的處理過程就和①步驟類似。

③如果被觸發(fā)的中斷中有快速中斷,INTMOD寄存器中為1的位對應(yīng)的中斷是FIQ,則CPU進入快速中斷模式進行處理

④ 對于一般的中斷IRQ,可能同時有幾個中斷被觸發(fā),未被INTMSK寄存器屏蔽的中斷經(jīng)過比較后,選出優(yōu)先級最高的中斷,此中斷在INTPND寄存器中的 相應(yīng)位被置1,然后CPU進入中斷模式進行處理。中斷服務(wù)程序通過讀取INTPND或者INTOFFSET來確定中斷源

三、中斷控制寄存器

1)SUBSRCPND寄存器

它用來表示INT_RXD0、INT_TXD0等中斷是否發(fā)生,每位對應(yīng)一個中斷,當(dāng)這些中斷發(fā)生并且沒有被INTSUBMSK寄存器屏蔽,則它們中的若干位將匯集出現(xiàn)在SRCPND寄存器的某一位上。要清除中斷,往此寄存器中某位寫1

2)INTSUBMSK寄存器

它用來屏蔽SUBSRCPND寄存器所標(biāo)識的中斷,INTSUBMSK寄存器中某位設(shè)置1時,對應(yīng)的中斷被屏蔽

3)SRCPND寄存器

它每一位被用來表示一個或一類中斷是否發(fā)生,要清除某一位,往此位寫1,具體參考數(shù)據(jù)手冊

4)INTMSK寄存器

用來屏蔽SRCPND寄存器所標(biāo)識的中斷。INTMSK寄存器中某位被設(shè)為1時,對應(yīng)的中斷被屏蔽,它只能屏蔽IRQ中斷,不能屏蔽FIQ

5)INTMOD寄存器

它某位被設(shè)為1時,對應(yīng)的中斷被設(shè)為FIQ,同一時間,INTMOD只能有一位被設(shè)為1

6)PRIORITY寄存器

當(dāng)有多個IRQ同時發(fā)生時,中斷控制器選出最高優(yōu)先級的中斷,首先處理它。中斷優(yōu)先級通過7個仲裁器來完成,結(jié)構(gòu)圖如下所示:

每個仲裁器基于一個位仲裁器模式控制(ARB_MODE)和選擇控制信號(ARB_SEL)的兩位來處理 6個中斷請求。

如果ARB_SEL位是 00b,優(yōu)先級是REQ0,REQ1,REQ2,REQ3,REQ4,和REQ5.

如果ARB_SEL位是 01b,優(yōu)先級是REQ0,REQ2,REQ3,REQ4,REQ1,和REQ5.

如果ARB_SEL位是 10b,優(yōu)先級是REQ0,REQ3,REQ4,REQ1,REQ2,和REQ5.

如果ARB_SEL位是 11b,優(yōu)先級是REQ0,REQ4,REQ1,REQ2,REQ3,和REQ5.

注 意仲裁器的 REQ0 總是有最高優(yōu)先級,REQ5 總是有最低優(yōu)先級。此外通過改變ARB_SEL 位,我們可以翻轉(zhuǎn) REQ1 到 REQ4 的優(yōu)先級。如果ARB_MODE位置0,ARB_SEL位不會自動改變,使得仲裁器在一個固定優(yōu)先級的模式下操作(注意在此模式下,我們通過手工改變 ARB_SEL 位來配置優(yōu)先級)。另外,如果 ARB_MODE 位是 1,ARB_SEL 位以翻轉(zhuǎn)的方式改變。例如如果 REQ1 被服務(wù),則ARB_SEL位自動的變?yōu)?1b,把REQ1放到最低的優(yōu)先級。ARB_SEL變化的詳細(xì)規(guī)則如下:

如果REQ0 或REQ5 被服務(wù),ARB_SEL位完全不會變化。

如果REQ1 被服務(wù),ARB_SEL位變?yōu)?01b。

如果REQ2 被服務(wù),ARB_SEL位變?yōu)?10b。

如果REQ3 被服務(wù),ARB_SEL位變?yōu)?11b。

如果REQ4 被服務(wù),ARB_SEL位變?yōu)?00b。

7)INTPND寄存器

經(jīng)過中斷優(yōu)先級選出優(yōu)先級最高的中斷后,這個中斷在INTPND寄存器中的相應(yīng)位被置1,隨后CPU進入中斷模式處理它

同一時間,此寄存器只有一位被置1,在ISR中,可以根據(jù)這個位確定是哪個中斷,清除中斷時,往此位寫入1

8)INTOFFSET寄存器

用來表示INTPND寄存器中哪位被置1了,即INTPND寄存器中位[x]為1時,INTOFFSET寄存器的值為x(x為0-31)

清除SRCPND、INTPND寄存器時,INTOFFSET寄存器被自動清除

四、中斷控制器操作實例:外部中斷

開發(fā)板上,K1-K4四個按鍵所接的CPU引腳可以設(shè)為外部中斷,本程序的功能是,當(dāng)按下某個按鍵時,CPU調(diào)用中斷服務(wù)程序點亮對應(yīng)的LED

@******************************************************************************

@ File:head.S

@ 功能:初始化,設(shè)置中斷模式、系統(tǒng)模式的棧,設(shè)置好中斷處理函數(shù)

@******************************************************************************

.extern main

.text

.global _start

_start:

@******************************************************************************

@ 中斷向量,本程序中,除Reset和HandleIRQ外,其它異常都沒有使用

@******************************************************************************

b Reset

@ 0x04: 未定義指令中止模式的向量地址

HandleUndef:

b HandleUndef

@ 0x08: 管理模式的向量地址,通過SWI指令進入此模式

HandleSWI:

b HandleSWI

@ 0x0c: 指令預(yù)取終止導(dǎo)致的異常的向量地址

HandlePrefetchAbort:

b HandlePrefetchAbort

@ 0x10: 數(shù)據(jù)訪問終止導(dǎo)致的異常的向量地址

HandleDataAbort:

b HandleDataAbort

@ 0x14: 保留

HandleNotUsed:

b HandleNotUsed

@ 0x18: 中斷模式的向量地址

b HandleIRQ

@ 0x1c: 快中斷模式的向量地址

HandleFIQ:

b HandleFIQ

Reset:

ldr sp, =4096 @ 設(shè)置棧指針,以下都是C函數(shù),調(diào)用前需要設(shè)好棧

bl disable_watch_dog @ 關(guān)閉WATCHDOG,否則CPU會不斷重啟

msr cpsr_c, #0xd2 @ 進入中斷模式,cpsr_c表示cpsr[7:0],0xd2=0b1101 0010

ldr sp, =3072 @ 設(shè)置中斷模式棧指針

msr cpsr_c, #0xdf @ 進入系統(tǒng)模式

ldr sp, =4096 @ 設(shè)置系統(tǒng)模式棧指針,

@ 其實復(fù)位之后,CPU就處于系統(tǒng)模式,

@ 前面的“ldr sp, =4096”完成同樣的功能,此句可省略

bl init_led @ 初始化LED的GPIO管腳

bl init_irq @ 調(diào)用中斷初始化函數(shù),在init.c中

msr cpsr_c, #0x5f @ 設(shè)置I-bit=0,開IRQ中斷

ldr lr, =halt_loop @ 設(shè)置返回地址

ldr pc, =main @ 調(diào)用main函數(shù)

halt_loop:

b halt_loop

HandleIRQ:

sub lr, lr, #4 @ 計算返回地址

stmdb sp!, { r0-r12,lr } @ 保存使用到的寄存器

@ 注意,此時的sp是中斷模式的sp

@ 初始值是上面設(shè)置的3072

ldr lr, =int_return @ 設(shè)置調(diào)用ISR即EINT_Handle函數(shù)后的返回地址

ldr pc, =EINT_Handle @ 調(diào)用中斷服務(wù)函數(shù),在interrupt.c中

int_return:

ldmia sp!, { r0-r12,pc }^ @ 中斷返回, ^表示將spsr的值復(fù)制到cpsr

/*

* init.c: 進行一些初始化

*/

#include "s3c24xx.h"

/*

* LED1-4對應(yīng)GPB5、GPB6、GPB7、GPB8

*/

#define GPB5_out (1<<(5*2)) // LED1

#define GPB6_out (1<<(6*2)) // LED2

#define GPB7_out (1<<(7*2)) // LED3

#define GPB8_out (1<<(8*2)) // LED4

/*

* K1-K4對應(yīng)GPG0,GPG3,GPG5,GPG6

*/

#define GPG0_eint (2<<(0*2)) // K1,EINT8

#define GPG3_eint (2<<(3*2)) // K2,EINT11

#define GPF5_eint (2<<(5*2)) // K3,EINT13

#define GPF6_eint (2<<(6*2)) // K4,EINT14

/*

* 關(guān)閉WATCHDOG,否則CPU會不斷重啟

*/

void disable_watch_dog(void)

{

WTCON = 0;// 關(guān)閉WATCHDOG很簡單,往這個寄存器寫0即可

}

void init_led(void)

{

GPBCON = GPB5_out | GPB6_out | GPB7_out | GPB8_out ;

}

/*

* 初始化GPIO引腳為外部中斷

* GPIO引腳用作外部中斷時,默認(rèn)為低電平觸發(fā)、IRQ方式(不用設(shè)置INTMOD)

*/

void init_irq( )

{

GPGCON = GPG0_eint | GPG3_eint |GPG5_eint |GPG6_eint;

// 對于EINT8、11、13、14,需要在EINTMASK寄存器中使能它們

EINTMASK &= (~(1<<8)) & (~(1<<11)) & (~(1<<13)) & (~(1<<14));

/*

* 設(shè)定優(yōu)先級:

* ARB_SEL0 = 00b, ARB_MODE0 = 0: REQ1 > REQ3,即EINT0 > EINT2

* 仲裁器1、6無需設(shè)置

* 最終:

* EINT0 > EINT2 > EINT11,EINT19,即K4 > K3 > K1,K2

* EINT11和EINT19的優(yōu)先級相同

*/

PRIORITY = (PRIORITY & ((~0x01) | (0x3<<7))) | (0x0 << 7) ;

//開啟EINT8_23

INTMSK &= ~(1<<5);

}

interrupt.c

#include "s3c24xx.h"

void EINT_Handle()

{

unsigned long oft = INTOFFSET;

switch( oft )

{

//INTOFFSET為5時,代表INTPND的位[5]為1,則EINT8-23中斷發(fā)生

case 5:

{

GPBDAT |= (0x0f<<5); //LED全滅

if (EINTPEND & (1<<8)) //EINT8發(fā)生(EINT8對應(yīng)K1)

GPBDAT &= ~(1<<5);

if (EINTPEND & (1<<11)) //EINT11發(fā)生(EINT8對應(yīng)K2)

GPBDAT &= ~(1<<6);

if (EINTPEND & (1<<13)) //EINT13發(fā)生(EINT8對應(yīng)K3)

GPBDAT &= ~(1<<7);

if (EINTPEND & (1<<14)) //EINT14發(fā)生(EINT8對應(yīng)K4)

GPBDAT &= ~(1<<8);

break;

}

default:

break;

}

//清除中斷

if(oft == 5)

EINTPEND = (1<<8) | (1<<11) | (1<<13) | (1<<14);

SRCPND = 1<

INTPND = 1<

}

main.c

int main()

{

while(1);

return 0;

}

Makefile
objs := head.o init.o interrupt.o main.o
int.bin: $(objs)
arm-linux-ld -Ttext 0x00000000 -o int_elf $^
arm-linux-objcopy -O binary -S int_elf $@
arm-linux-objdump -D -m arm int_elf > int.dis
%.o:%.c
arm-linux-gcc -Wall -O2 -c -o $@ $<
%.o:%.S
arm-linux-gcc -Wall -O2 -c -o $@ $<
clean:
rm -f int.bin int_elf int.dis *.o



關(guān)鍵詞: S3C2440中斷體系結(jié)

評論


技術(shù)專區(qū)

關(guān)閉