1. 程式人生 > >深入理解裸機中斷二

深入理解裸機中斷二

  • 前言
    上篇介紹了中斷的詳細流程,接下來結合手冊上的暫存器資訊來分析2440中的中斷結構
    arm9中斷分成兩個大類, 內部中斷與外部中斷
  • 中斷結構
    這裡寫圖片描述
    上圖即arm9中斷結構的分配(EINTPEND等是需要配置的暫存器), 由圖可知:
  • 外部中斷(中斷由外部電路觸發)
    外部中斷共有24個, 即EINT0->EINT23, 其中EINT0->EINT7對應GPF0-GPF7, EINT8-EINT23對應GPG0-GPG15, 有同學可能會奇怪,圖中外部中斷EINT0-EINT3是一組,而且不需要經過EINTPEND, EINTMASK暫存器的配置, 原因很簡單, EINTPEND暫存器位置不夠了,所以分出去EINT0->EINT3分開
  • 外部中斷源(EINT4-EINT23)舉例
    比如我們要用這個EINT4這個中斷,我們應該怎麼把它使能呢?根據上圖中的流程
    ■設定中斷使能
    1.配置GPF4為EINT4(即中斷模式)
    這裡寫圖片描述
    2.配置EINT4的觸發方式,這裡用到的暫存器沒有在圖中所表示, EXTINT0-EXTINT2:三個暫存器設定EINT0-EINT23的觸發方式。
    這裡寫圖片描述
    3.EINTMASK暫存器配置(即是否遮蔽EINT4中斷需要在這裡設定)
    這裡寫圖片描述
    這裡講EINT4中斷使能
    4.INTMSK暫存器配置(是否遮蔽中斷型別需要在這裡配置, 最終覺得CPU是否處理中斷源)
    這裡寫圖片描述
    由上圖我們可以看到, INTMSK第4位決定EINT4_7是否被遮蔽
    比如,我們要讓INT4使能,INT5遮蔽, 我們需要設定:
    (1).INTMSK第4位為0, 使能EINT4->EINT7
    (2).EINTMASK第5位1, 遮蔽EINT5
    5.配置中斷觸發模式(是IRQ還是RIQ), INTMODE暫存器配置,預設值為IRQ
    中斷使能的設定基本完成
    ■中斷髮生判斷-中斷的發生
    外部裝置接入GPF4引發中斷(低電平),首先介紹一下相關暫存器(上圖中剩餘暫存器)
    暫存器說明:
    SRCPND :當一箇中斷髮生後,那麼相應的位會被置1,表示一個或一類中斷髮生了。
    INTPND :中斷髮生後,SRCPND中會有位置1,可能好幾個(因為同時可 能發生幾個中斷),這些中斷會由優先順序仲裁器(由PRIORITY設定優先順序)選出一個最緊迫的,之後把INTPND中相應位置1,所以同一時間只有一位是1。也就是說前面的暫存器置1 是表示發生了,只有INTPND置1,CPU才會處理。
    INTOFFSET :用來表示INTPND中哪一位置1了,好讓你查詢,普通中斷跳轉時查詢用。清除INTPND、SRCPND時自動清除。
    所以假設EINT4與EINT8都使能,但EINT4的優先順序高,那麼發生中斷後, SRCPND中的兩位至1, INTPND中的EINT4對應位至1, INTOFFSET暫存器會自動賦值為EINT4所表示的整數
    結束髮生時的情況(EINT4與EINT8同時發生中斷):
    中斷髮生:
    首先SRCPND 對應位置1(2位),之後檢視EINTMASK是否被遮蔽, 接下來若沒有被遮蔽, SRCPND對應位置1, INTMSK沒有被遮蔽的話, 根據優先順序(假設EINT4的優先順序高), INTPND的EINT4-EINT7所在位被置1, INTOFFSET 暫存器中的值為20,當處理中斷函式清除中斷標誌後(清除EINT4中的中斷標誌,但是EINT8沒有被清除),所以INTPND中EINT8對應位被至1, INTOFFSET 暫存器中的值為21
    ■中斷髮生判斷-中斷判斷
    EINT4與EINT8同時發生中斷
    1.SRCPND
    這裡寫圖片描述

    上圖可知暫存器中的4,5位 置1
    2.INTPND
    這裡寫圖片描述
    由於EINT4的優先順序高,所以INTPND暫存器第4位 置1
    3.INTOFFSET
    這裡寫圖片描述
    由於INTPND的第4位置1,所以INTOFFSET暫存器變為20這個整數(我們寫中斷程式可以利用此數進行跳轉, 跳轉4*20處即處理 INT4-INT7的函式中)
    4.EINTPEND
    上述中斷的判斷中,我們只知道是EINT4->EINT7來了中斷,確認是EINT4的話就要用到EINTPEND這個暫存器了
    這裡寫圖片描述
    5.處理中斷結束後,需要清除中斷, 所以需要往
    EINTPEND, SRCPND, INTPND對應位置寫1, 而且順序必須是EINTPEND->SRCPND->INTPND, 因為假設你先清除SRCPND對應位,但此時EINTPEND位沒有清除,SRCPND對應位又變為1了
  • 內部中斷源(帶子中斷)
    什麼是子中斷,其實了類似於UART一樣,UART發生中斷由3種情況(收,發,ERR),這三種情況都屬於uart的子中斷, 下述例子中以uart0為例子
    ■設定中斷使能
    這裡不考慮如何配置uart0(比如配置GPH2引腳為uart,這種配置在uart文章中會有講解),只考慮與uart中斷相關的配置
    1.配置INTSUBMSK暫存器,使中斷使能
    這裡寫圖片描述
    我們發現對於INTSUBMSK暫存器,初始化預設值為0xFFFF,也就是說剛開始中斷都是被禁止的,所以這裡針對於uart0,我想開啟rx,tx,那麼就的往暫存器0,1位置0
    2.INTMSK暫存器配置(同上面EINT4的例子)
    這裡寫圖片描述
    比如,我們要讓uart0的rx, tx使能,err遮蔽, 我們需要設定:
    (1).INTMSK第28位為0, 使能uart0
    (2).INTSUBMSK第2位1, 遮蔽uart0的子中斷err0
    3.配置中斷觸發模式(是IRQ還是RIQ), INTMODE暫存器配置,預設值為IRQ
    中斷使能的設定基本完成
    ■中斷髮生判斷-中斷的發生
    暫存器說明:
    SUBSRCPND:當一箇中斷髮生後,那麼相應的位會被置1,表示具體哪個中斷髮生了。
    中斷髮生:
    uart0接受資料 uart0_rx發生中斷,此時SUBSRCPND中的uart_rx位置1, 其次,如果沒有uart_rx中斷沒有在INTSUBMSK暫存器被遮蔽的話, SRCPND對應uart0位被置1,INTMSK沒有被遮蔽的話, 對應的INTPND置1, 從而INTOFFSET變為值28
    ■中斷髮生判斷-中斷判斷
    uart0_rx發生了,如果INTMSK沒有遮蔽的話,在INTPND暫存器中uart0肯定被置1
    這裡寫圖片描述
    通過INTOFFSET的值28, 我們可以對其偏移並呼叫uart0的中斷函式,在中斷函式中我們想知道uart0的哪個子中斷髮生中斷的話,就得查詢SUBSRCPND暫存器
    這裡寫圖片描述
  • 內部中斷源,不帶子中斷
    這種情況,比如定時器,具體細節請讀者自行分析,這裡只作為簡單的宣告
    要設定定時器0的中斷
    ■設定中斷使能->設定暫存器INTMSK
    這裡寫圖片描述
    至於中斷的判斷不做陳述(上述2個例子如果明白的話分析定時器中斷很容易)
  • 總結:
    1.中斷的開啟。
    a.如果是不帶子中斷的內部中斷,只需設定INTMSK,讓它不遮蔽中斷就可以了。
    b 如果是帶子中斷的內部中斷,需設定INTSUBMSK和INTMSK,讓它門不遮蔽中斷就可以了。
    c 如果是外部中斷,對於EINT8-23需要設定EINTMASK和INTMSK。對於EINT0-EINT3只需設定INTMSK。
    2.中斷的清除。
    a.如果是不帶子中斷的內部中斷,只需清除SRCPND,INTPND, 注意清除需位置1。
    b 如果是帶子中斷的內部中斷,需清除SRCPND,SUBSRCPND和INTPND,注意先清除SUBSRCPND,再清除SRCPND。因為,如果你先清除SRCPND的話,然後在清除SUBSRCPND的過程中,SRCPND會以為又有中斷髮生,又會置1。也就是說一次中斷會響應兩次。所以必須先掐斷源頭。
    c 如果是外部中斷,對於EINT8-23需要清除EINTPEND,SRCPND和INTPND(同樣注意順序)。對於EINT0-EINT3只需清除SRCPND和INTPND。