Windows CE下的USB设备驱动程序开发实例(一)

 

下面举个简单的例子来详细说明一下驱动程序的开发过程。

例如我们有个USB Mouse设备,设备信息描述如下:

Device Descriptor:

bcdUSB: 0x0100

bDeviceClass: 0x00

bDeviceSubClass: 0x00

bDeviceProtocol: 0x00

bMaxPacketSize0: 0x08 (8)

idVendor: 0x05E3 (Genesys Logic Inc.)

idProduct: 0x0001

bcdDevice: 0x0101

iManufacturer: 0x00

iProduct: 0x01

iSerialNumber: 0x00

bNumConfigurations: 0x01

 

ConnectionStatus: DeviceConnected

Current Config Value: 0x01

Device Bus Speed: Low

Device Address: 0x02

Open Pipes: 1

 

Endpoint Descriptor:

bEndpointAddress: 0x81

Transfer Type: Interrupt

wMaxPacketSize: 0x0003 (3)

bInterval: 0x0A

可以看出上述设备有一个中断PIPE,包的最大值为3。可能有人问上述的值怎么得到的,win2k DDK中有个usbview的例程,编译一下,将你的USB设备插到PC机的USB口中,运行usbview.exe即可看得相应的设备信息。

 

有了这些基本信息,就可以编写USB设备了,首先声明一下,下面的代码取自微软的USB鼠标样本程序,版权归微软所有,此处仅仅借用来描述一下USB鼠标驱动的开发过程,读者如需要引用此代码,需要得到微软的同意。

 

首先,必须输出USBD要求调用的三个函数,首先到设备插入到USB端口时,USBD会调用USBDeviceAttach()函数,相应的代码如下:

extern "C" BOOL

USBDeviceAttach(

USB_HANDLE hDevice,            // USB设备句柄

LPCUSB_FUNCS lpUsbFuncs,       // USBDI的函数集合

LPCUSB_INTERFACE lpInterface,  // 设备接口描述信息

LPCWSTR szUniqueDriverId,      // 设备ID描述字符串。

LPBOOL fAcceptControl,         // 返回TRUE,标识我们可以控制此设备, 反之表示不能控制

DWORD dwUnused)

{

*fAcceptControl = FALSE;

// 我们的鼠标设备有特定的描述信息,要检测是否是我们的设备。

if (lpInterface == NULL)

return FALSE;

// 打印相关的USB设备接口描述信息。

DEBUGMSG(ZONE_INIT,(TEXT("USBMouse: DeviceAttach, IF %u, #EP:%u, Class:%u, Sub:%u,Prot:% u/r/n"), lpInterface->Descriptor.bInterfaceNumber,lpInterface->Descriptor.bNumEndpoints, lpInterface->Descriptor.bInterfaceClass,lpInterface->Descriptor.bInterfaceSubClass,lpInterface->Descriptor.bInterfaceProtocol));

// 初试数据USB鼠标类,产生一个接受USB鼠标数据的线程

CMouse * pMouse = new CMouse(hDevice, lpUsbFuncs, lpInterface);

if (pMouse == NULL)

return FALSE;

 

if (!pMouse->Initialize())

{

delete pMouse;

return FALSE;

}

 

// 注册一个监控USB设备事件的回调函数,用于监控USB设备是否已经拔掉。

(*lpUsbFuncs->lpRegisterNotificationRoutine)(hDevice,

USBDeviceNotifications, pMouse);

 

*fAcceptControl = TRUE;

return TRUE;

}

 

第二个函数是 USBInstallDriver()函数,

一些基本定义如下:

const WCHAR gcszRegisterClientDriverId[] = L"RegisterClientDriverID";

const WCHAR gcszRegisterClientSettings[] = L"RegisterClientSettings";

const WCHAR gcszUnRegisterClientDriverId[] = L"UnRegisterClientDriverID";

const WCHAR gcszUnRegisterClientSettings[] = L"UnRegisterClientSettings";

const WCHAR gcszMouseDriverId[] = L"Generic_Sample_Mouse_Driver";

 

函数接口如下:

extern "C" BOOL

USBInstallDriver(

LPCWSTR szDriverLibFile) // @parm [IN] - Contains client driver DLL name

