1. 程式人生 > >WinCE中串列埠驅動及介面函式介紹

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層的介面,在串列埠驅動中實際上就是指HWOBJPDD層會傳給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函式開啟串列埠時,該函式會被呼叫。

pContextCOM_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函式讀串列埠的時候,該函式被呼叫。

pContextCOM_Open函式返回的Handle

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

BufferLengthpTargetBuffer指向的Buffer的大小。

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

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

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

pContextCOM_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控制,他會被應用層的一些串列埠函式呼叫來獲得或者設定串列埠的狀態。

dwOpenDataCOM_Open函式返回的Handle

dwCodeI/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_NONEINTR_LINEINTR_RXINTR_TXINTR_MODEM,這些值在Serhw.h中定義。

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

3.11 VOID HWGetModemStatus(PVOID pContext, PULONG pModemStatus)

獲得Modem的狀態。

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

pModemStatusModem的狀態。

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控制

dwOpenDataCOM_Open函式返回的Handle

dwCodeI/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