阅读:5902回复:23
大家进来看看我写的USB上位机读写代码,分析一下问题
USB芯片是ISP1161,驱动程序用的是DDK下面的BULKUSB,下面是我写的一段读写代码,大家看对不对啊,思路是这样的:先用devDetail->DevicePath打开设备,然后用completeDeviceName打开对应的读写通道,然后用获得的句柄进行readfile(),writefile()操作
DWORD TransTimes = len/64; DWORD i,j; ULONG nBytes,Sum = 0; pProg = (CProgressCtrl*)GetDlgItem(IDC_PROGRESS); pProg->SetRange32(0,len); pProg->SetPos(0); pProg->SetStep(1); char inPipe[32] = "PIPE00"; // pipe name for bulk input pipe on our test board char outPipe[32] = "PIPE01"; // pipe name for bulk output pipe on our test board char completeDeviceName[256] = ""; //generated from the GUID registered by the driver itself const GUID DiskClassGuid = {0x6309DF86,0x017C,0x410e,{0x9D,0x7E,0XB8,0X97,0XF0,0XEF,0XCF,0XB6}}; GUID hidGuid ; hidGuid=DiskClassGuid; HDEVINFO hDevInfo = SetupDiGetClassDevs(&hidGuid, NULL, // no enumerator NULL, // no parent (DIGCF_PRESENT | DIGCF_INTERFACEDEVICE)); if(!hDevInfo) { MessageBox( "Couldn't get handle for HID devices.", NULL, MB_OK | MB_ICONSTOP); return 0; } SP_INTERFACE_DEVICE_DATA devInfoData; devInfoData.cbSize = sizeof (SP_INTERFACE_DEVICE_DATA); int deviceNo = 0; SetLastError(NO_ERROR); SetupDiEnumInterfaceDevice (hDevInfo, 0,//lpDeviceInfoData, &hidGuid, deviceNo, &devInfoData); ULONG requiredLength = 0; SetupDiGetInterfaceDeviceDetail(hDevInfo, &devInfoData, NULL, 0, &requiredLength, NULL); PSP_INTERFACE_DEVICE_DETAIL_DATA devDetail = (SP_INTERFACE_DEVICE_DETAIL_DATA*) malloc (requiredLength); devDetail->cbSize = sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA); strcpy(completeDeviceName,devDetail->DevicePath); strcat(completeDeviceName,"\\PIPE1"); HANDLE usb; usb=CreateFile(devDetail->DevicePath, GENERIC_READ |GENERIC_WRITE, FILE_SHARE_WRITE | FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); if (usb==INVALID_HANDLE_VALUE) { MessageBox("can't open device.", NULL, MB_OK | MB_ICONSTOP); return 0; } if ( direction == 1 ) //读取 { HANDLE hread=CreateFile(completeDeviceName, GENERIC_READ |GENERIC_WRITE, FILE_SHARE_WRITE | FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); if (hread==INVALID_HANDLE_VALUE) { MessageBox ( "can't open pipe.", NULL, MB_OK | MB_ICONSTOP ); } for ( i = 0,j = 0; i < TransTimes; i++,j = j + 64 ) { ReadFile(hread, &data[j], 64, &nBytes, NULL); Sum += nBytes; SetDlgItemInt( IDC_start1, i, FALSE); } _ASSERT ( Sum == 512*512 ); CloseHandle(hread); } else { HANDLE hwrite=CreateFile(completeDeviceName, GENERIC_READ |GENERIC_WRITE, FILE_SHARE_WRITE | FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); if (hwrite==INVALID_HANDLE_VALUE) { MessageBox("can't open outpipe.",NULL,MB_OK | MB_ICONSTOP); } for ( i = 0,j = 0; i < TransTimes; i++,j = j + 64 ) { WriteFile(hwrite, &data[j], 64, &nBytes, NULL); Sum += nBytes; m_nProgress+=64; pProg->SetPos(m_nProgress); SetDlgItemInt( IDC_start1, i, FALSE); } CloseHandle(hwrite); } MessageBox ( "transfer complete !!!",NULL, MB_OK | MB_ICONSTOP ); CloseHandle(usb); return TRUE; |
|
沙发#
发布于:2007-09-14 09:54
每日UP
|
|
板凳#
发布于:2007-09-13 16:28
通过别的方法把问题解决了,但还是希望搞明白这个问题。等待热心人,每日一顶
|
|
地板#
发布于:2007-09-13 10:52
up up,不小于三了吧
|
|
地下室#
发布于:2007-09-12 16:23
skertone
............................. 我qq250933131有空讨论下usb开发啊。 |
|
5楼#
发布于:2007-09-12 16:08
自己up
|
|
6楼#
发布于:2007-09-12 13:59
谢谢SKERTONE
目前的情况是: 我在驱动中定义:DEFINE_GUID(GUID_CLASS_I82930_BULK, 0xb3493d4e, 0xacc7, 0x4a40, 0xbe, 0xd4, 0x94, 0x45, 0x17, 0x5b, 0x4b, 0x1e);在上位机软件得到设备路径的函数中我使用了GUID_CLASS_182930_BULK,当把驱动装好,插上USB设备后,用您给的软件得到的GUID是USB设备的那个CLASS GUID,即36fc9e60-c465-11cf-8056-444553540000 存在的问题是:SetupDiEnumDeviceInterfaces()仍然返回错误 请您务必关注一下,这个问题困扰我几天了,没人指点,我把论坛里关于这个问题的帖子翻遍了,结论大致是说GUID有问题,但是具体没说到底用哪个GUID,谢谢了 |
|
7楼#
发布于:2007-09-12 12:43
给个看你设备实际GUID的软件给你吧
|
|
|
8楼#
发布于:2007-09-12 11:40
期待有经验的朋友来帮助一下,着急上火:(
|
|
9楼#
发布于:2007-09-12 11:11
TO zhourenyun:
三个问题请教您 1.特定的guid返回的就是特定的设备,这里特定的GUID是指我在驱动程序里定义的GUID吗?我现在用的就是自己定义的GUID,但函数SetupDiEnumDeviceInterfaces()返回错误 2.usb设备类的guid返回的将是所有usb设备信息,USB设备类的GUID是您上面提到的0xa5dcbf10, 0x6530, 0x11d2, 0x90, 0x1f, 0x00, 0xc0, 0x4f, 0xb9, 0x51, 0xed吗?这个GUID与那个setup class GUID有何不同?这个GUID我还没有试 3.在驱动程序中调用IoRegisterDeviceInterface后面是否应该调用IoSetDeviceInterfaceState?() |
|
10楼#
发布于:2007-09-12 10:55
应该是
1.先由GUID (存于注册表,源于驱动程序) 获取 DeviceName 2.由DeviceName 可以获得两个文件名用于读写 \\DeviceName\PipeWrite \\DeviceName\PipeRead 3.然后就是标准的Widnows文件读写了 CreateFile(FileName....) 打开文件 再ReadFile WriteFile CloseFile 。。。。。。。。。。。。。。。。。。。。。。 这个是上位机和下位机通信的具体步骤。 |
|
11楼#
发布于:2007-09-12 10:54
还有一点疑问,guid为什么应该是guidDEV, 0xa5dcbf10, 0x6530, 0x11d2, 0x90, 0x1f, 0x00, 0xc0, 0x4f, 0xb9, 0x51, 0xed?
代码里面的GUID应该是我在驱动程序中定义的GUID吧 你所说的这个GUID是在注册表里面的一个GUID,对于这点我也有点混淆 ...................................... 如果用你特定的guid返回的就是特定的设备 如果用的是usb设备类的guid返回的将是所有usb设备信息。 |
|
12楼#
发布于:2007-09-12 09:58
自己顶一下
|
|
13楼#
发布于:2007-09-11 17:03
我翻了下论坛上很多朋友发帖谈过SetupDiEnumDeviceInterfaces返回错误这个问题,总结了下很有可能是GUID的原因,我刚才用GUID生成工具生成了一个GUID,并在驱动程序中使用了它:DEFINE_GUID(GUID_CLASS_I82930_BULK, 0xb3493d4e, 0xacc7, 0x4a40, 0xbe, 0xd4, 0x94, 0x45, 0x17, 0x5b, 0x4b, 0x1e);,还是不行的!
|
|
14楼#
发布于:2007-09-11 16:54
skertone兄:
当程序单步到if(!SetupDiEnumDeviceInterfaces(hdev_info, NULL, pguid, instance, &ifdata)) __leave;时,直接跳到了__finally,再用别的代码调试时也是到了这句后退出了,这是什么原因啊? 您是否有QQ或MSN,小弟向你详细请教一下,不会占用您太多时间 我的QQ:280595580 MSN:lhappyrain@hotmail.com |
|
15楼#
发布于:2007-09-11 16:52
是呀GUID 在驱动的安装文件 Inf文件中有的也有给出啊
GUID定义方式与你有点区别(非实际数据) DEFINE_GUID(GUID_CLASS_D12, 0xf5ad6c6c, 0xabcd, 0xefgh, 0xaa, 0xcc, 0xc7, 0xxx, 0xxx, 0xxx, 0xx, 0xxx); 以下是我的USB端口初始化代码 p_context->h_read=INVALID_HANDLE_VALUE; p_context->h_write=INVALID_HANDLE_VALUE; if(!GetDeviceViaInterface((LPGUID)&GUID_CLASS_D12,usbdev_name,0)) { ret_code=EUSB_DEVICE_NOT_EXIST; __leave; } strcpy(usb_filename,usbdev_name); strcat(usb_filename,"\\2"); p_context->h_read=CreateFile(usb_filename,GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ | FILE_SHARE_WRITE,NULL,OPEN_EXISTING,FILE_FLAG_OVERLAPPED,NULL); if(p_context->h_read==INVALID_HANDLE_VALUE) { ret_code=EUSB_DEVICE_INUSE; __leave; } strcpy(usb_filename,usbdev_name); strcat(usb_filename,"\\3"); p_context->h_write=CreateFile(usb_filename,GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ | FILE_SHARE_WRITE,NULL,OPEN_EXISTING,FILE_FLAG_OVERLAPPED,NULL); if(p_context->h_write==INVALID_HANDLE_VALUE) { ret_code=EUSB_DEVICE_INUSE; __leave; } |
|
16楼#
发布于:2007-09-11 16:04
TO skertone:
GUID (存于注册表,源于驱动程序),是不是如果正常的话注册表中的GUID和驱动程序中的GUID是一样的? 我这样使用了你给出的函数: GetDeviceViaInterface((LPGUID)&GUID_CLASS_I82930_BULK,completeDeviceName,4); 结果出现下面的编译错误: error C2660: 'GetDeviceViaInterface' : function does not take 3 parameters 另:怎么给你分啊?很感谢你的热心指点 |
|
17楼#
发布于:2007-09-11 15:13
应该是
1.先由GUID (存于注册表,源于驱动程序) 获取 DeviceName 2.由DeviceName 可以获得两个文件名用于读写 \\DeviceName\PipeWrite \\DeviceName\PipeRead 3.然后就是标准的Widnows文件读写了 CreateFile(FileName....) 打开文件 再ReadFile WriteFile CloseFile 至于设备? 除了取DeviceName时用下其它时没用,也并不需要打开着 我哪个函数封装层次太多了,给个直接点的 由GUID 获取 DeviceName int GetDeviceViaInterface( GUID* pguid, char* dev_name,int instance) { int ret_code=NULL; HDEVINFO hdev_info=NULL; SP_INTERFACE_DEVICE_DATA ifdata; PSP_INTERFACE_DEVICE_DETAIL_DATA p_ifdetail=NULL; DWORD reqlen; __try { hdev_info = SetupDiGetClassDevs(pguid, NULL, NULL, DIGCF_PRESENT | DIGCF_INTERFACEDEVICE); if(hdev_info==INVALID_HANDLE_VALUE) __leave; ifdata.cbSize = sizeof(ifdata); if(!SetupDiEnumDeviceInterfaces(hdev_info, NULL, pguid, instance, &ifdata)) __leave; SetupDiGetDeviceInterfaceDetail(hdev_info, &ifdata, NULL, 0, &reqlen, NULL); p_ifdetail = (PSP_INTERFACE_DEVICE_DETAIL_DATA)(new char[reqlen]); if(p_ifdetail==NULL) __leave; p_ifdetail->cbSize = sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA); if( !SetupDiGetDeviceInterfaceDetail(hdev_info, &ifdata, p_ifdetail, reqlen, NULL, NULL)) __leave; if(dev_name) strcpy(dev_name,p_ifdetail->DevicePath); ret_code=1; } __finally { if(hdev_info!=INVALID_HANDLE_VALUE) SetupDiDestroyDeviceInfoList(hdev_info); if (p_ifdetail!=NULL) delete p_ifdetail; } return ret_code; } |
|
18楼#
发布于:2007-09-11 14:54
skertone 你好:
上位机于USB通信是不是这样的过程: 1。createfile()先打开USB设备,得到句柄usbhandle 2。打开读写管道,得到句柄hread,hwrite; 3。createfile(hread...)进行读写操作 4。关闭hread,hwrite 5。关闭usbhandle 我用那段测试性的代码是为了得到devicePath,从而打开设备 是不是函数GetUsbDeviceFileName可以实现这段代码的功能? 期待您的答复 |
|
19楼#
发布于:2007-09-11 14:38
还有一点疑问,guid为什么应该是guidDEV, 0xa5dcbf10, 0x6530, 0x11d2, 0x90, 0x1f, 0x00, 0xc0, 0x4f, 0xb9, 0x51, 0xed?
代码里面的GUID应该是我在驱动程序中定义的GUID吧 你所说的这个GUID是在注册表里面的一个GUID,对于这点我也有点混淆 |
|
上一页
下一页