<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計應(yīng)用 > ARM處理器s3c2410的中斷異常處理

          ARM處理器s3c2410的中斷異常處理

          作者: 時間:2010-01-27 來源:網(wǎng)絡(luò) 收藏

          在進入正題之前,我想先把20T的向量表(Exception Vectors)做一個簡短的介紹。

          20T的向量表有兩種存放方式,一種是低端存放(從0x00000000處開始存放),另一種是高端存放(從0xfff000000處開始存放)。關(guān)于為什么要分兩種方式進行存放這點我將在介紹MMU的文章中進行說明,本文采用低端模式。20T能處理有8個,他們分別是:

          Reset,Undefined

          instruction,Software Interrupt,Abort (prefetch),Abort

          (data),Reserved,IRQ,F(xiàn)IQ

          下面是某個采用低端模式的系統(tǒng)源碼片段:

          /*****************************************************************************

          _start:

          b

          Handle_Reset

          b HandleUndef

          b HandleSWI

          b

          HandlePrefetchAbort

          b HandleDataAbort

          b

          HandleNotUsed

          b HandleIRQ

          b

          HandleFIQ

          …..

          ..

          other

          codes

          ..

          .

          *****************************************************************************/

          上面這部分片段一般出現(xiàn)在一個名叫“head.s”的匯編文件的里,“bHandle_Reset”這條語句就是系統(tǒng)上電之后運行的第一條語句。也就是說這部分代碼的二進制碼必須位于內(nèi)存的最開始部分(這正是低端存放模式),因為上電后CPU會從SDRAM的0x00000000處取第一條指令并執(zhí)行。


          Address

          Instruct

          0x00000000: b

          Handle_Reset

          0x00000004: b

          HandleUndef

          0x00000008: b

          HandleSWI

          0x0000000C: b

          HandlePrefetchAbort

          0x00000010: b

          HandleDataAbort

          0x00000014: b

          HandleNotUsed

          0x00000018: b

          HandleIRQ

          0x0000001C: b

          HandleFIQ

          上面是該程序段在系統(tǒng)上電后加載到內(nèi)存后的分布情況,我們可以看到每條指令占用了4個字節(jié)。上電后,PC指針會跳轉(zhuǎn)到Handle_Reset處開始運行。以后系統(tǒng)每當有異常出現(xiàn),則CPU會根據(jù)異常號,從內(nèi)存的0x00000000處開始查表做相應(yīng)的處理,比如系統(tǒng)觸發(fā)了一個IRQ異常,IRQ為第6號異常,則CPU將把PC指向0x00000018地址(4*6=24= 0x00000018)處運行,該地址的指令是跳轉(zhuǎn)到“異常服務(wù)例程”(HandleIRQ)處運行。以上就是我對異常向量表的一個簡單介紹。現(xiàn)在可以進入我們文章的主題 “異常處理”,s3c2410的分快中斷(FIQ)和普通中斷(IRQ),我們討論的重點是普通中斷(IRQ)。

          s3c2410的中斷異常處理模塊總共由以下寄存器構(gòu)成

          SRCPND(SOURCE

          PENDING REGISTER)

          INTMOD(INTERRUPT MODE REGISTER)

          INTMSK(INTERRUPT MASK

          REGISTER)

          PRIORITY( PRIORITY REGISTER)

          INTPND(INTERRUPT PENDING

          REGISTER)

          INTOFFSET(INTERRUPT OFFSET REGISTER)

          SUBSRCPND (INTERRUPT SUB

          SOURCE PENDING)

          INTSUBMSK (INTERRUPT SUB MASK REGISTER)

          下面我將講解每個寄存器在一個中斷處理流程中所扮演的角色

          SRCPND/ SUBSRCPND這兩個寄存器在功能上是相同的,它們是中斷源引腳寄存器,在一個中斷異常處理流程中,中斷信號傳進中斷異常處理模塊后首先遇到的就是SRCPND/ SUBSRCPND,這兩個寄存器的作用是用于標示出哪個中斷請求被觸發(fā)。SRCPND的有效位為32,SUBSRCPND 的有效位為11,它們中的每一位分別代表一個中斷源。SRCPND為主中斷源引腳寄存器,SUBSRCPND為副中斷源引腳寄存器。

          這里列舉出SRCPND的各個位信息:

          每個位的初始值皆為0。假設(shè)現(xiàn)在系統(tǒng)觸發(fā)了TIMER0中斷,則第10bit將被置1,代表TIMER0中斷被觸發(fā),該中斷請求即將被處理(若該中斷沒有被屏蔽的話)。SUBSRCPND情況與SRCPND相同,這里就不多講了。

          INTMOD寄存器有效位為32位,每一位與SRCPND中各位相對應(yīng),它的作用是指定該位相應(yīng)的中斷源處理模式(IRQ還是FIQ)。若某位為0,則該位相對應(yīng)的中斷按IRQ模式處理,為1則以FIQ模式進行處理,該寄存器初始化值為0x00000000,即所有中斷皆以IRQ模式進行處理。(詳細請參考s3c2410操作手冊)。INTMSK/ INTSUBMSK 寄存器為中斷屏蔽寄存器,INTMSK為主中斷屏蔽寄存器,INTSUBMSK為副中斷屏蔽寄存器。INTMSK有效位為32,INTSUBMSK有效位為11,這兩個寄存器各個位與SRCPND和SUBSRCPND分別對應(yīng)。它們的作用是決定該位相應(yīng)的中斷請求是否被處理。若某位被設(shè)置為1,則該位相對應(yīng)的中斷產(chǎn)生后將被忽略(CPU不處理該中斷請求),設(shè)置為0則對其進行處理。這兩個寄存器初始化后的值是0xFFFFFFFF和0x7FF,既默認情況下所有的中斷都是被屏蔽的。

          到目前為止我們總共講解了SRCPND,INTMOD,INTMSK,SUBSRCPND,INTSUBMSK五個寄存器,在繼續(xù)講解PRIORITY寄存器之前我們先來看一張圖。

          先弄清楚一點,現(xiàn)在要討論的是一個中斷優(yōu)先級的判斷問題。為什么會有中斷有先級的問題呢?我們知道CPU某個時刻只能對一個中斷源進行中斷處理,如果現(xiàn)在有3個中斷同時發(fā)生了,那CPU要按什么順序處理這個3個中斷呢?這正是引入優(yōu)先級判斷的原因所在,通過優(yōu)先級判斷,CPU可以按某種順序逐個處理中斷請求。3sc2410的優(yōu)先級判斷分為兩級。

          如上圖所示,SRCPND寄存器對應(yīng)的32個中斷源總共被分為6個組,每個組由一個ARBITER(0~5)寄存器對其進行管理。中斷必須先由所屬組的ARBITER(0~5)進行第一次優(yōu)先級判斷(第一級判斷)后再發(fā)往ARBITER6進行最終的判斷(第二級判斷)。ARBITER(0~5)這六個組的優(yōu)先級已經(jīng)固定,我們無法改變,也就是說由ARBITER0控制的該組中斷優(yōu)先級最高(該組產(chǎn)生的中斷進行第一級判斷后永遠會以REQ0向ARBITER6傳遞過去)其次是ARBITER1, ARBITER2, ARBITER4, ARBITER4, ARBITER5.我們能夠控制的是某個組里面各個中斷的優(yōu)先級順序。怎么控制?通過PRIORITY寄存器進行控制:]

          以下是PRIORITY寄存器各個位的參數(shù)表

          從表上我們可以知道PRIORITY寄存器內(nèi)部各個位被分為兩種類型,一種是ARB_MODE,另一種為ARB_SEL, ARB_MODE類型有5組對應(yīng)ARBITER(2~6),ARB_SEL類型有7組對應(yīng)ARBITER(0~6)。現(xiàn)在我將以ARBITER2為例,講解中斷組與PRIORITY寄存器中ARB_SEL, ARB_MODE之間的相互關(guān)系。

          首先我們看到ARBITER2寄存器管理的該組中斷里包括了6個中斷,分別是INT_TIMER0,INT_TIMER1,INT_TIMER2,INT_TIMER3,INT_TIMER4,INT_UART2,她們的默認中斷請求號分別為REQ0,REQ1,REQ2,REQ3,REQ4,REQ5。我們先看PRIORITY寄存器中的ARB_SEL2,該參數(shù)由兩個位組成,初始值為00。從該表可以看出00定義了一個順序0-1-2-3-4-5,這個順序就是這組中斷組的優(yōu)先級排列,這個順序指明了以中斷請求號為0(REQ0)的INT_TIMER0具有最高的中斷優(yōu)先級,其次是INT_TIMER1,INT_TIMER2…。假設(shè)現(xiàn)在ARB_SEL2的值被我們設(shè)置為01。則一個新的優(yōu)先級次序?qū)⒈皇褂茫?1對應(yīng)的優(yōu)先級次序為0-2-3-4-1-5,從中可以看出優(yōu)先級最高和最低的中斷請求和之前沒有變化,但本來處于第2優(yōu)先級的INT_TIMER1中斷現(xiàn)在變成了第5優(yōu)先級。從ARB_SEL2被設(shè)置為00,01,10,11各個值所出現(xiàn)的情況我們可以看出,除最高和最低的優(yōu)先級不變以外,其他各個中斷的優(yōu)先級其實是在做一個旋轉(zhuǎn)排列(rotate)。為了達到對各個中斷平等對待這一目標,我們可以讓優(yōu)先級次序在每個中斷請求被處理完之后自動進行一次旋轉(zhuǎn),如何自動讓它旋轉(zhuǎn)呢?我們可以通過ARB_MODE2達到這個目的,該參數(shù)只有1個bit,置1代表開啟對應(yīng)中斷組的優(yōu)先級次序旋轉(zhuǎn),0則為關(guān)閉。事實上當該位置為1之后,每處里完某個組的一個中斷后,該組的ARB_SEL便遞增在1(達到11后恢復(fù)為00)。

          現(xiàn)在我們另ARB_MODE2=1,ARB_SEL2=00則當前ARBITER2的優(yōu)先級順序為0-1-2-3-4-5,假設(shè)現(xiàn)在該組的1號中斷請求INT_TIMER1和2號中斷請求INT_TIMER2被同時觸發(fā),CPU根據(jù)優(yōu)先級判斷后決定先把INT_TIMER1中斷向ARBITER6進行發(fā)送(在ARBITER6做第最終優(yōu)先級判斷),接著再向ARBITER6發(fā)送INT_TIMER2中斷。請注意,在INT_TIMER1被處理完畢后,該組中段的優(yōu)先級次序被自動做了一次旋轉(zhuǎn),旋轉(zhuǎn)后ARBITER2的優(yōu)先級順序變?yōu)?-2-3-4-1-5。假設(shè)之后某個時刻該組的INT_TIMER1和INT_TIMER2又被同時觸發(fā),則此時CPU優(yōu)先處理的會是INT_TIMER2。若我們另ARB_MODE2=0,則改組的中斷優(yōu)先級次序在任何情況下都不做任何改變,除非我們?nèi)藶榈刂匦略O(shè)置了ARB_SEL2的值。

          INTPND寄存器可能是整個中斷處理過程中我們要特別注意的一個寄存器了,他的操作比較特別,怎么特別?請聽我慢慢道來.

          先看一下該寄存器各位詳細功能列表

          正如你所見的,INTPND寄存器與SRCPND長得一模一樣,但他們在中斷異常處理中卻扮演著不同的角色,如果說SRCPND是中斷信號進入中斷處理模塊后所經(jīng)過的第一個場所的話,那么INTPND則是中斷信號在中斷處理模塊里經(jīng)歷的最后一個寄存器。它的每個位對應(yīng)一個中斷請求,若該位被置1,則表示相應(yīng)的中斷請求被觸發(fā),描述到這里你可能會發(fā)現(xiàn)它不僅和SRCPND長得一模一樣,就連功能都一樣,其實不然,他們在功能上有著重大的區(qū)別。SRCPND是中斷源引腳寄存器,某個位被置1表示相應(yīng)的中斷被觸發(fā),但我們知道在同一時刻內(nèi)系統(tǒng)可以觸發(fā)若干個中斷,只要中斷被觸發(fā)了,SRCPND的相應(yīng)位便被置1,也就是說SRCPND在同一時刻可以有若干位同時被置1,然而INTPND則不同,他在某一時刻只能有1個位被置1,INTPND某個位被置1(該位對應(yīng)的中斷在所有已觸發(fā)的中斷里具有最高優(yōu)先級且該中斷沒有被屏蔽),則表示CPU即將或已經(jīng)在對該位相應(yīng)的中斷進行處理。于是我們可以有一個總結(jié):SRCPND說明了有什么中斷被觸發(fā)了,INTPND說明了CPU即將或已經(jīng)在對某一個中斷進行處理。

          特別注意:每當某一個中斷被處理完之后,我們必須手動地把SRCPND/SUBSRCPND , INTPND三個寄存器中與該中斷相應(yīng)的位由1設(shè)置為0,剛才我說INTPND的操作很特別,它的特別之處就在于對當我們要把該寄存器中某個值為1的位設(shè)置為0時,我們不是往該位置0,而是往該位置1。假設(shè)SRCPND=0x00000003,INTPND=0x00000001,該值說明當前0號中斷和1號中斷被觸發(fā),但當前正在被處理的是0號中斷,處理完畢后我們應(yīng)該這樣設(shè)置INTPND和SRCPND:

          SRCPND=0x00000002

          //位0被置為0

          INTPND =0x00000001

          //位0被置為0(方法是往該位寫入1)

          INTOFFSET寄存器的功能則很簡單,它的作用只是用于表明哪個中斷正在被處理。下面是該寄存器各位詳細功能列表

          若當前INT_TIMER0被觸發(fā)了,則該寄存器的值為10,以此類推。

          現(xiàn)在我把整個中斷流程用一個圖加以說明

          以上這個圖清楚地說明了一個中斷異常處理流程。

          下面我用INT_TIMER0,INT_TIMER2和INT_UART0三個中斷完整地介紹一次中斷異常處理。首先我們得做幾個假設(shè):

          假設(shè)1:這三個中斷的屏蔽被取消。

          假設(shè)2:PRIORITY寄存器中ARB_MODE2,ARB_MODE5皆為0,既不進行優(yōu)先級的自動旋轉(zhuǎn)排序,任何時候ARBITER2,ARBITER5控制的中斷組優(yōu)先級次序分別為0-1-2-3-4-5和1-2-3-4。

          假設(shè)3:這三個中斷皆為IRQ類型。

          假設(shè)4:這三個中斷同時被觸發(fā)。

          INT_TIMER0, INT_TIMER2和INT_UART0三個中斷被同時觸發(fā),此時三個中斷信號流向SRCPND寄存器,使該寄存器中的第10位,12位,28位被置為1,中斷信號繼續(xù)向前流經(jīng)INTMASK寄存器,這三個中斷都沒有被屏蔽,于是信號進一步流經(jīng)INTMODE寄存器,這三個中斷皆為IRQ類型,故中斷信號繼續(xù)向前流向PRIORITY寄存器,經(jīng)過優(yōu)先級判斷,INT_TIMER0中斷信號使INTPND 寄存器的第10位置1(INT_TIMER0優(yōu)先級最高),此時INTOFFSET 寄存器的值為10,CPU轉(zhuǎn)向相應(yīng)的中斷服務(wù)例程進行處理。處理完畢后,我們的程序?qū)NTPND和SRCPND的第10置為0,至此INT_TIMER0中斷處理完畢。此時SRCPND 的第12位,28位仍為1(這兩個中斷請求未被處理),故他們會繼續(xù)被CPU已剛才描述的方式進行處理。



          關(guān)鍵詞: ARM9 S3C2410 中斷 異常

          評論


          相關(guān)推薦

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

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();