S3C2440中断解析和基于WINCE操作系统的中断分析(整理于网络,用于按键中断使用)
在調試CAN總線的時候,遇到了操作系統的中斷,為了徹底的弄清楚中斷是怎么回事?我先從底層的中斷開始研究,在這里我們只討論外部中斷,下面就結合S3C2440TEST測試程序來分析一下中斷是怎么執行的:我們研究的是IRQ中斷,分析中斷過程如下,
在2440init.s中有這樣的定義
b?HandlerIRQ??;handler for IRQinterrupt?這個標號HandlerIRQ?就是IRQ中斷發生十跳轉的地址,
然后有這個定義
HandlerIRQ?????HANDLER HandleIRQ??這是一個宏定義
?
我們知道HandlerIRQ?是一個標號,IRQ異常向量就是跳到這里執行的,根據上面的宏定義我又找到一個標號HandleIRQ這個標號是真正的處理函數,然后我們找到這個定義
AREA RamData, DATA, READWRITE
?^??_ISR_STARTADDRESS??;_ISR_STARTADDRESS=0x33FF_FF00
 HandleReset ?#??4?????? //啟動程序中,如下地址是依次加4
 HandleUndef ?#??4
 HandleSWI??#??4
 HandlePabort???#???4
 HandleDabort???#???4
 HandleReserved?#???4
 HandleIRQ??#??4
 HandleFIQ??#??4
在這里我們找到了HandleIRQ標號的入口地址:
接著往下看
HandleEINT0??#??4
 HandleEINT1??#??4
 HandleEINT2??#??4
 HandleEINT3??#??4
 HandleEINT4_7?#??4
 HandleEINT8_23?#??4
HandleEINT0是IRQ異常的向量存放的地方了,是所有IRQ中斷向量表的入口。
下面看2440的中斷按鍵程序,在2440addr.h里找到了這樣的定義(中斷、IO、LCD等地址分配)
#definepISR_EINT0??(*(unsigned*)(_ISR_STARTADDRESS+0x20))
 #define pISR_EINT1??(*(unsigned*)(_ISR_STARTADDRESS+0x24))
 #define pISR_EINT2??(*(unsigned*)(_ISR_STARTADDRESS+0x28))
 #define pISR_EINT3??(*(unsigned*)(_ISR_STARTADDRESS+0x2c))
 #define pISR_EINT4_7?(*(unsigned*)(_ISR_STARTADDRESS+0x30))
 #define pISR_EINT8_23?(*(unsigned*)(_ISR_STARTADDRESS+0x34))
通過地址對照,我們明白了pISR_EINT0??pISR_EINT1??pISR_EINT2??pISR_EINT3??pISR_EINT4_7?pISR_EINT8_23?就是上面的
HandleEINT0??HandleEINT1??HandleEINT2??HandleEINT3??HandleEINT4_7?HandleEINT8_23?
我們知道ARM9的外部中斷有5條中斷信號線,當外部的中斷發生時,就會觸發相應的中斷信號線,其中pISR_EINT4_7?pISR_EINT8_23?兩條復用的中斷信號線,當外部中斷,4-7,8-23都會觸發pISR_EINT4_7?pISR_EINT8_23?這兩條中斷信號線,然后再根據EINTPEND外部中斷懸掛寄存器來判斷是哪個外部中斷源。
因此我們知道pISR_EINT0?=?pISR_EINT2?=?pISR_EINT8_23?=?(U32)Key_ISR;
 
 就是將中斷服務程序Key_ISR的地址傳送到pISR_EINT0,pISR_EINT2,?pISR_EINT8_23?所對應的HandleEINT0???HandleEINT2????HandleEINT8_23?里。從而當中斷發生的時候,就可以執行相應的外部中斷服務程序。
/
下面介紹基于WINCE操作系統的外部中斷,我現在說一下,WINCE中斷的具體過程,
首先我們要把我們設置外部中斷函數在我們BSP包里必須定義對應的邏輯中斷號,在頭文件OALINTR.H中
// These are the 'standard' interrupts
 #defineSYSINTR_KEYBOARD????(SYSINTR_FIRMWARE+0)
 #defineSYSINTR_TOUCH?????(SYSINTR_FIRMWARE+1)
 #defineSYSINTR_ADC??????(SYSINTR_FIRMWARE+2)
 #defineSYSINTR_SERIAL?????(SYSINTR_FIRMWARE+3)
 #defineSYSINTR_AUDIO?????(SYSINTR_FIRMWARE+4)
 #defineSYSINTR_PCMCIA_STATE???(SYSINTR_FIRMWARE+5)
 #defineSYSINTR_PCMCIA_EDGE????(SYSINTR_FIRMWARE+6)
 #defineSYSINTR_PCMCIA_LEVEL???(SYSINTR_FIRMWARE+7)
…………// 具體查看D:\WINCE500\PLATFORM\SMDK2410\INC\oalintr.h
 
