日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

ARM中斷處理過程

 wfsy1983 2010-12-29

1.   首先就是知道ARM狀態(tài)37個(gè)寄存器包括通用寄存器、程序計(jì)數(shù)器、狀態(tài)寄存器。綠顏色的就是相應(yīng)模式下的私有寄存器。就是說程序一般運(yùn)行在系統(tǒng)和用戶模式下,使用的是系統(tǒng)和用戶模式下的通用寄存器,當(dāng)有異常發(fā)生時(shí),比如FIQ,那么系統(tǒng)將切換到FIQ模式下,相應(yīng)的就會(huì)采用FIQ模式下的寄存器,其中綠顏色的就是只在FIQ模式下才會(huì)用到的寄存器。

2.   在模式切換的過程中,要保護(hù)系統(tǒng)和用戶模式下的通用寄存器狀態(tài),以便在異常處理完成之后程序能正常返回。因?yàn)镕IQ模式下R8-R14為其私有寄存器,所以切換到FIQ模式的過程中,系統(tǒng)和用戶模式下的通用寄存器的R8-R14就不用保護(hù)了,所以減少了對(duì)寄存器存取的需要,從而可以快速的進(jìn)行FIQ處理,故稱為FIQ。這就是FIQ的私有寄存器比其它模式多的原因。切到FIQ模式需要保護(hù)的寄存器為R0~R7,切到SVC,IRQ,ABORT.和未定義模式需要保護(hù)的寄存器為R0~R12

ARM中斷處理過程 - smalming - SmalmingS Blog

3. 異常處理的動(dòng)作。當(dāng)然這都是CPU內(nèi)核自己干的。以FIQ為例。

當(dāng)CPU切入FIQ模式時(shí),

第一,將原來執(zhí)行程序的下一條指令地址保存到LR中,就是將R14保存到R14_fiq里面。

第二,拷貝CPSR到SPSR_fiq。

第三,改變CPSR模式位的值,改到FIQ模式。

第四,改變PC值,將其指向異常處理向量所指的下一條指令。

離開異常處理的時(shí)候,

第一,將LR(R14_fiq)賦給PC。

第二,將SPSR(SPSR_fiq)拷貝到CPSR。

第三,清除中斷禁止標(biāo)志(如果開始時(shí)置位了)。

4.異常中斷向量

異常中斷的向量地址

地址                 異常中斷類型             入口時(shí)處理器的操作模式

0x00000000        復(fù)位               超級(jí)用戶

0x00000004        未定義指令         未定義

0x00000008        軟件中斷           超級(jí)用戶

0x0000000c        中止(預(yù)取指)     中止

0x00000010        中止(數(shù)據(jù))       中止

0x00000014        保留                              保留

0x00000018        IRQ                                IRQ

0x0000001c        FIQ                                FIQ

異常中斷優(yōu)先級(jí)

中斷 優(yōu)先級(jí)

復(fù)位                                     最高

數(shù)據(jù)異常   

FIQ

IRQ

預(yù)取指異常中斷

未定義指令和軟件中斷        最低

5.當(dāng)發(fā)生IRQ中斷時(shí)

第一,模式進(jìn)入到IRQ里面。

第二,PC跳到0x00000018處運(yùn)行。因?yàn)檫@是IRQ的中斷入口。

第三, 通過0x00000018:LDR PC, IRQ_ADDR。跳轉(zhuǎn)到相應(yīng)的中斷服務(wù)程序。這個(gè)里面就有個(gè)確定哪個(gè)中斷源的問題了。那就有優(yōu)先級(jí)的問題了。每個(gè)中斷源會(huì)有自己的中斷服務(wù)程序。

