在线看毛片网站电影-亚洲国产欧美日韩精品一区二区三区,国产欧美乱夫不卡无乱码,国产精品欧美久久久天天影视,精品一区二区三区视频在线观看,亚洲国产精品人成乱码天天看,日韩久久久一区,91精品国产91免费

<menu id="6qfwx"><li id="6qfwx"></li></menu>
    1. <menu id="6qfwx"><dl id="6qfwx"></dl></menu>

      <label id="6qfwx"><ol id="6qfwx"></ol></label><menu id="6qfwx"></menu><object id="6qfwx"><strike id="6qfwx"><noscript id="6qfwx"></noscript></strike></object>
        1. <center id="6qfwx"><dl id="6qfwx"></dl></center>

            新聞中心

            EEPW首頁 > 嵌入式系統(tǒng) > 設計應用 > S3C2440中斷體系結構

            S3C2440中斷體系結構

            作者: 時間:2016-11-13 來源:網絡 收藏
            一、S3C2440中斷體系結構

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

            本文引用地址:http://www.biyoush.com/article/201611/316269.htm

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

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

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

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

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

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

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

            除用戶模式外,其他6種工作模式都屬于特權模式,大多數(shù)程序運行于用戶模式,進入特權模式是為了處理中斷、異常,或者訪問被保護的系統(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ù)據。

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

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

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

            R15是程序計數(shù)器

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

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


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

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

            ②將CPSR的值復制到異常模式的SPSR

            ③將CPSR的工作模式位設為這個異常對應的工作模式

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

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

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

            ②將SPSR的復制回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ù)據訪問終止模式

            異常原因:指令預取終止

            SUBS PC, R14, #4

            PC+4(1)

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

            SUBS PC, R14, #8

            PC+8(3)

            注:

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

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

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

            二、S3C2440中斷控制器

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

            中斷處理的過程:

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

            ②CPU保存當前程序的運行環(huán)境,調用中斷服務程序(ISR)來處理這些中斷

            ③在ISR中通過讀取中斷控制器、外設的相關寄存器來識別時哪個中斷,并進行相應處理

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

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

            s3c2440的中斷控制器結構如上圖所示:

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

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

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

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

            三、中斷控制寄存器

            1)SUBSRCPND寄存器

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

            2)INTSUBMSK寄存器

            它用來屏蔽SUBSRCPND寄存器所標識的中斷,INTSUBMSK寄存器中某位設置1時,對應的中斷被屏蔽

            3)SRCPND寄存器

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

            4)INTMSK寄存器

            用來屏蔽SRCPND寄存器所標識的中斷。INTMSK寄存器中某位被設為1時,對應的中斷被屏蔽,它只能屏蔽IRQ中斷,不能屏蔽FIQ

            5)INTMOD寄存器

            它某位被設為1時,對應的中斷被設為FIQ,同一時間,INTMOD只能有一位被設為1

            6)PRIORITY寄存器

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

            每個仲裁器基于一個位仲裁器模式控制(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 位,我們可以翻轉 REQ1 到 REQ4 的優(yōu)先級。如果ARB_MODE位置0,ARB_SEL位不會自動改變,使得仲裁器在一個固定優(yōu)先級的模式下操作(注意在此模式下,我們通過手工改變 ARB_SEL 位來配置優(yōu)先級)。另外,如果 ARB_MODE 位是 1,ARB_SEL 位以翻轉的方式改變。例如如果 REQ1 被服務,則ARB_SEL位自動的變?yōu)?1b,把REQ1放到最低的優(yōu)先級。ARB_SEL變化的詳細規(guī)則如下:

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

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

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

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

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

            7)INTPND寄存器

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

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

            8)INTOFFSET寄存器

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

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

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

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

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

            @ File:head.S

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

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

            .extern main

            .text

            .global _start

            _start:

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

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

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

            b Reset

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

            HandleUndef:

            b HandleUndef

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

            HandleSWI:

            b HandleSWI

            @ 0x0c: 指令預取終止導致的異常的向量地址

            HandlePrefetchAbort:

            b HandlePrefetchAbort

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

            HandleDataAbort:

            b HandleDataAbort

            @ 0x14: 保留

            HandleNotUsed:

            b HandleNotUsed

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

            b HandleIRQ

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

            HandleFIQ:

            b HandleFIQ

            Reset:

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

            bl disable_watch_dog @ 關閉WATCHDOG,否則CPU會不斷重啟

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

            ldr sp, =3072 @ 設置中斷模式棧指針

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

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

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

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

            bl init_led @ 初始化LED的GPIO管腳

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

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

            ldr lr, =halt_loop @ 設置返回地址

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

            halt_loop:

            b halt_loop

            HandleIRQ:

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

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

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

            @ 初始值是上面設置的3072

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

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

            int_return:

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

            /*

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

            */

            #include "s3c24xx.h"

            /*

            * LED1-4對應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對應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

            /*

            * 關閉WATCHDOG,否則CPU會不斷重啟

            */

            void disable_watch_dog(void)

            {

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

            }

            void init_led(void)

            {

            GPBCON = GPB5_out | GPB6_out | GPB7_out | GPB8_out ;

            }

            /*

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

            * GPIO引腳用作外部中斷時,默認為低電平觸發(fā)、IRQ方式(不用設置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));

            /*

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

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

            * 仲裁器1、6無需設置

            * 最終:

            * 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對應K1)

            GPBDAT &= ~(1<<5);

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

            GPBDAT &= ~(1<<6);

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

            GPBDAT &= ~(1<<7);

            if (EINTPEND & (1<<14)) //EINT14發(fā)生(EINT8對應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



            評論


            技術專區(qū)

            關閉