1. 程式人生 > >WINce串列埠驅動解析

WINce串列埠驅動解析

在WinCE中,串列埠驅動實際上就是一個流裝置驅動,具體架構如圖:


串列埠驅動本身分為MDD層和PDD層。MDD層對上層的Device Manager提供了標準的流裝置驅動介面(COM_xxx),PDD層實現了HWOBJ結構及結構中若干針對於串列埠硬體操作的函式指標,這些函式指標將指向PDD層中的串列埠操作函式。DDSI是指MDD層與PDD層的介面,在串列埠驅動中實際上就是指HWOBJ,PDD層會傳給MDD層一個HWOBJ結構的指標,這樣MDD層就可以呼叫PDD層的函式來操作串列埠。

微軟針對於串列埠驅動提供了參考原始碼,可以在下面的目錄下找到:”\WINCE600\PUBLIC\COMMON\OAK\DRIVERS\SERIAL”。

串列埠驅動的結構也就是這樣了,下面介紹相關的驅動中的介面。

1. HWOBJ結構
在串列埠驅動中,HWOBJ結構中的函式實現了對串列埠硬體的操作,並在MDD層被呼叫。可以說,該結構描述了串列埠裝置的所有特性,先來介紹一下該結構,具體定義如下:
typedef struct __HWOBJ
{
ULONG BindFlags;
DWORD dwIntID;
PHW_VTBL pFuncTbl;
} HWOBJ, *PHWOBJ;

BindFlags:用於控制MDD層如何來處理IST,具體值如下:

THREAD_IN_PDD:MDD層不處理,中斷在PDD層處理。

THREAD_AT_INIT:在驅動初始化的時候,MDD層啟動IST。

THREAD_AT_OPEN:在驅動被Open的時候,MDD層啟動IST。

dwInitID: 系統的中斷號 pFuncTbl: 指向一個PHW_VTBL結構,該結構中包含一個函式指標列表,這些函式指標指向串列埠硬體操作函式,用於操作串列埠。
typedef struct __HW_VTBL
{
PVOID (*HWInit)(ULONG Identifier, PVOID pMDDContext);
ULONG (*HWDeinit)(PVOID pHead);
BOOL (*HWOpen)(PVOID pHead);
ULONG (*HWClose)(PVOID pHead);
ULONG (*HWGetBytes)(PVOID pHead, PUCHAR pTarget, PULONG pBytes);
PVOID (*HWGetRxStart)(PVOID pHead);
INTERRUPT_TYPE (*HWGetIntrType)(PVOID pHead);
VOID (*HWOtherIntrHandler)(PVOID pHead);
VOID (*HWLineIntrHandler)(PVOID pHead);
ULONG (*HWGetRxBufferSize)(PVOID pHead);
VOID (*HWTxIntrHandler)(PVOID pHead);
ULONG (*HWPutBytes)(PVOID pHead, PUCHAR pSrc, ULONG NumBytes, PULONG pBytesSent);
BOOL (*HWPowerOff)(PVOID pHead);
BOOL (*HWPowerOn)(PVOID pHead);
VOID (*HWClearDTR)(PVOID pHead);
VOID (*HWSetDTR)(PVOID pHead);
VOID (*HWClearRTS)(PVOID pHead);
VOID (*HWSetRTS)(PVOID pHead);
BOOL (*HWEnableIR)(PVOID pHead, ULONG BaudRate);
BOOL (*HWDisableIR)(PVOID pHead);
VOID (*HWClearBreak)(PVOID pHead);
VOID (*HWSetBreak)(PVOID pHead);
BOOL (*HWXmitComChar)(PVOID pHead, UCHAR ComChar);
ULONG (*HWGetStatus)(PVOID pHead, LPCOMSTAT lpStat);
VOID (*HWReset)(PVOID pHead);
VOID (*HWGetModemStatus)(PVOID pHead, PULONG pModemStatus);
VOID (*HWGetCommProperties)(PVOID pHead, LPCOMMPROP pCommProp);
VOID (*HWPurgeComm)(PVOID pHead, DWORD fdwAction);
BOOL (*HWSetDCB)(PVOID pHead, LPDCB pDCB);
BOOL (*HWSetCommTimeouts)(PVOID pHead, LPCOMMTIMEOUTS lpCommTO);
BOOL (*HWIoctl)(PVOID pHead, DWORD dwCode,PBYTE pBufIn, DWORD dwLenIn, PBYTE pBufOut,DWORD dwLenOut,PDWORD pdwActualOut);
} HW_VTBL, *PHW_VTBL;

這些函式將在PDD層實現,用於實際的串列埠硬體操作。





2. MDD層API

MDD層向上提供了流裝置介面,這部分程式碼微軟已經實現,用於管理串列埠。雖然我們不需要實現這部分,但是還是對相應的介面做個簡單介紹。



2.1HANDLE COM_Init(ULONG Identifier):

初始化串列埠裝置,該函式通過讀取登錄檔獲得串列埠裝置號,並獲得相應的HWOBJ的結構指標,通過該指標呼叫PDD層的硬體初始化函式初始化串列埠。

Identifier:如果驅動被裝置管理器載入,那麼這個引數將包含一個登錄檔鍵值在” HKEY_LOCAL_MACHINE\Drivers\Active”路徑下。如果驅動是通過呼叫RegisterDevice函式來載入的,那麼這個值等於dwInfo的值。在COM_Init中,會先開啟該鍵值,用返回的控制代碼來查詢DeviceArrayIndex值,並根據該值獲得PDD層的HWOBJ結構指標。



2.2 BOOL COM_Deinit(void):

解除安裝串列埠裝置,該函式中主要做了一些釋放資源的操作。也可以被DeregisterDevice函式呼叫。



2.3 HANDLE COM_Open(HANDLE pContext, DWORD AccessCode, DWORD ShareMode):

開啟串列埠裝置。應用程式呼叫CreateFile函式開啟串列埠時,該函式會被呼叫。

pContext:COM_Init函式返回的Handle。

AccessCode:設定訪問模式,比如共享讀或者是讀寫模式。

ShareMode:在引數從應用程式中的CreateFile函式中傳來,表示是否支援獨自佔有。



2.4 BOOL COM_Close(DWORD pContext):

關閉串列埠裝置。應用程式呼叫CloseHandle函式關閉串列埠時,該函式會被呼叫。

pContext:該引數為COM_Open函式返回的Handle。



2.5 ULONG COM_Read(HANDLE pContext, PUCHAR pTargetBuffer, ULONG BufferLength, PULONG pBytesRead):

讀串列埠資料。應用程式呼叫ReadFile函式讀串列埠的時候,該函式被呼叫。

pContext:COM_Open函式返回的Handle。

pTargetBuffer:指向一個用於存放讀到資料的Buffer。

BufferLength:pTargetBuffer指向的Buffer的大小。

pBytesRead:實際讀到的資料的大小。



2.6 ULONG COM_Write(HANDLE pContext, PUCHAR pSourceBytes, ULONG NumberOfBytes):

寫串列埠資料。應用程式呼叫WriteFile函式寫串列埠的時候,該函式被呼叫。

pContext:COM_Open函式返回的Handle。

pSourceBytes:指向一個Buffer,該Buffer包含要寫入串列埠的資料。

NumberOfBytes:要寫入串列埠的資料的大小。



2.7 BOOL COM_PowerUp(HANDLE pContext):

該函式主要用於串列埠裝置從suspend模式恢復到正常模式。

pContext:串列埠裝置的Handle。



2.8 BOOL COM_PowerDown(HANDLE pContext):

該函式主要用於串列埠裝置從正常模式進入suspend狀態。

pContext:串列埠裝置的Handle。



2.9 BOOL COM_IOControl(DWORD dwOpenData, DWORD dwCode, PBYTE pBufIn, DOWRD dwLenIn, PBYTE pBufOut, DWORD dwLenOut, PDWORD pdwActualOut):

該函式主要實現了一些串列埠的IO控制,他會被應用層的一些串列埠函式呼叫來獲得或者設定串列埠的狀態。

dwOpenData:COM_Open函式返回的Handle。

dwCode:I/O控制操作碼。

pBufIn:傳入的Buffer。

dwLenIn:傳入的Buffer的大小。

pBufOut:傳出的Buffer。

dwLenOut:傳出的Buffer的大小。

pdwActualOut:實際傳出的資料的大小。

對於串列埠驅動來說,COM_IOControl函式非常有用,應用程式通過呼叫COM_IOControl函式並傳入不同的操作碼,實現了控制串列埠的功能。這裡列舉一些操作碼如下:


