以文本方式查看主题 - 曙海教育集团论坛 (http://sun4.cn/bbs/index.asp) -- WinCE系统定制与驱动开发 (http://sun4.cn/bbs/list.asp?boardid=36) ---- WinCE中串口驱动及接口函数介绍 (http://sun4.cn/bbs/dispbbs.asp?boardid=36&id=1832) |
-- 作者:wangxinxin -- 发布时间:2010-11-26 14:01:54 -- 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结构,该结构中包含一个函数指针列表,这些函数指针指向串口硬件操作函数,用于操作串口。 view plaincopy to clipboardprint? 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; 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。 |