WinCE中串列埠驅動及介面函式介紹
作者:ARM-WinCE
在WinCE中,串列埠驅動實際上就是一個流裝置驅動,具體架構如圖:
<shapetype id="_x0000_t75" coordsize="21600,21600" o:spt="75" o:preferrelative="t" path="[email protected]@[email protected]@[email protected]@[email protected]@5xe" filled="f" stroked="f"><stroke joinstyle="miter"></stroke><formulas><f eqn="if lineDrawn pixelLineWidth 0"></f><f eqn="sum @0 1 0"></f><f eqn="sum 0 0 @1"></f><f eqn="prod @2 1 2"></f><f eqn="prod @3 21600 pixelWidth"></f><f eqn="prod @3 21600 pixelHeight"></f><f eqn="sum @0 0 1"></f><f eqn="prod @6 1 2"></f><f eqn="prod @7 21600 pixelWidth"></f><f eqn="sum @8 21600 0"></f><f eqn="prod @7 21600 pixelHeight"></f><f eqn="sum @10 21600 0"></f></formulas><path o:extrusionok="f" gradientshapeok="t" o:connecttype="rect"></path><lock v:ext="edit" aspectratio="t"></lock></shapetype><shape id="_x0000_i1025" style="WIDTH: 184.5pt; HEIGHT: 255.75pt" type="#_x0000_t75"><imagedata src="file:///C:%5CDOCUME~1%5CTANG~1.MIA%5CLOCALS~1%5CTemp%5Cmsohtml1%5C01%5Cclip_image001.jpg" o:title="Drawing4"></imagedata></shape>
串列埠驅動本身分為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函式並傳入不同的操作碼,實現了控制串列埠的功能。這裡列舉一些操作碼如下:
上述的操作碼,很多都會被應用程式呼叫,看看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