第四,得到中斷源有硬件實(shí)現(xiàn)和軟件處理兩種方式。比如LPC21XX的就是利用硬件方式,為了利用向量中斷控制器的優(yōu)點(diǎn),IRQ中斷向量入口處代碼做了修改,變成

        0x00000018:LDR PC, [PC, #-0xff0]。

    這條指令從內(nèi)存映射地址0xfffff030處獲得數(shù)據(jù)裝載到PC,這樣就能夠直接從硬件中獲得中斷源。這樣就減少了中斷延遲。記得,三星的S3C44B0好象采用的是用軟件確定中斷源,因此要建立中斷向量表。好久不用了,記不清了。

第五,得到中斷源,就知道要跳到哪個(gè)中斷服務(wù)程序去了。

    一般都是這么定義的。Timer0_Handler HANDLER Timer0 。這種格式是調(diào)用一種宏定義,目的是保護(hù)現(xiàn)場(chǎng),跳到中斷服務(wù)程序。

 

 

 

 

ARM中斷實(shí)現(xiàn)過程的個(gè)人筆記

作者: 逛逛   發(fā)布日期:2006-3-19     

歡迎大家加入我的小圈子共同學(xué)習(xí)討論:www./club/embbed/

決定開始學(xué)習(xí)嵌入式后,最先做的事情就是要熟悉ARM指令及其偽指令偽操作。ARM指令的助記符其實(shí)都是其具體功能的單次縮寫,所以學(xué)習(xí)的過程中最好利用網(wǎng)絡(luò),從一些文獻(xiàn)或書籍中找到ARM指令助記符的全稱,這樣方便記憶。學(xué)完之后,我做了整理了一個(gè)有關(guān)這方面的筆記,有需要的朋友請(qǐng)郵件聯(lián)系:gmman@163.com

    接下來的學(xué)習(xí)過程中,比較難以理解的是ARM的中斷過程和存儲(chǔ)系統(tǒng)。ARM中斷的實(shí)現(xiàn)有些書上看一兩遍也不見得能夠完全理解,當(dāng)然可能只對(duì)于像我一樣跨專業(yè)的朋友來說存在這個(gè)問題。這次只談中斷。由于是初學(xué)者,難免會(huì)出錯(cuò),敬請(qǐng)各位指正。

    當(dāng)一個(gè)程序正常執(zhí)行過程中,CPU可能檢測(cè)到有某個(gè)中斷源發(fā)出中斷請(qǐng)求,這時(shí)ARM硬件實(shí)現(xiàn)了程序強(qiáng)制跳轉(zhuǎn),在這之前保存了相關(guān)信息,以便程序正常返回。如果是發(fā)生了Reset中斷,程序?qū)崿F(xiàn)系統(tǒng)初始化設(shè)置。

    開始比較難以理解的是中斷產(chǎn)生后,程序都進(jìn)行了哪些操作。我就從跟蹤PC作為分析的主線。以發(fā)生FIQ中斷為例。(只以ROM起始地址為0為例,不為0的情況參照存儲(chǔ)地址映射)

    最簡(jiǎn)單的是中斷發(fā)生后,PC=0x08,在此地址處存放一個(gè)跳轉(zhuǎn)指令,跳轉(zhuǎn)到相關(guān)處理程序。當(dāng)然多數(shù)情況中斷處理程序可能比較復(fù)雜,并且要處理多種中斷的情況下,采用一步映射兩步跳轉(zhuǎn)(我自己起的名字,不一定妥當(dāng))。如下圖所示:

   

一步映射指,在RAM地址中建立一個(gè)中斷向量表,圖中該表起始地址為0x400000,在該表中存放的是中斷處理函數(shù)的入口地址。兩步跳轉(zhuǎn)是指,當(dāng)中斷發(fā)生時(shí),由于系統(tǒng)硬件強(qiáng)制程序跳轉(zhuǎn)到了0x08處,在該地址處是一個(gè)跳轉(zhuǎn)指令,跳轉(zhuǎn)到中斷函數(shù)地址解析程序IRQ_Handler,完成一步跳轉(zhuǎn)。解析程序(IRQ_Handler)的作用無非是把中斷向量表內(nèi)中斷處理函數(shù)(SystemIrqHandler)的入口地址賦值給 PC,如圖所示PC=0x003000280,完成第二步跳轉(zhuǎn),開始處理中斷。在中斷處理函數(shù)的最后,恢復(fù)中斷開始時(shí)保存的相關(guān)寄存器的值,完成中斷。

下面以一個(gè)實(shí)例來具體說明中斷建立及實(shí)現(xiàn)的過程。

首先通過偽指令建立一個(gè)中斷向量表,用于存放中斷程序的入口地址(如上圖中的中斷向量表,注意,此時(shí)表中還未賦值):

;/* EXCEPTION HANDLER VECTOR TABLE */

^ DRAM_BASE

HandleReset # 4

HandleUndef # 4

HandleSwi # 4

HandlePrefetch # 4

HandleAbort # 4

HandleReserv # 4

HandleIrq # 4

HandleFiq # 4

然后定義一個(gè)連續(xù)的數(shù)據(jù)段,并把中斷處理函數(shù)的入口地址值賦給各字單元

ExceptionHandlerTable

DCD UserCodeArea

DCD SystemUndefinedHandler

DCD SystemSwiHandler

DCD SystemPrefetchHandler

DCD SystemAbortHandler

DCD SystemReserv

DCD SystemIrqHandler

DCD SystemFiqHandler

下面從程序的開始處分析:

AREA Init, CODE, READONLY

ENTRY