操作碼
解釋

IOCTL_SERIAL_CLR_DTR
設定串列埠的DTR管腳為低

IOCTL_SERIAL_CLR_RTS
設定串列埠的RTS管腳為低

IOCTL_SERIAL_DISABLE_IR
禁用串列埠的紅外模式

IOCTL_SERIAL_ENABLE_IR
啟用串列埠的紅外模式

IOCTL_SERIAL_GET_COMMSTATUS
清除串列埠裝置的異常標記並返回當前狀態

IOCTL_SERIAL_GET_DCB
獲得串列埠的DCB結構

IOCTL_SERIAL_GET_MODEMSTATUS
獲得當前Modem的控制暫存器值

IOCTL_SERIAL_GET_PROPERTIES
重新獲得當前串列埠裝置的硬體屬性

IOCTL_SERIAL_GET_TIMEOUTS
獲得串列埠裝置的讀寫超時

IOCTL_SERIAL_GET_WAIT_MASK
獲得等待事件標記掩碼

IOCTL_SERIAL_IMMEDIATE_CHAR
在傳送資料前,先發送一個特定的字元

IOCTL_SERIAL_PURGE
清除串列埠中的輸入輸出Buffer,也可以中止未進行的讀寫操作

IOCTL_SERIAL_SET_BREAK_OFF
串列埠通訊從中斷狀態恢復

IOCTL_SERIAL_SET_BREAK_ON
設定串列埠為中斷狀態,停止傳送接收資料

IOCTL_SERIAL_SET_DCB
設定串列埠的DCB結構

IOCTL_SERIAL_SET_DTR
設定串列埠的DTR管腳為高

IOCTL_SERIAL_SET_QUEUE_SIZE
目前,在微軟的MDD層程式碼中沒有支援

IOCTL_SERIAL_SET_RTS
設定串列埠的RTS管腳為高

IOCTL_SERIAL_SET_TIMEOUTS
設定串列埠的讀寫操作超時

IOCTL_SERIAL_SET_WAIT_MASK
設定等待事件標記掩碼

IOCTL_SERIAL_SET_XOFF
軟體流控模式下,終止資料傳輸

IOCTL_SERIAL_SET_XON
軟體流控模式下,啟動資料傳輸

IOCTL_SERIAL_WAIT_ON_MASK
等待一個與事件掩碼中匹配的事件

操作碼
解釋

IOCTL_SERIAL_CLR_DTR
設定串列埠的DTR管腳為低

IOCTL_SERIAL_CLR_RTS
設定串列埠的RTS管腳為低

IOCTL_SERIAL_DISABLE_IR
禁用串列埠的紅外模式

IOCTL_SERIAL_ENABLE_IR
啟用串列埠的紅外模式

IOCTL_SERIAL_GET_COMMSTATUS
清除串列埠裝置的異常標記並返回當前狀態

IOCTL_SERIAL_GET_DCB
獲得串列埠的DCB結構

IOCTL_SERIAL_GET_MODEMSTATUS
獲得當前Modem的控制暫存器值

IOCTL_SERIAL_GET_PROPERTIES
重新獲得當前串列埠裝置的硬體屬性

IOCTL_SERIAL_GET_TIMEOUTS
獲得串列埠裝置的讀寫超時

IOCTL_SERIAL_GET_WAIT_MASK
獲得等待事件標記掩碼

IOCTL_SERIAL_IMMEDIATE_CHAR
在傳送資料前,先發送一個特定的字元

IOCTL_SERIAL_PURGE
清除串列埠中的輸入輸出Buffer,也可以中止未進行的讀寫操作

IOCTL_SERIAL_SET_BREAK_OFF
串列埠通訊從中斷狀態恢復

IOCTL_SERIAL_SET_BREAK_ON
設定串列埠為中斷狀態,停止傳送接收資料

IOCTL_SERIAL_SET_DCB
設定串列埠的DCB結構

IOCTL_SERIAL_SET_DTR
設定串列埠的DTR管腳為高

IOCTL_SERIAL_SET_QUEUE_SIZE
目前,在微軟的MDD層程式碼中沒有支援

IOCTL_SERIAL_SET_RTS
設定串列埠的RTS管腳為高

IOCTL_SERIAL_SET_TIMEOUTS
設定串列埠的讀寫操作超時

IOCTL_SERIAL_SET_WAIT_MASK
設定等待事件標記掩碼

IOCTL_SERIAL_SET_XOFF
軟體流控模式下,終止資料傳輸

IOCTL_SERIAL_SET_XON
軟體流控模式下,啟動資料傳輸

IOCTL_SERIAL_WAIT_ON_MASK
等待一個與事件掩碼中匹配的事件

 上述的操作碼,很多都會被應用程式呼叫,看看MDD層中的實現,其中一些也是呼叫了PDD層下的函式來完成對串列埠硬體的設定。

3. PDD層API



PDD層的函式主要是實現了對串列埠硬體的操作,函式比較多,不過還是都說一下吧:


3.1 PHWOBJ GetSerialObject(DWORD DeviceArrayIndex):

該函式返回一個指向HWOBJ結構的指標,該結構包含了相關硬體介面函式的函式指標。

DeviceArrayIndex:串列埠索引號



3.2 VOID HWClearBreak(PVOID pContext):

清除串列埠中斷狀態,用於串列埠從中斷狀態恢復。

pConText:指向HWInit函式返回的指標。



3.3 VOID HWClearDTR(PVOID pContext):

設定串列埠的DTR管腳為低

pConText:指向HWInit函式返回的指標。



3.4 VOID HWClearRTS(PVOID pContext):

設定串列埠的RTS管腳為低

pConText:指向HWInit函式返回的指標。



3.5 VOID HWClose(PVOID pContext):

關閉由HWInit函式初始化的裝置

pConText:指向HWInit函式返回的指標。



3.6 VOID HWDeinit(PVOID pContext):

當裝置驅動被解除安裝的時候,該函式被呼叫。

pConText:指向HWInit函式返回的指標。



3.7 VOID HWDisableIR(PVOID pContext):

禁用串列埠的紅外模式

pConText:指向HWInit函式返回的指標。



3.8 VOID HWEnableIR(PVOID pContext):

啟用串列埠的紅外模式

pConText:指向HWInit函式返回的指標。



3.9 VOID HWGetCommProperties(PVOID pContext, LPCOMMPROP pCommProp):

重新獲得當前串列埠裝置的硬體屬性。

pConText:指向HWInit函式返回的指標。

pCommProp:指向一個COMMPROP結構,該結構描述硬體裝置的屬性,比如最大波特率,停止位以及流控模式等。



3.10 INTERRUPT_TYPE HWGetIntrType(PVOID pContext):

獲得當前的中斷型別。返回值可以是INTR_NONE,INTR_LINE,INTR_RX,INTR_TX和INTR_MODEM,這些值在Serhw.h中定義。

pConText:指向HWInit函式返回的指標。



3.11 VOID HWGetModemStatus(PVOID pContext, PULONG pModemStatus):

獲得Modem的狀態。

pConText:指向HWInit函式返回的指標。

pModemStatus:Modem的狀態。



3.12 ULONG HWGetRxBufferSize(PVOID pContext):

獲得串列埠硬體接收Buffer的大小。

pConText:指向HWInit函式返回的指標。



3.13 PVOID HWGetRxStart(PVOID pContext):

返回硬體接收Buffer的起始位置。

pConText:沒有被使用。



3.14 ULONG HWGetStatus(PVOID pContext, LPCOMSTAT lpStat):

獲得硬體狀態資訊。

pConText:指向HWInit函式返回的指標。

lpStat:指向COMSTAT結構,該結構描述硬體狀態。



3.15 PVOID HWInit(ULONG Identifier, PVOID pMDDContext, PHWOBJ pHWObj):

初始化串列埠硬體裝置。

Identifier:該驅動的鍵值,從MDD層傳到PDD層。

pMDDContext:指向MDD層串列埠相關資訊,從MDD層傳給PDD層。

pHWObj:指向HWOBJ結構。



3.16 BOOL HWIoctl(DWORD dwOpenData, DWORD dwCode, PBYTE pBufIn, DWORD dwLenIn, PBYTE pBufOut, DWORD dwLenOut, PDWORD pdwActualOut):

執行I/O控制

dwOpenData:COM_Open函式返回的Handle。

dwCode:I/O控制操作碼。

pBufIn:傳入的Buffer。

dwLenIn:傳入的Buffer的大小。

pBufOut:傳出的Buffer。

