guanbenben1984
驱动牛犊
驱动牛犊
  • 注册日期2007-08-13
  • 最后登录2007-09-21
  • 粉丝0
  • 关注0
  • 积分80分
  • 威望9点
  • 贡献值0点
  • 好评度8点
  • 原创分0分
  • 专家分0分
阅读:5904回复:23

大家进来看看我写的USB上位机读写代码,分析一下问题

楼主#
更多 发布于:2007-09-08 14:55
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;
    
guanbenben1984
驱动牛犊
驱动牛犊
  • 注册日期2007-08-13
  • 最后登录2007-09-21
  • 粉丝0
  • 关注0
  • 积分80分
  • 威望9点
  • 贡献值0点
  • 好评度8点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2007-09-10 08:30
我用这段代码通讯找不到USB设备,哪位哥哥可以指教一下问题出在了哪里?
zhourenyun
驱动牛犊
驱动牛犊
  • 注册日期2007-03-13
  • 最后登录2009-04-13
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望17点
  • 贡献值0点
  • 好评度16点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2007-09-11 11:57
纠正一点
不是用completeDeviceName打开文件句柄的
你用的是createfile打开的文件句柄
2 如果句柄没有获取的最大原因可能是你的usb设备没有连接。
3usb设备的guid应该是guidDEV,   0xa5dcbf10,   0x6530,   0x11d2,
            0x90,   0x1f,   0x00,   0xc0,   0x4f,   0xb9,   0x51,   0xed
skertone
驱动牛犊
驱动牛犊
  • 注册日期2006-06-23
  • 最后登录2015-03-12
  • 粉丝0
  • 关注0
  • 积分476分
  • 威望99点
  • 贡献值0点
  • 好评度48点
  • 原创分0分
  • 专家分0分
地板#
发布于:2007-09-11 13:08
有三个名字要对
1.GUID
   这个没什么好说要约定好
2.端点名,分开读与写
  这个与驱动程序有关有些定义成 \\2  \\3 有些又定义成 \\piep2  \\pipe3 其实质不过传个字符串参数给驱动程序而已,这个要对

3.
strcpy(completeDeviceName,devDetail->DevicePath);
    strcat(completeDeviceName,"\\PIPE1");
    
    HANDLE usb;
    usb=CreateFile(devDetail->DevicePath,

  这段测试设备的就不用了吧?直接到下面用 \\DEVICENAME\\PIPEX 的名称去CreateFile来用就行了。

以下是我的一段代码
{

    HANDLE h;

    if ( !GetUsbDeviceFileName((LPGUID) &GUID_CLASS_D12_BULK,completeDeviceName) )
    {
        return  INVALID_HANDLE_VALUE;
    }

    strcat (completeDeviceName,    "\\");            

    strcat (completeDeviceName,filename);                    

    h = CreateFile(completeDeviceName,
        GENERIC_WRITE | GENERIC_READ,
        FILE_SHARE_WRITE | FILE_SHARE_READ,
        NULL,
        OPEN_EXISTING,
        FILE_FLAG_OVERLAPPED,
//        0,
        NULL);

    return h;
}
greetanan
驱动牛犊
驱动牛犊
  • 注册日期2007-06-05
  • 最后登录2010-07-15
  • 粉丝0
  • 关注0
  • 积分2分
  • 威望33点
  • 贡献值0点
  • 好评度21点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2007-09-11 14:34
zhourenyun你好:
 我用completedevicename打开的是对应的读写管道,然后用获得的句柄进行读写
打开设备用的是devDetail_DevicePath。
不知道这么说对不对?请指教
greetanan
驱动牛犊
驱动牛犊
  • 注册日期2007-06-05
  • 最后登录2010-07-15
  • 粉丝0
  • 关注0
  • 积分2分
  • 威望33点
  • 贡献值0点
  • 好评度21点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2007-09-11 14:38
还有一点疑问,guid为什么应该是guidDEV,  0xa5dcbf10,  0x6530,  0x11d2, 0x90,  0x1f,  0x00,  0xc0,  0x4f,  0xb9,  0x51,  0xed?
代码里面的GUID应该是我在驱动程序中定义的GUID吧
你所说的这个GUID是在注册表里面的一个GUID,对于这点我也有点混淆
greetanan
驱动牛犊
驱动牛犊
  • 注册日期2007-06-05
  • 最后登录2010-07-15
  • 粉丝0
  • 关注0
  • 积分2分
  • 威望33点
  • 贡献值0点
  • 好评度21点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2007-09-11 14:54
skertone 你好:
   上位机于USB通信是不是这样的过程:
1。createfile()先打开USB设备,得到句柄usbhandle
2。打开读写管道,得到句柄hread,hwrite;
3。createfile(hread...)进行读写操作
4。关闭hread,hwrite
5。关闭usbhandle
我用那段测试性的代码是为了得到devicePath,从而打开设备
是不是函数GetUsbDeviceFileName可以实现这段代码的功能?
期待您的答复
 
skertone
驱动牛犊
驱动牛犊
  • 注册日期2006-06-23
  • 最后登录2015-03-12
  • 粉丝0
  • 关注0
  • 积分476分
  • 威望99点
  • 贡献值0点
  • 好评度48点
  • 原创分0分
  • 专家分0分
7楼#
发布于: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;
}
greetanan
驱动牛犊
驱动牛犊
  • 注册日期2007-06-05
  • 最后登录2010-07-15
  • 粉丝0
  • 关注0
  • 积分2分
  • 威望33点
  • 贡献值0点
  • 好评度21点
  • 原创分0分
  • 专家分0分
