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