dwLenOut:傳出的Buffer的大小。

pdwActualOut:實際傳出的資料的大小。



3.17 VOID HWLineIntrHandler(PVOID pContext):

線路狀態資訊中斷處理函式

pContext:指向HWInit函式返回的指標。



3.18 VOID HWModemIntrHandler(PVOID pContext):

該函式檢測Modem狀態,並對相關中斷進行處理。

pContext:指向HWInit函式返回的指標。



3.19 BOOL HWOpen(PVOID pContext):

開啟串列埠裝置,可以在該函式中開啟串列埠硬體供電。

pContext:指向HWInit函式返回的指標。



3.20 VOID HWOtherHandler(PVOID pContext):

該函式已經被HWModemIntrHandler取代,實現與HWModemIntrHandler一樣。

pContext:指向HWInit函式返回的指標。



3.21 BOOL HWPostInit(PVOID pContext):

該函式在COM_Init中被呼叫,但是在串列埠資料,硬體以及IST初始化後備呼叫。

pContext:指向HWInit函式返回的指標。



3.22 BOOL HWPowerOff(PVOID pContext):

串列埠硬體進入Suspend模式。

pContext:指向HWInit函式返回的指標。



3.23 BOOL HWPowerOn(PVOID pContext):

串列埠硬體從Suspend模式恢復到工作模式。

pContext:指向HWInit函式返回的指標。



3.24 VOID HWPurgeComm(PVOID pContext, DWORD fdwAction):

清除串列埠硬體buffer的資訊。

pContext:指向HWInit函式返回的指標。

fdwAction:

PURGE_TXABORT:終止寫操作立即返回。

PURGE_RXABORT:終止讀操作立即返回。

PURGE_TXCLEAR:清空寫Buffer。

PURGE_RXCLEAR:清空讀Buffer。



3.25 ULONG HWPutBytes(PVOID pContext, PUCHAR pSrc, ULONG NumberOfBytes, PULONG pBytesSent):

通過寫資料到硬體中來直接傳送資料。

pContext:指向HWInit函式返回的指標。

pSrc:指向要傳送的資料Buffer。

NumberOfBytes:要傳送的資料長度。

pBytesSent:實際傳送的資料長度。



3.26 VOID HWReset(PVOID pContext):

復位串列埠硬體。

pContext:指向HWInit函式返回的指標。



3.27 ULONG HWRxIntrHandler(PVOID pContext, PUCHAR pTargetBuffer, PULONG pByteNumber):

接收資料中斷處理函式。

pContext:指向HWInit函式返回的指標。

pTargetBuffer:接收資料Buffer。

pByteNumber:接收資料Buffer的大小。



3.28 VOID HWSetBreak(PVOID pContext):

設定串列埠為中斷狀態,停止傳送接收資料。

pContext:指向HWInit函式返回的指標。



3.29 BOOL HWSetCommTimeouts(PVOID pContext, LPCOMMTIMEOUT lpCommTO):

設定串列埠操作超時時間。

pContext:指向HWInit函式返回的指標。

lpComTO:指向一個超時的結構,其中包括讀寫超時。



3.30 BOOL HWSetDCB(PVOID pContext, LPDCB pDCB):

設定串列埠硬體裝置資訊。

pContext:指向HWInit函式返回的指標。

pDCB:指向DCB結構,該結構描述相關的串列埠硬體設定資訊。



3.31 VOID HWSetDTR(PVOID pContext):

設定串列埠的DTR管腳為高

pContext:指向HWInit函式返回的指標。



3.32 VOID HWSetRTS(PVOID pContext):

設定串列埠的RTS管腳為高

pContext:指向HWInit函式返回的指標。



3.23 VOID HWTxIntrHandler(PVOID pContext, PUCHAR pSourceBuffer, PULONG pByteNumber):

串列埠傳送中斷處理函式。

pContext:指向HWInit函式返回的指標。

pSourceBuffer:傳送資料Buffer。

pByteNumber:最大能夠傳送的資料的大小。函式返回時,指向實際傳送的資料的大小。



3.24 VOID HWXmitComChar(PVOID pContext, UCHAR ComChar):

傳送一個字元

pContext:指向HWInit函式返回的指標。

ComChar:要被髮送的字元。

轉自http://www.cnblogs.com/b2tang/archive/2009/12/30/1636144.html