{

BOOL fRet = FALSE;

HINSTANCE hInst = LoadLibrary(L"USBD.DLL");

 

// 注册USB设备信息

if(hInst)

{

LPREGISTER_CLIENT_DRIVER_ID pRegisterId = (LPREGISTER_CLIENT_DRIVER_ID)

GetProcAddress(hInst, gcszRegisterClientDriverId);

 

LPREGISTER_CLIENT_SETTINGS pRegisterSettings =

(LPREGISTER_CLIENT_SETTINGS) GetProcAddress(hInst,

gcszRegisterClientSettings);

 

if(pRegisterId && pRegisterSettings)

{

USB_DRIVER_SETTINGS DriverSettings;

 

DriverSettings.dwCount = sizeof(DriverSettings);

 

// 设置我们的特定的信息。

DriverSettings.dwVendorId = USB_NO_INFO;

DriverSettings.dwProductId = USB_NO_INFO;

DriverSettings.dwReleaseNumber = USB_NO_INFO;

 

DriverSettings.dwDeviceClass = USB_NO_INFO;

DriverSettings.dwDeviceSubClass = USB_NO_INFO;

DriverSettings.dwDeviceProtocol = USB_NO_INFO;

 

DriverSettings.dwInterfaceClass = 0x03; // HID

DriverSettings.dwInterfaceSubClass = 0x01; // boot device

DriverSettings.dwInterfaceProtocol = 0x02; // mouse

 

fRet = (*pRegisterId)(gcszMouseDriverId);

 

if(fRet)

{

fRet = (*pRegisterSettings)(szDriverLibFile,

gcszMouseDriverId, NULL, &DriverSettings);

 

if(!fRet)

{

//BUGBUG unregister the Client Driver’s ID

}

}

}

else

{

RETAILMSG(1,(TEXT("!USBMouse: Error getting USBD function pointers/r/n")));

}

FreeLibrary(hInst);

}

return fRet;

}

上述代码主要用于产生USB设备驱动程序需要的注册表信息,需要注意的是:USB设备驱动程序不使用标准的注册表函数,而是使用RegisterClientDriverID()和RegisterClientSettings来注册相应的设备信息。

 

另外一个函数是USBUninstallDriver()函数,具体代码如下:

extern "C" BOOL

USBUnInstallDriver()

{

BOOL fRet = FALSE;

HINSTANCE hInst = LoadLibrary(L"USBD.DLL");

 

if(hInst)

{

LPUN_REGISTER_CLIENT_DRIVER_ID pUnRegisterId =

(LPUN_REGISTER_CLIENT_DRIVER_ID)

GetProcAddress(hInst, gcszUnRegisterClientDriverId);

 

LPUN_REGISTER_CLIENT_SETTINGS pUnRegisterSettings =

(LPUN_REGISTER_CLIENT_SETTINGS) GetProcAddress(hInst,

gcszUnRegisterClientSettings);

 

if(pUnRegisterSettings)

{

USB_DRIVER_SETTINGS DriverSettings;

 

DriverSettings.dwCount = sizeof(DriverSettings);

// 必须填入与注册时相同的信息。

DriverSettings.dwVendorId = USB_NO_INFO;

DriverSettings.dwProductId = USB_NO_INFO;

DriverSettings.dwReleaseNumber = USB_NO_INFO;

 

DriverSettings.dwDeviceClass = USB_NO_INFO;

DriverSettings.dwDeviceSubClass = USB_NO_INFO;

DriverSettings.dwDeviceProtocol = USB_NO_INFO;

 

DriverSettings.dwInterfaceClass = 0x03; // HID

DriverSettings.dwInterfaceSubClass = 0x01; // boot device

DriverSettings.dwInterfaceProtocol = 0x02; // mouse

 

fRet = (*pUnRegisterSettings)(gcszMouseDriverId, NULL,

&DriverSettings);

}

 

if(pUnRegisterId)

{

BOOL fRetTemp = (*pUnRegisterId)(gcszMouseDriverId);

fRet = fRet ? fRetTemp : fRet;

}

FreeLibrary(hInst);

}

return fRet;

}

此函数主要用于删除USBInstallDriver()时创建的注册表信息,同样的它使用自己的函数接口UnRegisterClientDriverID()和UnRegisterClientSettings()来做相应的处理。

另外一个需要处理的注册的监控通知函数USBDeviceNotifications():

extern "C" BOOL USBDeviceNotifications(LPVOID lpvNotifyParameter, DWORD dwCode,

LPDWORD * dwInfo1, LPDWORD * dwInfo2, LPDWORD * dwInfo3,

LPDWORD * dwInfo4)

{

CMouse * pMouse = (CMouse *)lpvNotifyParameter;

 

switch(dwCode)

{

case USB_CLOSE_DEVICE:

//删除相关的资源。

delete pMouse;

return TRUE;

}

return FALSE;

}

 

未完待续...... 

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值