S3C2410 WinCE6.0的中断处理分析 (转载自博客园牛人we-hjb)
S3C2410 && WinCE6.0的中斷處理分析
?????S3C2410的內核是ARM920T,所以,這里先介紹一下ARM920T的異常。ARM920T中有一個當前程序狀態寄存器(CPSR),其中BIT6和BIT7分別控制FIQ和IRQ的使能與否。大家經常說的開中斷和關中斷,就是指的設置這兩個BIT。
?????? ARM體系的異常中斷如下圖所示:
?????????????????
?????可以看到,ARM920T中一共有7中異常模式,如果同一時刻有多個異常發生,系統則通過優先級順序來決定處理其中的哪一個異常。他們之間的優先級順序從高到低依次是:
1.?????? Reset復位
2.?????? Data Abort數據訪問中止
3.?????? FIQ 快速中斷請求
4.?????? IRQ 外部中斷請求
5.?????? 指令預取中止
6.?????? 未定義的指令和軟件中斷
當系統發生異常時,PC指針將跳轉到相應的異常中斷處理程序處。異常中斷和其處理程序之間的對應關系被稱為異常向量表,就是通常所說的中斷向量表。一般情況下,它存放在低地址(0x0),但在WinCE中,該表存放在高地址(0xffff0000)。
S3C2410的中斷處理過程如下圖所示:
??????????
可以看到,S3C2410中跟中斷密切相關的寄存器主要有以下幾個:
SUBSRCPND(二級源待決寄存器):硬件產生中斷后,該寄存器的相應位被置1;
SUBMASK(二級屏蔽寄存器):若該寄存器的對應位為1,則屏蔽該中斷,不再往前提交;
SRCPND(源待決寄存器):如果是二級中斷源產生了中斷,當SUBSRCPND和SUBMASK滿足條件時,該寄存器的相應位被置1,或者由一級中斷源直接引起該寄存器的對應位置1;
MASK(一級屏蔽寄存器):如果該寄存器的對應位為1,則屏蔽該中斷,不再往前提交;
MODE(中斷模式寄存器):決定中斷是FIQ模式還是IRQ模式,系統中只能有一個FIQ中斷。若當前中斷為FIQ模式,則產生一個FIQ異常,CPU進入FIQ異常處理程序。
PRIORITY(優先級控制寄存器):控制各中斷源的優先級。當有多個中斷源同時發出請求時由優先級最高的中斷源最終產生IRQ。
INTPND(中斷待決寄存器):當SRCPND某一位被置1,且沒有被屏蔽,則該寄存器的相應位也被置1,同時產生一個IRQ異常,CPU進入IRQ異常處理程序。
IRQ異常處理程序中,需要清除SRCPND、INTPND。清除SRCPND和INTPND的方法比較特殊,并不是往對應的位寫0,相反,應該往對應的位寫1。一般是將其值讀取出來,再寫進去,以完成清除SRCPND和INTPND的工作。
除了以上幾個寄存器外,2410還有一個INTOFFSET寄存器,用來表明當前是哪一個中斷請求處理。WinCE的OEMInterruptHandler()函數,就是根據其值來判斷當前是哪一個中斷發出請求。該寄存器在清除SRCPND和INTPND時,被自動復位。所以,代碼中不必對其進行處理。
如果中斷源是EINT4-23,則還需處理EXTINTn、EINTFLT、EINTMASK和EINTPEND等幾個寄存器。另外,由于2410的中斷引腳一般與IO復用,所以在使用特定的外部中斷之前,需要設置相應的GPIO,使其工作在中斷模式下。
WinCE6.0中的中斷處理過程如下圖所示:
???????????????
?????可以看到,整個處理過程分為四層,分別是硬件、內核、OAL和驅動。硬件產生一個IRQ,CPU進入中斷服務程序,調用OAL中的OEMInterruptHandler()函數,根據IRQ返回一個SYSINTR,內核根據該SYSINTR,設置一個事件,驅動中捕獲到該事件,執行相應的處理程序,完成處理后,調用InterruptDone(),通知CPU中斷處理完成。
這里說明一下SYSINTR和IRQ的概念。IRQ一般被認為是物理中斷號,由硬件決定。SYSINTR是邏輯中斷號,一般跟IRQ一一對應。這種對應關系可以在OAL中靜態建立,一般通過函數OALIntrStaticTranslate()實現,靜態映射的IRQ一般是MCU內部的中斷源,如USB Host。為了提高驅動的可移植性,通常采用動態映射的方式,如網卡驅動。不同的硬件平臺,可能使用不同的外部中斷供網卡使用,通過動態映射的方式,只需修改注冊表中的相應鍵值就能完成驅動的移植,而無須修改代碼。驅動中動態映射IRQ的方法是調用函數KernelIoControl(),第一個參數為IOCTL_HAL_REQUEST_SYSINTR,傳入物理中斷號IRQ,正確返回后,會產生一個SYSINTR,最終完成動態轉換的是函數OALIntrRequestSysIntr()。IRQ和SYSINTR的映射關系在文件C:/WINCE600/PLATFORM/COMMON/SRC/COMMON/INTR/BASE/map.c中實現。
驅動中使用中斷的典型過程如下:
1.?????? 初始化GPIO,以及相應中斷寄存器,配置中斷的工作模式。
2.?????? 建立一個SYSINTR與IRQ對應,調用函數KernelIoControl()。
3.?????? 創建一個事件與SYSINTR關聯,調用函數CreateEvent()。
4.?????? 創建一個線程,在線程中等待創建的事件,調用函數WaitForSingleObject()。
5.?????? 完成處理后,通知內核本次中斷處理結束,調用函數InterruptDone()。
OAL層跟中斷相關的有如下幾個函數:
OALIntrInit():初始化中斷寄存器及相應的GPIO,可建立靜態的IRQ到SYSINTR的映射關系。
OALIntrRequestIrqs():獲取設備的IRQ號,如通過IO Address獲取該設備對應的IRQ。
OALIntrEnableIrqs():使能中斷源,主要完成清除中斷屏蔽寄存器和中斷待決寄存器。
OALIntrDisableIrqs():關閉中斷源,通過設置中斷屏蔽寄存器的相應位以屏蔽中斷源。
OALIntrDoneIrqs():清除中斷屏蔽寄存器和中斷待決寄存器使MCU能處理下一次中斷。
OEMInterruptHandler():將IRQ號轉換為SYSINTR,內核的中斷服務程序將根據此值設定特定的事件。
內核中跟中斷相關的工作主要有以下幾個部分:
1.???????? 定義異常處理函數,其實現文件為C:/WINCE600/PRIVATE/WINCEOS/COREOS/NK/KERNEL/ARM/armtrap.s。
2.???????? 創建中斷向量表,其實現文件為C:/WINCE600/PRIVATE/WINCEOS/COREOS/NK/KERNEL/ARM/exvector.s
3.???????? 中斷向量的初始化,其實現在文件C:/WINCE600/PRIVATE/WINCEOS/COREOS/NK/KERNEL/ARM/mdarm.c中,其中的代碼表明WinCE的中斷向量表在高端(0xffff0000)。
?
原文地址:http://www.cnblogs.com/we-hjb/archive/2008/11/08/1329830.html
作者:we-hjb
總結
以上是生活随笔為你收集整理的S3C2410 WinCE6.0的中断处理分析 (转载自博客园牛人we-hjb)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Python.牛客.HJ8.合并表记录
- 下一篇: 军用装备机车车辆设备冲击和振动试验测试机