MapIrq2SysIntr(DWORD_Irq)這個函數我自己理解當我們的中斷發生的時候,調用相應的邏輯中斷號時,它就返回邏輯中斷號的值。_Irq就是(SYSINTR_FIRMWARE+_Irq)中的。_Irq。只要有了這個邏輯中斷號我們就可以用這個函數進行關聯中斷了,InterruptInitialize(SYSINTR_ETHER,g_hInterrupt, 0,0)他的作用就是,把SYSINTR_ETHER邏輯中斷號和創建的事件g_hInterrupt關聯起來,當有中斷發生的時候,這個函數就會使g_hInterrupt這個事件生效,然后我們用這個函數WaitForSingleObject(g_hInterrupt,INFINITE);
 這個函數是一個等待函數,當事件g_hInterrupt生效時,就會向下面的程序執行,否則一直在這里等待事件生效。這就是靜態中斷的過程,動態我還沒有研究出來,可能和我們的BSP包有關系,在下面的學習中我會把它研究出來。
注:在EVC編寫調用上面的函數時需要包含頭文件:ceddk.h(此處用于實驗室面板按鍵用)。
 
其實添加完對應的邏輯中斷號之后我們還的在這幾個文件中添加相應的語句才能真正的觸發中斷,CFW.C中(參考現有中斷添加需要的中斷如EINT0等)
2 OAL層中斷程序匯總
關于WinCE的中斷處理,OAL中主要是實現了ISR部分,一般IST會在設備驅動中實現。架構如圖:硬件中斷產生以后,會導致內核ISR的運行,然后由OAL中的ISR來處理相應的中斷,最后導致相對應的IST運行完成真正的中斷處理。所以在WinCE中,中斷處理由ISR和IST共同完成。ISR主要完成中斷源的確定,屏蔽該中斷并返回給內核相對應的系統中斷號,ISR應該盡量短小。IST則是完成真正的中斷處理,比如數據的傳輸和解析等。當然不是所有的中斷處理都需要ISR和IST,看需要,比如WinCE的系統Timer中斷就只需要ISR完成。
2.1 在OAL中支持中斷,需要實現以下幾個中斷處理函數a. BOOL OEMInterruptEnable(DWORD sysIntr, VOID* pData, DWORD dataSize)
sysIntr:要被使能的系統中斷號
pData:傳入的數據指針,該數據由InterruptInitialize函數傳入
dataSize:傳入數據的大小
該函數用于使能某一個硬件中斷。在設備驅動調用InterruptInitialize來初始化一個中斷的時候,內核就會調用該函數來使能相應的硬件中斷。
b. VOID OEMInterruptDisable(DWORD sysIntr)
sysIntr:要被屏蔽的系統中斷號
該函數用于屏蔽一個硬件中斷。如果設備驅動調用InterruptDisable函數,則該函數會被調用。
c. VOID OEMInterruptDone(DWORD sysIntr)
sysIntr:要被重新使能的系統中斷號
該函數標志著一個中斷處理過程的完成。當設備驅動調用InterruptDone函數的時候,該函數會被調用,重新使能相應的硬件中斷。
d. ULONG OEMInterruptHandler(ULONG ra)
ra:指令計數,在實際應用中,沒有太大意義
當硬件中斷產生的時候,該函數就會被調用完成ISR部分的中斷處理。一般會在該函數中讀取系統的中斷標記位,確定中斷源并返回相應的系統中斷號。
e. void OEMInterruptHandlerFIQ(void)
針對于ARM處理器,該函數用于處理快速中斷。
上面5個函數完成了中斷的相關處理。這里要提到兩個概念:IRQ和SYSINTR。IRQ是指物理中斷或者叫硬件中斷,而SYSINTR指的是系統中斷,也有的地方稱為虛擬中斷或者邏輯中斷,我個人覺得還是叫系統中斷比較好。每一個IRQ會和一個系統中斷SYSINTR相對應,當硬件中斷產生時,ISR實際上是處理IRQ中斷,然后返回相應的系統中斷SYSINTR給內核,內核會根據相應的SYSINTR觸發相應的IST來完成中斷處理。
IRQ和SYSINTR之間的對應關系稱為映射,分為靜態映射和動態映射。靜態映射是指在系統編譯時IRQ已經和SYSINTR相對應,一般通過OALIntrStaticTranslate函數來實現。而動態映射是指WinCE系統啟動后,動態關聯IRQ與SYSINTR,一般通過KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR…)來實現。
SYSINTR的類型在nkintr.h中定義,OEMInterruptHandler函數在處理完中斷以后,會返回不同類型的SYSINTR給內核,內核會根據返回值進行下一步操作,分為以下幾種類型:
SYSINTR_NOP:表示不需要進行任何處理
SYSINTR_RESCHED:表示要進行一次系統調度
SYSINTR_CHAIN:表示不是該中斷源產生,在中斷鏈中尋找下一個中斷
SYSINTR_RTC_ALARM:表示RTC報警產生
SYSINTR_TIMING:用于ILTiming測試
SYSINTR_PROFILE:用于系統的profile
SYSINTR_FIRMWARE:用于用戶自定義系統中斷號,所有自定義的系統中斷號都應該基于該值進行累加加1,這些自定義的系統中斷號用于和IRQ一一對應。
總結
以上是生活随笔為你收集整理的S3C2440中断解析和基于WINCE操作系统的中断分析(整理于网络,用于按键中断使用)的全部內容,希望文章能夠幫你解決所遇到的問題。
                            
                        - 上一篇: iOS 16来了!锁屏焕然一新
 - 下一篇: java 二进制as_Java中的二进制