8楼#
发布于: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
另:怎么给你分啊?很感谢你的热心指点
skertone
驱动牛犊
驱动牛犊
  • 注册日期2006-06-23
  • 最后登录2015-03-12
  • 粉丝0
  • 关注0
  • 积分476分
  • 威望99点
  • 贡献值0点
  • 好评度48点
  • 原创分0分
  • 专家分0分
9楼#
发布于: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;
        }
greetanan
驱动牛犊
驱动牛犊
  • 注册日期2007-06-05
  • 最后登录2010-07-15
  • 粉丝0
  • 关注0
  • 积分2分
  • 威望33点
  • 贡献值0点
  • 好评度21点
  • 原创分0分
  • 专家分0分
10楼#
发布于:2007-09-11 16:54
skertone兄:
当程序单步到if(!SetupDiEnumDeviceInterfaces(hdev_info, NULL, pguid, instance, &ifdata))    __leave;时,直接跳到了__finally,再用别的代码调试时也是到了这句后退出了,这是什么原因啊?

您是否有QQ或MSN,小弟向你详细请教一下,不会占用您太多时间
我的QQ:280595580
MSN:lhappyrain@hotmail.com
greetanan
驱动牛犊
驱动牛犊
  • 注册日期2007-06-05
  • 最后登录2010-07-15
  • 粉丝0
  • 关注0
  • 积分2分
  • 威望33点
  • 贡献值0点
  • 好评度21点
  • 原创分0分
  • 专家分0分
11楼#
发布于: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);,还是不行的!
greetanan
驱动牛犊
驱动牛犊
  • 注册日期2007-06-05
  • 最后登录2010-07-15
  • 粉丝0
  • 关注0
  • 积分2分
  • 威望33点
  • 贡献值0点
  • 好评度21点
  • 原创分0分
  • 专家分0分
12楼#
发布于:2007-09-12 09:58
自己顶一下
zhourenyun
驱动牛犊
驱动牛犊
  • 注册日期2007-03-13
  • 最后登录2009-04-13
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望17点
  • 贡献值0点
  • 好评度16点
  • 原创分0分
  • 专家分0分
13楼#
发布于: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设备信息。
zhourenyun
驱动牛犊
驱动牛犊
  • 注册日期2007-03-13
  • 最后登录2009-04-13
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望17点
  • 贡献值0点
  • 好评度16点
  • 原创分0分
  • 专家分0分
14楼#
发布于:2007-09-12 10:55
应该是
1.先由GUID (存于注册表,源于驱动程序) 获取 DeviceName
2.由DeviceName 可以获得两个文件名用于读写
  \\DeviceName\PipeWrite  \\DeviceName\PipeRead
3.然后就是标准的Widnows文件读写了
  CreateFile(FileName....) 打开文件 再ReadFile WriteFile
CloseFile
。。。。。。。。。。。。。。。。。。。。。。
这个是上位机和下位机通信的具体步骤。
greetanan
驱动牛犊
驱动牛犊
  • 注册日期2007-06-05
  • 最后登录2010-07-15
  • 粉丝0
  • 关注0
  • 积分2分
  • 威望33点
  • 贡献值0点
  • 好评度21点
  • 原创分0分
  • 专家分0分
15楼#
发布于: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?()
greetanan
驱动牛犊
驱动牛犊
  • 注册日期2007-06-05
  • 最后登录2010-07-15
  • 粉丝0
  • 关注0
  • 积分2分
  • 威望33点
  • 贡献值0点
  • 好评度21点
  • 原创分0分
  • 专家分0分
16楼#
发布于:2007-09-12 11:40
期待有经验的朋友来帮助一下,着急上火:(
skertone
驱动牛犊
驱动牛犊
  • 注册日期2006-06-23
  • 最后登录2015-03-12
  • 粉丝0
  • 关注0
  • 积分476分
  • 威望99点
  • 贡献值0点
  • 好评度48点
  • 原创分0分
  • 专家分0分
17楼#
发布于:2007-09-12 12:43
给个看你设备实际GUID的软件给你吧
附件名称/大小 下载次数 最后更新
DevMgr.rar (28KB)  32 2007-09-12 12:43
greetanan
驱动牛犊
驱动牛犊
  • 注册日期2007-06-05
  • 最后登录2010-07-15
  • 粉丝0
  • 关注0
  • 积分2分
  • 威望33点
  • 贡献值0点
  • 好评度21点
  • 原创分0分
  • 专家分0分
18楼#
发布于: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,谢谢了
guanbenben1984
驱动牛犊
驱动牛犊
  • 注册日期2007-08-13
  • 最后登录2007-09-21
  • 粉丝0
  • 关注0
  • 积分80分
  • 威望9点
  • 贡献值0点
  • 好评度8点
  • 原创分0分
  • 专家分0分
19楼#
发布于:2007-09-12 16:08
  自己up
上一页
游客

返回顶部