• OMAP-L138的新歷程之ARM裸機中斷AINTC(5) - 下載本文

    OMAP-L138的新歷程之ARM裸機中斷AINTC(5)

    上一節我在此說了準備移植linux等操作系統,由于這些系統的移植工作在我購買開發板的時候的廠家已經做了。所以大家想移植這些系統可以先參看廠家的移植實例,但是由于代碼量太龐大了。所以我在這兒先想把片上的各個模塊測試理解一遍,這樣在做系統調用的時候思路就比較清晰了! 先請大家看看omapl138 arm處理機執行中斷的流程:

    1.首先就是知道ARM狀態下的通用寄存器和程序計數器,綠顏色的就是相應模式下的私有寄存器。就是說程序一般運行在系統和用戶模式下,使用的是系統和用戶模式下的通用寄存器,當有異常發生時,比如FIQ,那么系統將切換到FIQ模式下,相應的就會采用FIQ模式下的寄存器,其中綠顏色的就是只在FIQ模式下才會用到的寄存器。

    2.在模式切換的過程中,要保護系統和用戶模式下的通用寄存器狀態,以便在異常處理完成之后程序能正常返回。因為FIQ模式下R8-R14為其私有寄存器,所以切換的過程中,系統和用戶模式下的通用寄存器的R8-R14就不用保護了,所以減少了對寄存器存取的需要,從而可以快速的進行FIQ處理,故稱為FIQ。

    3. 異常處理的動作。當然這都是內核自己干的。以FIQ為例。 當系統進入FIQ模式時,

    第一,將原來執行程序的下一條指令地址保存到LR中,就是將R14保存到R14_fiq里面。 第二,拷貝CPSR到SPSR_fiq。

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

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

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

    第二,將SPSR(SPSR_fiq)拷貝到CPSR。 第三,清除中斷禁止標志(如果開始時置位了)。 4.異常中斷向量

    異常中斷的向量地址

    地址 異常中斷類型 入口時處理器的操作模式 0×00000000 復位 超級用戶 0×00000004 未定義指令 未定義 0×00000008 軟件中斷 超級用戶 0x0000000c 中止(預取指) 中止 0×00000010 中止(數據) 中止 0×00000014 保留 保留 0×00000018 IRQ IRQ 0x0000001c FIQ ; FIQ 異常中斷優先級

    中斷 優先級 復位 最高 數據異常 FIQ IRQ

    預取指異常中斷

    未定義指令和軟件中斷 最低 5.當發生IRQ中斷時

    第一,模式進入到IRQ里面。

    第二,PC跳到0×00000018處運行。因為這是IRQ的中斷入口。

    第三, 通過0×00000018:LDR PC, IRQ_ADDR。跳轉到相應的中斷服務程序。這個里面就有個確定哪個中斷源的問題了。那就有優先級的問題了。每個中斷源會有自己的中斷服務程序。

    第四,得到中斷源有硬件實現和軟件處理兩種方式。omapl138的就是利用硬件方式,為了利用向量中斷控制器的優點,IRQ中斷向量入口處代碼做了修改,變成0×00000018:LDR PC, [PC, #-0xA1C]。這條指令從內存映射地址0xFFFEF604處獲得數據裝載到PC,這樣就能夠直接從硬件中獲得中斷源。這樣就減少了中斷延遲。記得,三星的S3C44B0采用的是用軟件確定中斷源,因此要建立中斷向量表。

    第五,得到中斷源,就知道要跳到哪個中斷服務程序去了。

    一般都是這么定義的。Timer0_Handler HANDLER Timer0 。這種格式是調用一種宏定義,目的是保護現場,跳到中斷服務程序。

    好了,以上是arm的一般執行中斷的方法。我們來看看omapl138的一般實現過程。值得注意的是:我們一般在使用中斷的時候,很多人就想直接使能中斷就行了,但是由于arm有幾種模式,每一種模式下面都會有自己的堆棧和一些特殊的寄存器。所以我們在開啟中斷之前得做一些初始化工作,比如關閉mmu,初始化各個模式的堆棧等

    在這兒我做的實驗程序是以timer0 32位模式為基礎的,實現了一個中斷過程。首先我們得初始化aintc這個中斷管理子模塊,第一步就是先關閉全局中斷,然后將我們的的定時器子中斷,安裝我們定時器的中斷向量函數表(也就是將函數地址放到我們子中斷向量表中),將我們的定時的中斷映射2~31中的某一個中斷通道,最后在使能SYSINT_T64P0_TINT12中斷,這樣就建立起來了一個中斷連接關系。

    設置好定時器之后就可以開始我們的中斷了,當定時器到一定時間之后產生一個cpu中斷,然后cpu就跳轉到0xffff0000那兒去執行我們的向量。但是不知道是我的CCS的原因還是怎么回事。我直接在cmd中將我們的arm中斷向量分配到ram的local ram中,編譯不能通過。所以我只能想個辦法在cmd中先把他放在公共的空間中,當程序運行的時候先搬移這個向量表到arm 的ram中,如果有高手看到我的文章有解決方法,請給我留言,謝謝!

    現在我們可以進入我們的中斷值函數了,由于產生中斷之后IRQ會自動的關閉,所以我們在中斷子函數中重新打開,不然下一個中斷就無法進入,并且aintc模塊也會設置標準位,這個也得我們手動清除。我的處理方法是:將LR寄存器的值減四,因為arm是三級流水的,cpu執行的當前指令的時候LR中的值是下下條指令的地址。然后將pc的值修改成我們的中斷子程序的地址。這樣執行完中斷子程序的時候讓cpu感覺是發生函數調用而已。當然進入我們真正的中斷函數之后還得清除定時器自己的中標志位。接著下一個中斷開始!

    初始化mmu: .align 4

    $C$CON1: .field 00002001h,32 .align 4

    $C$CON2: .field 00002078h,32 ;SBO set and Vector is 0xFFFF0000 .global _c_intOMAP

    ;*************************************************************** ;* FUNCTION DEF: _c_intOMAP

    ;*************************************************************** _c_intOMAP:

    ;*—————————————————— ; Handle MMU now LDR R1, $C$CON1

    MCR p15, #0, r0, c15, c1, #0 ;allow access to all co processors NOP NOP NOP

    LDR r0, $C$CON2 ; disable MMU, caches, write buffer MCR p15, #0, r0, c1, c0, #0 NOP NOP NOP mvn r0, #0

    mcr p15, #0, r0, c8, c7, #0 ; flush tlb’s mcr p15, #0, r0, c7, c7, #0 ; flush Caches mcr p15, #0, r0, c7, c10, #4 ; flush Write Buffer NOP NOP NOP mvn r0, #0

    mcr p15, #0, r0, c3, c0, #0 ; grant manager access to all domains NOP NOP NOP

    ;*—————————————————— ;* Disable ITCM bus

    ;*—————————————————— LDR R0 , ITCM_RegionReg_Val





    日本黄色视频在线观看 - 在线观看 - 影视资讯 - 爱赏网