arm的中斷體系結構

ARM 276瀏覽

arm體系結構:arm920t



CPU一上電就處于 ARM 狀態。

    如果對于arm的CPU的工作模式和狀態有疑惑: **
ARM處理器的寄存器,ARM與Thumb狀態,7中運行模式
 

    如果對arm剛上電的工作模式和狀態有疑惑:**arm
上電或復位時的狀態,模式
 



ARM異常中斷處理概述

    1、中斷的概念 

            中斷是一個過程,是CPU在執行當前程序的過程中因硬件或軟件的原因插入了另一段程序運行的過程。

            因硬件原因引起的中斷過程的出現是不可預測的,即隨機的,而軟中斷是事先安排的。

         

    2、中斷源的概念  

            我們把可以引起中斷的信號源稱之為中斷源。

             arm920T中有60中斷源



            (1)子中斷源20個:

         

            (2擁有15中斷源的

          



            (4)攝像頭接口:

           



    3、中斷優先級的概念 

            ARM處理器中有7種類型的異常,按優先級從高到低的排列如下:

                復位異常(Reset)、

                數據異常(Data Abort)、

                快速中斷異常(FIQ)、

                外部中斷異常(IRQ)、

                預取異常(Prefetch Abort)、

                軟件中斷(SWI)、

                未定義指令異常(Undefined instruction)。



 

 ARM異常的優先級

 

ARM體系異常種類細說:

1.復位異常

        當處理器的復位引腳有效時,系統產生復位異常中斷,程序跳轉到復位異常中斷處理程序處執行。

        復位異常中斷通常用在下面兩種情況下。 

            *系統上電。 

            *系統復位。 

        當復位異常時,系統執行下列偽操作: 

            R14_svc = UNPREDICTABLE value    //任意值

            SPSR_svc = UNPREDICTABLE value  //任意值

            CPSR[4∶0] = 0b10011  /*進入管理模式*/ 

            CPSR[5] = 0    /*處理器進入ARM狀態*/ 

            CPSR[6] = 1    /*禁止快速中斷*/ 

            CPSR[7] = 1    /*禁止外設中斷*/ 

            If high vectors configured then 

                PC = 0xffff0000 

            Else 

                PC = 0x00000000 



        復位異常中斷處理程序的主要功能: 

        *設置異常中斷向量表。 

        *初始化數據棧和寄存器。 

        *初始化存儲系統,如系統中的MMU等。 

        *初始化關鍵的I/O設備。 

        *使能中斷。 

        *處理器切換到合適的模式。 

        *初始化C變量,跳轉到應用程序執行。





2.未定義指令異常

        當ARM處理器執行協處理器指令時,它必須等待一個外部協處理器應答后,才能真正執行這條指令。

        若協處理器沒有響應,則發生未定義指令異常。





3.軟中斷SWI

        軟中斷異常發生時,處理器進入特權模式,執行一些特權模式下的操作系統功能。



4.預取指令異常 

        預取指令異常是由系統存儲器報告的。當處理器試圖去取一條被標記為預取無效的指令時,

        發生預取異常。



5.數據訪問中止異常 

        數據訪問中止異常是由存儲器發出數據中止信號,它由存儲器訪問指令Load/Store產生。

        當數據訪問指令的目標地址不存在或者該地址不允許當前指令訪問時,處理器產生數據訪問中止異常。





6.外部中斷IRQ 

        當處理器的外部中斷請求引腳有效,而且CPSR寄存器的I控制位被清除時,處理器產生外部中斷IRQ異常。

        系統中各外部設備通常通過該異常中斷請求處理器服務。



7.快速中斷FIQ 

        當處理器的快速中斷請求引腳有效且CPSR寄存器的F控制位被清除時,處理器產生快速中斷請求FIQ異常。







 
 當異常發生時處理器會把PC設置為一個特定的存儲器地址。

    這一地址放在被稱為向量表(vector table)的特定地址范圍內。

    向量表的入口是一些跳轉指令,跳轉到專門處理某個異常或中斷的子程序。 

            







ARM Generic Interrupt Controller : ARM GIC : arm 通用中斷控制器

        如果對 通用中斷控制器有疑惑的,請看:***arm
通用中斷控制器
 



中斷的狀態:

Inactive(不激活)   沒有被激活或掛起的中斷

Pending(掛起)   
  這個中斷可以被硬件識別或是由軟件產生的,正處於等待處理器處理。


Active(激活)   
    這個中斷被處理器從
通用中斷控制器中的中斷源中識別了出來,并且正在處理這個中斷,且沒有處理完成。

Active and pending(激活和掛起)  處理器正在處理某個中斷,且通用中斷控制器有一個掛起的中斷,

                                                      這兩個中斷是屬于同一個中斷源的



中斷流程:





       









進入異常

    在異常發生后,ARM內核會作以下工作: 

    1.在LR中保存下一條指令的地址(即返回地址) 

    2.將CPSR復制到適當的SPSR中; 

    3.將CPSR模式位強制設置為與異常類型相對應的值; 

    4.原來無論是ARM狀態或THUMB狀態,都進入ARM狀態; 

    5.屏蔽快速中斷和外部中斷。 

    6.強制PC從相關的異常向量處取指。



        進入異常過程:

            1.
程序在系統模式下運行
用戶程序,假定當前處理器狀態為Thumb狀態、允許IRQ中斷; 

            2.
用戶程序運行時發生
IRQ中斷,硬件完成以下動作: 

                *置位I位(禁止IRQ中斷)

                *清零T位(進入ARM狀態)

                *設置MOD位,切換處理器模式至IRQ模式 

                *將下一條指令的地址存入IRQ模式的LR寄存器 

                *將CPSR寄存器內容存入IRQ模式的SPSR寄存器 

                *將跳轉地址存入PC,實現跳轉 

            



    中斷響應步驟:

        1、保護斷點, 

        2、尋找中斷入口,根據不同的中斷源所產生的中斷,查找不同的入口地址。 

        3、執行中斷處理程序。 

        4、中斷返回



        具體實現如下:

            1.判斷處理器狀態

                當異常發生時,處理器自動切換到ARM狀態,所以在異常處理函數中要判斷

                在異常發生前處理器是ARM狀態還是Thumb狀態。這可以通過檢測SPSR的T位來判斷。

            

            2.向量表 

                每一個異常發生時總是從異常向量表開始跳轉。最簡單的一種情況是向量表里面的

                每一條指令直接跳向對應的異常處理函數。

                    異常處理向量表如下:

                



    利用跳轉指令B建立異常向量表

        ENTRY      ;匯編程序開始 

        b reset      ;跳入reset處理程序 

        b HandleUndef    ;跳到未定義處理程序          

        b HandSWI    ;跳到軟中斷處理程序       

        b HandPrefetchAbt  ;跳到預取指令處理程序       

        b HandDataAbt    ;跳回數據訪問中止處理程序      

        b HandNoUsed    ;保留 

        b HandleIRQ    ;跳入中斷處理程序  

        b HandleFIQ    ;跳回快速中斷處理標簽 



        注意:跳轉指令B的跳轉范圍為±32MB,但很多情況下不能保證所有的異常處理函數都定位在向量的32MB范圍內,

                需要更大范圍的跳轉,而且由于向量表空間的限制,只能由一條指令完成。

                    具體實現方法有下面兩種。

                    (1)MOV
 PC,#imme_value


                        這種辦法將目標地址直接賦值給PC。但這種方法受格式限制不能處理任意立即數。

                        這個立即數由一個8位數值循環右移偶數位得到。



                    (2)LDR
 PC,[PC+offset] 


                        把目標地址先存儲在某一個合適的地址空間,然后把這個存儲器單元的32位數據傳送給PC來實現跳轉。 

                        這種方法對目標地址值沒有要求。但是存儲目標地址的存儲器單元必須在當前指令的±4KB空間范圍內。 





退出異常

    當異常結束時,異常處理程序必須: 

        1.將LR中的值減去偏移量后存入PC,偏移量根據異常的類型而有所不同; 

        2.將SPSR的值復制回CPSR; 

        3.清零在入口置位的中斷禁止標志。 

        注:恢復CPSR的動作會將T、F和I位自動恢復為異常發生前的值。



            退出異常過程

                在異常處理結束后,異常處理程序完成以下動作: 

                *將SPSR寄存器的值復制回CPSR寄存器; 

                *將LR寄存的值減去一個常量后復制到PC寄存器,跳轉到被中斷的用戶程序。 

            



            從異常處理程序中返回 

            當一個ARM異常處理返回時,一共有3件事情需要處理 

                *通用寄存器的恢復 

                *狀態寄存器的恢復 

                *PC指針的恢復



            具體操作如下:

                1.恢復被中斷程序的處理器狀態 

                    PC和CPSR的恢復可以通過一條指令來實現,下面是3個例子。 

                        MOVS  PC,LR 

                        SUBS  PC,LR,#4 

                        LDMFD  SP!,{PC}^ 

                    這幾條指令是普通的數據處理指令,特殊之處在于它們把程序計數器寄存器PC作為目標寄存器,

                    并且帶了特殊的后綴“S“或“^”。其中“S“或“^”的作用就是使指令在執行時,

                    同時完成從SPSR到CPSR的拷貝,達到恢復狀態寄存器的目的。



                2.異常的返回地址





        注意:異常返回時,另一個非常重要的問題就是返回地址的確定。前面提到過,

                處理器進入異常時會有一個保存LR的動作,但是該保持值并不一定是正確中斷的返回地址

                以一個簡單的指令執行流水狀態圖來對此加以說明,如圖所示, 3級流水線示例:

           



總結IRQ中斷處理過程 







中斷寄存器:

        1,中斷控制器中有5個中斷控制寄存器:

            (1),源掛起寄存器,SOURCE
PENDING (SRCPND) REGISTER  


                    中斷控制寄存器INTCON共有32位,每一位對應著一個中斷源,

                    當中斷源發出中斷請求的時候,就會置位源掛起寄存器的相應位。反之,中斷的掛起寄存器的值為0。 



                    該寄存器中的每一位對應特定的中斷源,

                        當該位的值為:    0,表示這個中斷源中沒有中斷被請求

                                            1,表示該中斷源中中斷被請求 
 


 





                1.1,子源掛起寄存器(SUB
SOURCE PENDING (SUBSRCPND) REGISTER 


             







            (2),中斷模式寄存器,INTERRUPT
MODE (INTMOD) REGISTER


                    中斷模式寄存器INTMOD共有32位,每一位對應著一個中斷源,

                    當中斷源的模式位設置為1時,對應的中斷會由ARM920T內核以FIQ模式來處理。

                    相反,當模式位設置為0時,中斷會以IRQ模式來處理。默認為IRQ模式。



            :如果中斷模式為FIQ模式,INTPND和INTOFFSET寄存器是的,

                    也就是說,這兩個寄存器只在IRQ模式下有效





                    該寄存器中的每一位對應特定的中斷源,

                        當該位的值為:    0,表示這個中斷源中的中斷為IRQ模式

                                            1,表示該中斷源中的中斷為FIQ模式  。



 



            (3),中斷屏蔽寄存器INTERRUPT
MASK (INTMSK) REGISTER


                    這個寄存器有32位,分別對應一個中斷源。

                    當中斷源的屏蔽位設置為1時,CPU不響該中斷源的中斷請求,

                    反之,等于0時CPU能該中斷源的中斷請求。

    

                    該寄存器中的每一位對應特定的中斷源,

                        當該位的值為:    0,表示這個中斷源沒有被屏蔽,其中的中斷可以被響應

                                            1,表示該中斷源被屏蔽,該中斷源中的中斷不可被響應 。

  

  



                   
3.1,子中斷屏蔽寄存器(
INTERRUPT SUB MASK (INTSUBMSK) REGISTER 










            (4)中斷優先權寄存器,PRIORITY
REGISTER (PRIORITY) 


                        CPU某個時刻只能對一個中斷源進行中斷處理,

                        如果現在有3個中斷同時發生了,那CPU要按什么順序處理這個3個中斷呢?

                        這正是引入優先級判斷的原因所在,通過優先級判斷,CPU可以按某種順序逐個處理中斷請求。

                        arm920t 的優先級判斷分為級。

                   

                ①ARBITER6所控制的REQ0,1,2,3,4,5實際上對應ARBITER0,1,2,3,4,5

                ②REQ0在任何情況下具有最高優先級,REQ5具有最低優先級

                        對ARBITER1-4的仲裁組來說(仲裁組組中的不同的中斷),在任何情況下:對應的仲裁組中的中斷REQ0具有最高優先級,

                            中斷REQ5具有最低優先級,而 ARBITER0,ARBITER5仲裁組中并沒有中REQ0,REQ5。

                        
ARBITER6仲裁組來說(同的中斷仲裁組),在任何情況下:ARBITER0具有最高優先級,

                            即仲裁組中的中斷優先級是最高的,比別的仲裁組中的中斷優先級都要高。ARBITER5具有最低優先級,同理。

    

     

   

         
  1,當 ARB_MODEx
    = 0:


                                ARB_SELx   仲裁組中的中斷的優先級不會被自動改變,

                                如:ARB_SEL0     bit[8:7]
= 00 優先級次序:REQ1>REQ2>REQ3>RE
Q4(即:EINT0>EINT1>EINT2>EINT3);


                                                            bit[8:7]
= 01 優先級次序:REQ2>REQ3>RE
Q4<REQ1(即:EINT1>EINT2>EINT3<EINT0);

                        ARB_SEL1 bit[10:9] = 00 優先級次序:REQ0> REQ1>REQ2>REQ3>REQ4>REQ5

                                        (即:EINT4_7>EINT8_23>INT_CAM>Nbatt_FLT>INT_TICK>INT_WDT/AC97);

                                                bit[10:9]
01 優先級次序:REQ1>REQ2>REQ3>REQ4>REQ5>REQ0

                                        即:EINT8_23>INT_CAM>Nbatt_FLT>INT_TICK>INT_WDT/AC97<EINT4_7);

                                其他的ARB_SELx同理

         
  2,當 ARB_MODEx
    = 1:


                              
  ARB_SELx   仲裁組中的中斷被觸發后,組中的中斷的優先級
被自動改變。

                                    1,
REQ0和REQ5因為優先級固定而不參與輪轉

                            2,當 REQ1 中斷被處理之后,該中斷仲裁組中的中斷優先級 ARB_SELx 會變為 01b。


                            3,當 REQ2 中斷被處理之后,該中斷仲裁組中的中斷優先級 ARB_SELx 會變為 10b。


                            4,當 REQ3 中斷被處理之后,該中斷仲裁組中的中斷優先級 ARB_SELx 會變為 11b。


                            5,當 REQ4 中斷被處理之后,該中斷仲裁組中的中斷優先級 ARB_SELx 會變為 00b。




                                如:ARB_SEL0     bit[8:7] = 00 優先級次序:REQ1>REQ2>REQ3>REQ4(即:EINT0>EINT1>EINT2>EINT3);                                    

                                        假設 REG2 (即 EINT1)中斷被觸發后,當cpu處理完REG2(EINT1)的中斷處理函數之后,ARB_SEL0 中的值為 bit[8:7] = 10,

                                        優先級次序:REQ3>REQ4<REQ1>REQ2(即:EINT2>EINT3<EINT0>EINT1);  

            

                                其他的 ARB_SELx 同理。

            (5),中斷掛起寄存器,INTERRUPT
PENDING (INTPND) REGISTER
 

                    中斷掛起寄存器INTPND共有32位,每一位對應著一個中斷源, 當中斷請求被響應的時候,相應的位會被設置為1。

                    在某一時刻只有一個位能為1,因此在中斷服務子程序中可以通過判斷INTPND來判斷哪個中斷正在被響應,

                    在中斷處理函數退出前,需要清除源掛起寄存器中對應的位,以及
中斷掛起寄存器中對應的位。


   



    

     



           
5.1,
IRQ偏移寄存器(INTERRUPT OFFSET (INTOFFSET) REGISTER 


                    中斷偏移寄存器給出INTPND寄存器中哪個是IRQ模式的中斷請求。



                    INTOFFSET的值對應INTPND中的中斷掛起位,取值范圍為:





       
2,外部中斷寄存器


                1,外部中斷控制寄存器(EXTINTn) 

                arm920t有24個外部中斷有幾種中斷觸發方式,EXTINTn配置外部中斷的觸發類型是電平觸發、邊沿觸發及觸發的極性。

                 8 個外部中斷可以由多種信號觸發方式所請求。EXTINT
寄存器為外部中斷配制信號觸發方式為電平觸發或邊沿觸發,


                同時還配制信號觸發極性。  為了確認電平中斷,由于噪聲濾波必須保持 EXTINTn引腳上有效邏輯電平至少40ns





    EXTINT0:





    EXTINT1:







    EXTINT2:









        1.1,外部中斷濾波寄存器(EINTFLTn
(External Interrupt Filter Register  n) 


            為了確認電平中斷,由于噪聲濾波必須保持
EXTINTn引腳上有效邏輯電平至少 
40ns。 





                2,外部中斷屏蔽寄存器(EINTMASK)

                    EXTMASK[23:4]分別對應外部中斷23~4,等于1,對應的中斷被屏蔽;等于0,允許外部中斷。EXTMASK[3:0]保留。





                3,外部中斷掛起寄存器
(
EINTPEND )


                    中斷掛起寄存器INTPND共有32位,前4位保留(因為EINT0—EINT3對應的掛起位在寄存器INTPND中),

                    4~23位對應著一個中斷源,當中斷請求被響應的時候,相應的位會被設置為1

                    在中斷服務子程序中可以通過判斷EINTPND來判斷哪個中斷在提起申請。



 
 




    arm920t中斷相關各寄存器關系: 





測試實例:

點擊(此處)折疊或打開

  1. @******************************************************************************

  2. @ File:head.S
  3. @ 功能:初始化,設置中斷模式、管理模式的棧,設置好中斷處理函數
  4. @****************************************************************************** 

  5. .extern        main
  6. .text
  7. .global        _start
  8. _start:

  9. @****************************************************************************** 
  10. @ 中斷向量,本程序中,除Reset和HandleIRQ外,其它異常都沒有使用
  11. @******************************************************************************
  12.     b    Reset
  13.     
  14. @ 0x04: 未定義指令中止模式的向量地址
  15. HandleUndef:
  16.     b    HandleUndef    


  17. @ 0x08: 管理模式的向量地址,通過SWI指令進入此模式
  18. handleSWI:
  19.     b    handleSWI
  20.     
  21.     
  22. @ 0x0c: 指令預取終止導致的異常的向量地址
  23. HandlePrefetchAbort:
  24.     b    HandlePrefetchAbort
  25.     
  26.     
  27. @ 0x10: 數據訪問終止導致的異常的向量地址
  28. HandleDataAbort:
  29.     b    HandleDataAbort


  30. @ 0x14: 保留
  31. HandleNotUsed:
  32.     b    HandleNotUsed

  33.     
  34. @ 0x18: 中斷模式的向量地址
  35.     b    HandleIRQ
  36.     
  37.     
  38. @ 0x1C: 快中斷模式的向量地址
  39. HandleFIQ:
  40.     b    HandleFIQ

  41. @ CPU剛上電或是復位之后,系統處于 arm 狀態,管理(SVC)模式。
  42. Reset:
  43.     ldr    sp,        =4096        @ 設置棧指針,以下都是C函數,調用前需要設好棧
  44.     bl    disable_watch_dog    @ 關閉 WATCHDOG,否則CPU會不斷重啟
  45.     
  46.     @ 在arm匯編中,唯一能更改cpsr的指令就是msr, cpsr_c是CPSR的低8位, 
  47.     @ 0xd2 = (110 10010)b,可參見CPSR各bit的定義,
  48.     @ 可知CPSR的低5位是工作模式位,如果定義為10010就是進入IRQ(中斷模式), 
  49.     @ 于是這條指令的意義就是進入中斷模式 
  50.     msr    cpsr_c,    #0xd2        @ 進入 中斷(IRQ) 模式
  51.     ldr    sp,        =3072        @ 設置中斷模式的棧指針,中斷模式是有自己的堆棧寄存器的,就是r13。
  52.     
  53.     msr    cpsr_c,    #0xd3        @ 重新進入 管理(SVC) 模式。
  54.     ldr    sp,        =4096        @ 設置 管理(SVC) 模式下的棧指針
  55.                             @ 其實復位之后,CPU就處于管理模式,
  56.                             @ 前面的“ldr sp, =4096”完成同樣的功能,此句可省略

  57.     bl    init_led            @ 初始化 LED 的GPIO管腳 
  58.     bl    init_irq            @ arm中中斷使能前的初始化配置
  59.     
  60.     msr    cpsr_c,    #0x5f        @ 進入 系統(sys)模式,使能 IRQ 中斷
  61.     
  62.     ldr    lr,        =halt_loop    @ 設置返回地址
  63.     ldr    pc,        =main        @ 調用 main 函數
  64. halt_loop:
  65.     b    halt_loop
  66.     
  67.     
  68. HandleIRQ:
  69.     sub    lr,    lr,    #4                        @ 計算返回地址,irq
    模式,lr - 4,指向發送異常是正在執行的指令
  70.     stmdb        {r0-r12,lr}        @ 保存使用到的寄存器,現場保護
  71.                             @ 注意,此時的sp是中斷模式的sp
  72.                             @ 初始值是上面設置的3072
  73.                                     
  74.     ldr    lr, =int_return                @ 設置調用ISR即EINT_Handle函數后的返回地址 
  75.     ldr    pc,    =EINT_Handle            @ 調用中斷服務函數,在interrupt.c中
  76.     
  77. int_return:
  78.     ldmia        {r0-r12,pc}^    @ 中斷返回,現場恢復, ^表示將spsr的值復制到cpsr

    cpsr_c :表示cpsr寄存器中的低8位

        如果對cpsr_c 有疑惑的請看:*arm中的
CPSR_c是什么
 

        如果對cpsr 有疑惑的請看:*
CPSR 和 SPSR
 



    如果對arm上電或復位,cpu的狀態和模式,請看:

        **arm
上電或復位時的狀態,模式
 



    如果對 stmdb,ldmia 指令有疑惑的請看:**arm匯編指令之數據塊傳輸(LDM,STM)詳見 

    

    如果對arm中的r0
- r15 
的作用有疑惑的請看:*arm中R0-R15寄存器的作用 





中斷初始化:

點擊(此處)折疊或打開

  1. void    EINT_Handle(void)

  2. {
  3.     unsigned long oft = INTOFFSET;    //獲取中斷偏移,即那個中斷被觸發

  4.     switch( oft )
  5.     {
  6.         // S2被按下
  7.     case 0: 
  8.         { 
  9.             GPFDAT |= (0x7<<4); // 所有LED熄滅
  10.             GPFDAT &= ~(1<<4); // LED1點亮
  11.             break;
  12.         }

  13.         // S3被按下
  14.     case 2:
  15.         { 
  16.             GPFDAT |= (0x7<<4); // 所有LED熄滅
  17.             GPFDAT &= ~(1<<5); // LED2點亮
  18.             break;
  19.         }

  20.         // K4被按下
  21.     case 5:
  22.         { 
  23.             GPFDAT |= (0x7<<4); // 所有LED熄滅
  24.             GPFDAT &= ~(1<<6); // LED4點亮 
  25.             break;
  26.         }

  27.     default:
  28.         break;
  29.     }

  30.     //清中斷
  31.     if( oft == 5 ) 
  32.         EINTPEND = (1<<11); // EINT8_23合用IRQ5,寫“1”清零此位 
  33.     SRCPND = 1<<oft;
  34.     INTPND = 1<<oft;
  35. }



中斷處理函數:

點擊(此處)折疊或打開

  1. void init_irq(void)

  2. {
  3.     //@設置GPIO為中斷
  4.     // S2,S3對應的2根引腳設為中斷引腳 EINT0,ENT2
  5.     GPFCON &= ~(GPF0_msk | GPF2_msk);
  6.     GPFCON |= GPF0_eint | GPF2_eint;

  7.     // S4對應的引腳設為中斷引腳EINT11
  8.     GPGCON &= ~GPG3_msk;
  9.     GPGCON |= GPG3_eint;

  10.     //@設置外部中斷屬性,子中斷屬性
  11.     // 對于EINT11,需要在EINTMASK寄存器中使能它
  12.     EINTMASK &= ~(1<<11);

  13.     //@設置優先級

  14.     //@使能中斷
  15.     // EINT0、EINT2、EINT8_23使能
  16.     INTMSK &= (~(1<<0)) & (~(1<<2)) & (~(1<<5));
  17. }





    源碼附件int.rar


from: http://blog.chinaunix.net/uid-28458801-id-3780127.html

七星彩走势图2元网官网