zhiyaormb 2023-05-11 14:08 采纳率: 23.1%
浏览 152
已结题

libusb的libusb_bulk_transfer函数超时

win10 64系统,libusb 1.0,用zadig安装的驱动。目标设备采用bulk传输,一问一答的方式,既PC向目标板(EndPoint 0x01)发一条数据,再从目标板(EndPoint 0x81)读回来一组数据。写的数据长度为8字节,读不到300字节。因为通讯很频繁,且对时间比较敏感,所以需要控制完成一次读写(一读一写)所需的时间。这个时间发现经常会在30ms左右,且很少有28ms~5ms之间的值(希望是在5ms以内,其中2ms是目标板卡执行指令的时间,这个时间是目标板定时器决定的)。已经设置数据交互进程的优先级为RealTime。用QueryPerformanceCounter和QueryPerformanceFrequency作定时器判断执行的时间.
主要部分代码如下:

int init()
{
  ....
    if(libusb_init(&ctx))
   {
       return -1;
   }
    cnt = libusb_get_device_list(ctx, &dev_list);
    if(cnt < 0)
    {
         libusb_exit(ctx);
         return -2;
    }
   for(int i = 0; i < cnt; i ++)
   {
          if(libusb_get_device_descriptor(dev_list[i], &dev_desc[i]))
          {
                  return -3;
          }
          .......
   }
   return cnt;
}

int open(int dev)
{
     .......
     libusb_open(...,...);
     ......
     libusb_set_auto_detach_kernel_driver(......,  1);
     libusb_claim_interface(......,0);
}
int write(int dev, uchar* buf, int len, int ot_ms)
{
       ......
        rtn = libusb_bulk_transfer(h_dev[id],1, buf,len, &rel_len,ot_ms );
       ......
}
int read(int dev, uchar* buf, int len, int ot_ms)
{
      {
       ......
        rtn = libusb_bulk_transfer(h_dev[id],0X81, buf,len, &rel_len,ot_ms );
       ......
    }
}
void test(int retry)
{
  double ms;
  for(int i = 0; i < retry; i ++)
  {
    timer_start();
    EnterCriticalSection(&cs);
    rtn = write(......);
    if(rtn)
    {
        .......
    }
    //也曾经在这里timer_start,用来卡read的时间,发现实际上超时的都是read
    rtn =read(......);
    LeaveCriticalSection(&cs);
    if(rtn)
   {
      ..........
   }
    ms = timer_get_ms();
    if(ms > 5)
    {
        ..............
    }
    timer_dly_ms(1);
  }
}

用程序卡时间,发现每次都是read超时。但用BUS Hound抓包,与程序的执行略有不同,每次超时之后,下一次write的时间点,与超时当次read的时间点差距,正好接近超时多出来的时间。怀疑只是Bus Hound计的时间点是write或者read的开始时间点所导致。即便超时,Bus Hound抓到的数据本身也是对的。尝试过缩短read每一包数据的长度到64字节以内,发现依然会有类似的情况。
请问这个可能是什么原因造成的?是否有改善的思路?如何改善?谢谢

补充一点,libusb_bulk_transfer函数 的超时时间其实为这里只设置了5ms,但是一次数据读写实际执行的时间却有可能超过28ms,这期间并没有发现libusb返回超时错误,这个超时是我自己用QueryPerformanceFrequency和QueryPerformanceCounter测量的时间超时。

  • 写回答

6条回答 默认 最新

  • Leodong. 2023-05-11 14:29
    关注

    该回答通过自己思路及引用到GPTᴼᴾᴱᴺᴬᴵ搜索,得到内容具体如下:

    从代码和描述来看,您的程序使用的是libusb库进行USB通讯,在写入和读取数据时,使用的是libusb_bulk_transfer函数,并设置了超时时间ot_ms。您的目标是控制一次读写(一读一写)所需的时间,并且希望这个时间在5ms以内。但是实际测试中,发现经常会在30ms左右,很少有在5ms以内的情况,且每次超时都是在读取(read)数据时发生的。
    
    可能的原因:
    
    1. USB总线带宽限制:USB总线的带宽是有限的,如果数据量较大,可能会导致读写数据的时间较长。您可以通过缩短每一包数据的长度来测试是否有改善。
    
    2. 系统调度和中断处理:在Windows系统中,有很多后台任务和中断处理程序,这些可能会干扰您的程序执行,导致读写时间不稳定。您可以尝试使用实时线程或者提高线程的优先级来减少系统干扰。
    
    3. USB设备响应时间:USB设备的响应时间也会影响读写时间,如果设备响应时间较长,可能会导致读写时间较长。您可以查看设备的响应时间,并根据需要优化设备响应时间。
    
    改善思路:
    
    1. 使用异步传输:libusb支持异步传输,使用异步传输可以减少读写时间,提高程序的响应速度。您可以尝试使用libusb_submit_transfer函数进行异步传输,这样就可以在等待数据传输完成的同时,执行其他操作,从而提高程序的并发性。
    
    2. 使用多线程:使用多线程可以使程序更加并发,提高程序的响应速度。您可以将读写操作放在不同的线程中执行,这样可以避免读写操作之间的互相干扰,从而提高程序的稳定性。
    
    3. 优化USB设备:如果USB设备的响应时间较长,可以尝试优化设备的响应时间,例如使用更快的处理器或者优化设备驱动程序等。
    
    总之,USB通讯的时间受到多种因素的影响,需要全面考虑。您可以综合考虑以上因素,选择合适的优化方式来改善程序的执行效率。
    
    

    如果以上回答对您有所帮助,点击一下采纳该答案~谢谢

    评论

报告相同问题?

问题事件

  • 系统已结题 5月19日
  • 修改了问题 5月11日
  • 修改了问题 5月11日
  • 创建了问题 5月11日

悬赏问题

  • ¥50 AI大模型精调(百度千帆、飞浆)
  • ¥15 关于#c语言#的问题:我在vscode和codeblocks中编写c语言时出现打不开源文件该怎么办
  • ¥15 非科班怎么跑代码?如何导数据和调参
  • ¥15 福州市的全人群死因监测点死亡原因报表
  • ¥15 Altair EDEM中生成一个颗粒,并且各个方向没有初始速度
  • ¥15 系统2008r2 装机配置推荐一下
  • ¥500 服务器搭建cisco AnyConnect vpn
  • ¥15 悬赏Python-playwright部署在centos7上
  • ¥15 psoc creator软件有没有人能远程安装啊
  • ¥15 快速扫描算法求解Eikonal方程咨询