/* ROM起始地址向量表 */

B Reset_Handler

B Undefined_Handler

B SWI_Handler

B Prefetch_Handler

B Abort_Handler

NOP Reserved vector

B IRQ_Handler

B FIQ_Handler

/* B跳轉(zhuǎn)范圍限于+ -32M內(nèi)*/

/* 以下是地址解析程序 */

IRQ_Handler

SUB sp, sp, #4

STMFD sp!, {r0} FD滿遞減堆棧 執(zhí)行寄存器壓棧操作.

LDR r0, =HandleIrq  //對(duì)應(yīng)程序開始處以偽指令定義的向量表

LDR r0, [r0]  //中斷處理函數(shù)的地址賦給R0.

STR r0, [sp, #4]  //中斷處理函數(shù)的地址入棧

LDMFD sp!, {r0, pc} //實(shí)現(xiàn)程序跳轉(zhuǎn),目前沒明白為什么又給r0賦值?

上面提到了還沒有給中斷向量表賦值,下面代碼把中斷處理函數(shù)的地址放到DRAM中斷向量表里

EXCEPTION_VECTOR_TABLE_SETUP

LDR r0, =HandleReset

LDR r1, =ExceptionHandlerTable

MOV r2, #8

ExceptLoop

LDR r3, [r1], #4

STR r3, [r0], #4

SUBS r2, r2, #1 Down Count

BNE ExceptLoop ;;

下面是中斷處理函數(shù)

SystemIrqHandler

IMPORT ISR_IrqHandler

STMFD sp!, {r0-r7, lr}

BL ISR_IrqHandler

LDMFD sp!, {r0-r7, lr}

SUBS pc, lr, #4

它實(shí)際上只調(diào)用了下面的C語言的中斷處理函數(shù),其他什么也沒做。

void ISR_IrqHandler(void)

{

IntOffSet = (U32)INTOFFSET;

(IntOffSet>>2)

(*InterruptHandlers[IntOffSet>>2])(); // Call interrupt service routine

}

以上編程思路是,先在系統(tǒng)初始化時(shí)重新建立一個(gè)中斷向量表,并把相關(guān)的中斷處理函數(shù)的地址放到中斷向量表中。當(dāng)系統(tǒng)監(jiān)測(cè)到有中斷源請(qǐng)求服務(wù)后,硬件實(shí)現(xiàn)pc跳轉(zhuǎn)到地址0x08處,執(zhí)行一個(gè)跳轉(zhuǎn)指令B IRQ_Handler  , 然后執(zhí)行地址解析程序,把中斷向量表中的中斷處理函數(shù)的入口地址賦給pc,開始響應(yīng)中斷。在中斷處理函數(shù)的最后,執(zhí)行

LDMFD sp!, {r0-r7, lr}

SUBS pc, lr, #4

實(shí)現(xiàn)中斷的返回

 

 

 

 

 

硬件平臺(tái)為ARM7內(nèi)核。當(dāng)有軟中斷發(fā)生(即調(diào)用2.2中某一個(gè)函數(shù)時(shí))時(shí),系統(tǒng)首先自動(dòng)調(diào)轉(zhuǎn)到0x0008處執(zhí)行。

1、第一級(jí)中斷向量

    AREA    Init,CODE,READONLY

 

    ENTRY

    b ResetHandler  ;for debug

    b HandlerUndef  ;handlerUndef

    b HandlerSWI    ;SWI interrupt handler

    b HandlerPabort ;handlerPAbort

    b HandlerDabort ;handlerDAbort

    b .             ;handlerReserved

    b HandlerIRQ

    b HandlerFIQ

2、宏展開

繼續(xù)找HandlerSWI。

HandlerSWI  HANDLER HandleSWI

3、內(nèi)存第二級(jí)中斷向量

再找HandleSWI。

^   _ISR_STARTADDRESS

HandleReset     #   4

HandleUndef     #   4

HandleSWI       #   4

HandlePabort    #   4

HandleDabort    #   4

HandleReserved  #   4

HandleIRQ       #   4

HandleFIQ       #   4

現(xiàn)在我們知道軟中斷的服務(wù)程序跑到了內(nèi)存中(執(zhí)行速度較快)去了,我們可以編寫相應(yīng)的代碼來實(shí)現(xiàn)不同功能號(hào)下的不同功能。

 

 

 

 

 

ARM的中斷分析

      對(duì)于學(xué)習(xí)ARM的朋友來說,中斷處理是一塊硬骨頭,尤其是中斷向量表以及中斷的跳轉(zhuǎn)。下面主要對(duì)中斷向量表的建立問題及重映射問題進(jìn)行探討。近來做一些東西用到中斷時(shí),總會(huì)出現(xiàn)一些問題。

      各種Bootloader的初始化相關(guān)代碼摘要,首先來看下面的程序:

         ^ DRAM_BASE                     //DRAM的基地址

HandleReset # 4                              // 空留4個(gè)單元

HandleUndef # 4

HandleSwi    # 4

HandlePrefetch # 4                       //用于填充地址的

HandleAbort # 4

HandleReserv # 4

HandleIrq    # 4

HandleFiq # 4

  注: 這里的^是RMAP,#是FIELD,分配的意思

  就是在SDARM的BANK0開始的地方定義了一個(gè)中斷向量表,相當(dāng)于0地址的FLASH??樟魡卧糜诖娣胖袛喑绦虻娜肟诘刂?。

ExceptionHandlerTable                             //實(shí)際的映射地址

     DCD UserCodeArea

     DCD SystemUndefinedHandler

     DCD SystemSwiHandler

     DCD SystemPrefetchHandler

     DCD SystemAbortHandler

     DCD SystemReserv

     DCD SystemIrqHandler

     DCD SystemFiqHandler

        這個(gè)表中存放的是匯編程序中中斷處理函數(shù)的入口地址,每一項(xiàng)對(duì)應(yīng)一個(gè)中斷函數(shù)。這次的跳轉(zhuǎn)后就進(jìn)入了C服務(wù)程序。 

        從初始化程序的開始處來看:(各種Bootloader的初始化代碼)

  AREA Init, CODE, READONLY     //相當(dāng)于init進(jìn)程

  ENTRY                                               //入口

     B Reset_Handler

     B Undefined_Handler                      //無條件的跳轉(zhuǎn)

     B SWI_Handler

     B Prefetch_Handler

     B Abort_Handler

     NOP  Reserved vector

     B IRQ_Handler

     B FIQ_Handler

    

FIQ_Handler

     SUB sp, sp, #4          

     STMFD sp!, {r0}       FD滿遞減堆棧  執(zhí)行寄存器壓棧操作.

LDR r0, =HandleFiq    匯編里的處理函數(shù)地址,然后跳到C中,在DRAM。

LDR r0, [r0]          中斷向量地址給R0.

     STR r0, [sp, #4]         中斷向量地址給PC

     LDMFD sp!, {r0, pc}

   稍微解釋一下:

  首先執(zhí)行了壓棧,然后給出了中斷入口地址.這個(gè)HandleFiq就是我們前面的在DRAM中建立的中斷向量其中一個(gè)的地址。

在HandleFiq開始的四個(gè)字節(jié)中,放著匯編中斷處理函數(shù)的入口地址。

       那么匯編中斷處理函數(shù)的地址是如何放到DRAM中斷向量表里的呢?

  上面的第一個(gè)表就起作用了??聪旅孢@段程序:

EXCEPTION_VECTOR_TABLE_SETUP

     LDR r0, =HandleReset 

     LDR r1, =ExceptionHandlerTable

     MOV r2, #8 

    

ExceptLoop

     LDR r3, [r1], #4

     STR r3, [r0], #4

     SUBS r2, r2, #1       //填充8個(gè)地址        

     BNE ExceptLoop   //從表里取出來給了HandleReset后面的空間

       這一段把ExceptionHandlerTable里的中斷處理函數(shù)的地址拷給了SDRAM里的中斷向量表。這樣兩者就聯(lián)系起來了。

     在執(zhí)行程序開始的跳轉(zhuǎn)之后就自然跳到了*****Handler.真正的處理函數(shù)如下:

       它實(shí)際上只調(diào)用了C語言的中斷處理函數(shù),其他什么也沒做。

SystemFiqHandler

     IMPORT ISR_FiqHandler

     STMFD sp!, {r0-r7, lr}

     BL ISR_FiqHandler                    //真正的中斷處理服務(wù)函數(shù)

     LDMFD sp!, {r0-r7, lr}

     SUBS pc, lr, #4

        它實(shí)際上只調(diào)用了C語言的中斷處理函數(shù),其他什么也沒做。寫中斷處理服務(wù)程序其實(shí)就只寫C中相應(yīng)的處理部分就好了。

void ISR_FiqHandler(void)

{

       IntOffSet = (U32)INTOFFSET;

       (IntOffSet>>2)

       (*InterruptHandlers[IntOffSet>>2])(); // Call interrupt service routine

}

      其實(shí)就是將中斷向量表重映射,以提高中斷的響應(yīng)速度。代碼在SDRAM的運(yùn)行速度要比在FLASH中運(yùn)行速度快。

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多