您的位置:首页 > 其它

基于Cy68013的USB设备在VC程序中热插拔的实现

2009-06-05 20:21 555 查看
开发基于Cy68013的USB设备已经有一段时间,虽然知道它可以支持即插即用,但是一直没有去设计相关的代码,只是在MFC中设计了一个名为“USB连接”的按钮来手动连接到USB设备(参考《USB应用开发技术大全》薛园园编著 人民邮电出版社,2007)。最近又去翻看Cy68013的帮助文档,发现了支持插即用的相关代码,于是试验了一下,基本解决了基于Cy68013的USB设备的PnP功能。

在CyAPI的帮助文件中,对于提供的USB设备类CCyUSBDevice有一段这样的解释:

CCyUSBDevice::CCyUSBDevice(HANDLE hnd = NULL, GUID guid = CYUSBDRV_GUID)

* This is the constructor for the CCyUSBDevice class.

* It registers the window of hnd to receive USB Plug and Play messages when devices are onnected or disconnected to/from the driver.

* The object created serves as the programming interface to the driver whose GUID is passed in the guid parameter.

可见,在构建类的对象时给定其HANDLE之后便可以支持USB即插即用。

在CyAPI的帮助文件中还给出了代码示例(虽然是c++ Builder的代码,但对VC程序还是有借鉴作用的)。代码如下:

void __fastcall TMainForm::FormCreate(TObject *Sender)

{

USBDevice = new CCyUSBDevice(Handle);

CurrentEndPt = USBDevice->ControlEndPt;

}

// Overload MainForm's WndProc method to watch for PnP messages

// Requires #include <dbt.h>

void __fastcall TMainForm::WndProc(TMessage &Message)

{

if (Message.Msg == WM_DEVICECHANGE) {

// Tracks DBT_DEVICEARRIVAL followed by DBT_DEVNODES_CHANGED

if (Message.WParam == DBT_DEVICEARRIVAL) {

bPnP_Arrival = true;

bPnP_DevNodeChange = false;

}

// Tracks DBT_DEVNODES_CHANGED followed by DBT_DEVICEREMOVECOMPLETE

if (Message.WParam == DBT_DEVNODES_CHANGED) {

bPnP_DevNodeChange = true;

bPnP_Removal = false;

}

if (Message.WParam == DBT_DEVICEREMOVECOMPLETE) {

bPnP_Removal = true;

PDEV_BROADCAST_HDR bcastHdr = (PDEV_BROADCAST_HDR) Message.LParam;

if (bcastHdr->dbch_devicetype == DBT_DEVTYP_HANDLE) {

PDEV_BROADCAST_HANDLE pDev = (PDEV_BROADCAST_HANDLE) Message.LParam;

if (pDev->dbch_handle == USBDevice->DeviceHandle())

USBDevice->Close();

}

}

// If DBT_DEVNODES_CHANGED followed by DBT_DEVICEREMOVECOMPLETE

if (bPnP_Removal && bPnP_DevNodeChange) {

Sleep(10);

DisplayDevices();

bPnP_Removal = false;

bPnP_DevNodeChange = false;

}

// If DBT_DEVICEARRIVAL followed by DBT_DEVNODES_CHANGED

if (bPnP_DevNodeChange && bPnP_Arrival) {

DisplayDevices();

bPnP_Arrival = false;

bPnP_DevNodeChange = false;

}

}

TForm::WndProc(Message);

}

可以看出,程序通过重载WndProc来实现USB设备的相关通知(“Overload MainForm's WndProc method to watch for PnP messages ”), 而在VC下也是有这个函数的,仿照上述代码,可以编写代码如下:

LRESULT C**IDlg::WindowProc(UINT message,WPARAM wParam,LPARAM lParam)

{

// TODO: 在此添加专用代码和/或调用基类

if (message == WM_DEVICECHANGE)

{

// Tracks DBT_DEVICEARRIVAL followed by DBT_DEVNODES_CHANGED

if (wParam == DBT_DEVICEARRIVAL)

{

bPnP_Arrival = true;

bPnP_DevNodeChange = false;

}

// Tracks DBT_DEVNODES_CHANGED followed by DBT_DEVICEREMOVECOMPLETE

if (wParam == DBT_DEVNODES_CHANGED)

{

bPnP_DevNodeChange = true;

bPnP_Removal = false;

}

if (wParam == DBT_DEVICEREMOVECOMPLETE)

{

bPnP_Removal = true;

// PDEV_BROADCAST_HDR bcastHdr = (PDEV_BROADCAST_HDR) lParam;

// if (bcastHdr->dbch_devicetype == DBT_DEVTYP_HANDLE)

{

// PDEV_BROADCAST_HANDLE pDev = (PDEV_BROADCAST_HANDLE) lParam;

// DEV_BROADCAST_HDR *stHDR;

// stHDR = (DEV_BROADCAST_HDR *)lParam;

//if (pDev->dbch_handle == USBDevice->DeviceHandle()) //判断设备类型

//if (stHDR->dbch_handle == USBDevice->DeviceHandle())

// USBDevice->Close();

}

}

// If DBT_DEVNODES_CHANGED followed by DBT_DEVICEREMOVECOMPLETE

if (bPnP_Removal && bPnP_DevNodeChange)

{

Sleep(10);

DisplayDevices();

bPnP_Removal = false;

bPnP_DevNodeChange = false;

}

// If DBT_DEVICEARRIVAL followed by DBT_DEVNODES_CHANGED

if (bPnP_DevNodeChange && bPnP_Arrival)

{

DisplayDevices();

bPnP_Arrival = false;

bPnP_DevNodeChange = false;

}

}

return CDialog::WindowProc(message,wParam,lParam);

}

然而该段代码并没有指明产生USB消息的设备类型,因此任何USB设备的插拔都会引起程序的相应,为了准确识别到Cy68013的USB设备特别编写了代码中加粗的DisplayDevices(),代码如下:

void CECHWorkStationIIDlg::DisplayDevices()

{

if(USBDevice->IsOpen())

{

USBDevice->Open(0);

if(!USBDevice->IsOpen())

{

USBDevice->Close();

m_USBStatus = "未连接到仪器";

UpdateData(FALSE);

// MessageBox("USB设备移除。/n","USB connect",MB_OK|MB_ICONERROR);

}

}

else

{

USBDevice->Open(0);

if(USBDevice->IsOpen())

{

m_USBStatus = USBDevice->DeviceName;

UpdateData(FALSE);

if(USBDevice->DeviceCount()>1)

MessageBox("应用程序不支持多台仪器同时连接到电脑。/n请移除不必要的仪器!/n","出错",MB_OK|MB_ICONERROR);

}

}

}

这样就实现了CY68013设备的热插拔。

上述内容只是提供了一种解决CY68013 USB设备的一种方法。更多方法欢迎大家一起讨论!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: