1.實驗目的:通過本次試驗學習Windows CE6.0的中斷處理的過程以及熟悉在驅動程序中運行中斷的編程。
2.我對Windows CE6.0中斷的理解:
Windows? CE將中斷處理分成兩個步驟:中斷服務程序ISR和中斷服務線程IST。如果中斷被使能,則當中斷產生時,內核將調用該中斷注冊的ISR,ISR執行完后將返回系統中斷號,內核檢查系統中斷號并且設置相關的事件,內核設置相關事件后,相應的IST將開始執行。
3.Windows? CE的處理流程:
(1)如果一個驅動程序要處理一個中斷,那么驅動程序首先要建立一個事件(CreateEvent),然后調用InterruptInitialize將該事件與中斷號綁定,這一步會使能該中斷,OAL中的OEMInerrupteEnable會被調用,如果該函數不返回true的話,InterruptInitialize就會失敗。然后驅動程序中的IST就可以使用WaitForSingleObject函數來等待中斷的發生。
(2)當一個硬件中斷發生之后,操作系統陷入異常,中斷向量指示進入CE的異常處理程序,該異常處理程序然后調用OAL的OEMInterruptHandler函數,該函數檢測硬件之后,將硬件中斷轉換為軟件的中斷號,返回給系統。該中斷號就是上面提到的InterruptInitialize中使用的那個中斷號。系統得到該中斷號之后,就會找到該中斷號對應的事件,并喚醒等待相應事件的線程(IST),然后IST就可以在用戶態進行中斷處理。處理完成之后,IST需要調用InterruptDone來告訴操作系統中斷處理結束,操作系統調用OAL中的OEMInterruptDone函數,最后完成中斷的處理。
4.在驅動中安裝中斷的方法:
首先, 在驅動中通過 CreateEvent()函數創建一個 Event 內核對象, 然后通過 InterruptInitialize()
函數負責把某個邏輯中斷號與這個 Event 內核對象關聯起來。當中斷發生時,操作系統負責引發此
Event 事件,函數的原型如下:
InterruptInitialize(DWORD idInt, // SYSINTR中斷號
HANDLE hEvent , // 與該中斷相關聯的事件句柄
LPVOID pvData, // 傳給OEMInterruptEnable緩沖指針
DWORD cbData, // 緩沖區的大小
)
然后通過 CreatThread()函數來來創建一個線程,在線程函數中用 WaitForSingleObject()來阻塞
當前的線程,等待某個 Event 內核對象標識的事件發生。當中斷發生后,OAL層就會返回邏輯中斷,
與邏輯中斷相關聯的 Event 事件就會被觸發,被阻塞的中斷線程函數就會就緒開始工作。
InterruptDonce()函數用來告訴操作系統, 對該中斷的處理已完成, 操作系統可重新開啟該中斷。
5.步驟:
1.在vs2005里面新建一個DLL的子項目MyKey,在F:/WINCE600/PLATFORM/SMDK6410/SRC/DRIVERS/目錄下
2.添加MyKey.c和MyKey.h文件,編輯源程序,如下:
MyKey.h:
#ifndef _MYKEY_H
#define _MYKEY_H
#ifdef __cplusplus
Extern 'C' {
#endif
typedef struct {
volatile S3C6410_GPIO_REG *pGPIOregs;
BOOL FlagExitThrd;
} KEY_PUBLIC_CONTEXT, *PKEY_PUBLIC_CONTEXT;
#ifdef __cplusplus
}
#endif
#endif
MyKey.c:
#include #include #include #include #include #include #include #include #include 'MyKey.h' #define Led1Mask 0x01 #define Led2Mask 0x02 #define Led3Mask 0x04 #define Led4Mask 0x08 #define LedAllMask 0x0F #define Butt1Mask 0x01 #define Butt2Mask 0x02 #define Butt3Mask 0x04 #define Butt4Mask 0x08 #define Butt5Mask 0x10 #define Butt6Mask 0x20 static KEY_PUBLIC_CONTEXT *pPublicKey = NULL; static volatile UINT32 dwLedFlag = 1; UINT32 g_SysIntr1 = 0; UINT32 g_SysIntr2 = 0; HANDLE g_hEvent1 = NULL; HANDLE g_hThread1 = NULL; HANDLE g_hEvent2 = NULL; HANDLE g_hThread2 = NULL; /****************************************************************************** * * MyKey button event thread * *******************************************************************************/ INT WINAPI Button1Thread(void) { RETAILMSG(1, (TEXT('Button1 Thread Entered ! /r/n'))); while(!pPublicKey->FlagExitThrd) { UINT16 ch; RETAILMSG(1, (TEXT('Button1 KEY_Read: KEY Device Read Successfully./r/n'))); ch = (UINT16)pPublicKey->pGPIOregs->GPNDAT; RETAILMSG(1,(TEXT('Button1 ReadValue: 0x%x /n'), ch)); RETAILMSG(1, (TEXT('Button1 Thread ! /r/n'))); WaitForSingleObject(g_hEvent1, INFINITE); if(pPublicKey->FlagExitThrd) break; RETAILMSG(1, (TEXT('Button1 Thread Start Running ! /r/n'))); if( dwLedFlag == 1 ) { dwLedFlag = 0; pPublicKey->pGPIOregs->GPMDAT |= LedAllMask; RETAILMSG(1, (TEXT('Button1 pressed---Led ALL On:/r/n'))); } else { dwLedFlag = 1; pPublicKey->pGPIOregs->GPMDAT &= ~LedAllMask; RETAILMSG(1, (TEXT('Button1 pressed---Led ALL Off:/r/n'))); } InterruptDone(g_SysIntr1); } RETAILMSG(1, (TEXT('KEY: KEY Button1Thread Exiting/r/n'))); return 0; } // Key_Button1Thread() INT WINAPI Button2Thread(void) { DWORD LedNum = 1; RETAILMSG(1, (TEXT('Button2 Thread Entered ! /r/n'))); while(!pPublicKey->FlagExitThrd) { UINT16 ch; RETAILMSG(1, (TEXT('Button2 KEY_Read: KEY Device Read Successfully./r/n'))); ch = (UINT16)pPublicKey->pGPIOregs->GPNDAT; RETAILMSG(1,(TEXT('Button2 ReadValue: 0x%x /n'), ch)); RETAILMSG(1, (TEXT('Button2 Thread ! /r/n'))); WaitForSingleObject(g_hEvent2, INFINITE); if(pPublicKey->FlagExitThrd) break; RETAILMSG(1, (TEXT('Button2 Thread Start Running ! /r/n'))); if( LedNum == 1 ) { LedNum = 2; pPublicKey->pGPIOregs->GPMDAT |= Led1Mask; RETAILMSG(1, (TEXT('Button2 pressed---Led 1 on:/r/n'))); } else if ( LedNum == 2 ) { LedNum = 3; pPublicKey->pGPIOregs->GPMDAT |= Led2Mask;; RETAILMSG(1, (TEXT('Button2 pressed---Led 2 On:/r/n'))); } else if ( LedNum == 3 ) { LedNum = 4; pPublicKey->pGPIOregs->GPMDAT |= Led3Mask;; RETAILMSG(1, (TEXT('Button2 pressed---Led 3 On:/r/n'))); } else if ( LedNum == 4 ) { LedNum = 0; pPublicKey->pGPIOregs->GPMDAT |= Led4Mask;; RETAILMSG(1, (TEXT('Button2 pressed---Led 4 On:/r/n'))); } else { LedNum = 1; pPublicKey->pGPIOregs->GPMDAT &= ~LedAllMask;; RETAILMSG(1, (TEXT('Button2 pressed---Led ALL off:/r/n'))); } InterruptDone(g_SysIntr2); } RETAILMSG(1, (TEXT('KEY: KEY Button2Thread Exiting/r/n'))); return 0; } // Key_Button2Thread() BOOL KEY_Deinit(DWORD dwContext) { RETAILMSG(1, (TEXT('KEY_DeInit: dwContext = 0x%x/r/n/n'), dwContext)); // inform IST exit status pPublicKey->FlagExitThrd = TRUE; // free virtual memory if(pPublicKey->pGPIOregs ) { DrvLib_UnmapIoSpace((PVOID)pPublicKey->pGPIOregs); pPublicKey->pGPIOregs = NULL; } if(g_hEvent1) { SetEvent(g_hEvent1); InterruptDisable(g_SysIntr1); CloseHandle(g_hEvent1); } if(g_hEvent2) { SetEvent(g_hEvent2); InterruptDisable(g_SysIntr2); CloseHandle(g_hEvent2); } // Wait for threads to finish WaitForSingleObject(g_hThread1, INFINITE); if(g_hThread1) CloseHandle(g_hThread1); WaitForSingleObject(g_hThread2, INFINITE); if(g_hThread2) CloseHandle(g_hThread2); LocalFree(pPublicKey); return (TRUE); } PKEY_PUBLIC_CONTEXT KEY_Init(DWORD dwContext) { LPTSTR ActivePath = (LPTSTR) dwContext; // HKLM/Drivers/Active/xx BOOL bResult = TRUE; DWORD dwHwIntr = 0; RETAILMSG(1, (TEXT('KEY_Init:dwContext = 0x%x/r/n'), dwContext)); RETAILMSG(1,(TEXT('[KEY] Active Path : %s/n'), ActivePath)); if ( !(pPublicKey = (PKEY_PUBLIC_CONTEXT)LocalAlloc( LPTR, sizeof(KEY_PUBLIC_CONTEXT) )) ) { RETAILMSG(1,(TEXT('[KEY] Can't not allocate for KEY Context/n'))); return NULL; } // GPIO Virtual alloc pPublicKey->pGPIOregs = (volatile S3C6410_GPIO_REG *)DrvLib_MapIoSpace(S3C6410_BASE_REG_PA_GPIO, sizeof(S3C6410_GPIO_REG), FALSE); if (pPublicKey->pGPIOregs == NULL)
上一篇:基于gnu-arm-linux的LPC2220的簡單工程模板
下一篇:基于ARM7(LPC2131)平臺的μC/OS-Ⅱ的移植
推薦閱讀最新更新時間:2025-04-15 17:16




設計資源 培訓 開發板 精華推薦
- STEVAL-CBL015V1,單 LNB 電源和控制 IC DiSEqC 1.x 符合 DSQIN,基于 QFN16 (4x4) 中的 LNBH29
- LTC3110IFE 500mA USB 充電/備用應用的典型應用電路,具有可變充電功率 PCHRG,取決于系統負載
- LTC4090 演示板,具有 2A 高壓降壓穩壓器的 USB 電源管理器
- LT1173CS8 +20V 至 5V 降壓轉換器的典型應用電路
- EVAL-ADE7913EBZ,用于評估 ADE7913 隔離式 Sigma-Delta ADC 的評估板
- 縫合怪,nfc+8266名片
- 使用基于 ZICM357SP2-2-R Ember EM35x 收發器模塊的 Mesh Connect EM35x 迷你模塊的典型應用電路
- CN0118
- 基于STM32F411RC的小四軸飛行器
- 644/1284 Narrow:基于 ATmega644/1284 最小的板