libusb异步接收数据丢包问题


libusb异步接收数据丢包问题

  1人已赏 易百纳技术社区 小王子?? 2020-08-25 17:51:11

一、 libusb异步接收数据丢包问题

经过种种的坑,终于可以通过异步传输的方式收发数据,但是再实际使用中又出现了一个坑,还是比较致命的坑:对于接收时间间隔较大的数据是完全没有问题的,但是当下位机以很短的时间间隔快速发送数据时,这是上位机使用libusb接收数据就会出现丢包现象,对于较为严格的数据交互这是不允许存在的。

因为libusb是一个比较强大的库,所以出现这种情况我的第一反映是对libusb库的使用出了问题,肯定是有一些地方我没注意到,少写了哪一个步骤导致的。

紧接着我就开始在网上各种查找,结果一无所获,我有重新看了一遍libusb的API文档,结果还是一无所获。

网上查不到资料,我就自己调试程序,一遍遍的调试,扩大传输结构中的缓存大小、变化超时时间等方法都没有用。

最后我尝试着提交多个接收传输结构发现不丢包了,问题解决了。

https://www.ebaina.com/articles/140000004301

一直以为接收缓存仅仅只是传输结构中的缓存,解决问题后才发现提交多个接收传输结构等待接收也属于多开缓存等待接收

 int rc = 0;
    for(int i = 0;i<100;i++)
    {
        libusb_transfer* transfer = libusb_alloc_transfer(0);
        unsigned char *buf = new unsigned char[64];
        memset(buf,0,64);
        transfer->actual_length = 0;
       libusb_fill_bulk_transfer(transfer,dHand,0x82,buf,64,&callbackRevc,this,0);
        rc = libusb_submit_transfer(transfer);
        if(rc < 0)
        {
            libusb_cancel_transfer(transfer);
            libusb_free_transfer(transfer);
            transfer = nullptr;
            qDebug() << "libusb_submit_transfer file:" << rc;
            return;
        }

        qDebug() << rc;

        qTransferList.append(transfer);
}

二、关闭设备后再次打开提交传输失败

在使用中无意间发现当我不关闭程序,仅仅只对设备进行关闭重新打开时提交传输结构失败,导致无法接收也无法发送。 刚开始以为时设备关闭不彻底导致的,在多次调试检查关闭接口后发现关闭设备没有问题,问题不是出现在关闭上,最后发现是因为提交的接收传输结构没有取消释放才导致再次打开设备提交传输结构时失败,所以要在设备关闭时取消传输和释放传输。

原本这个问题就这样解决了,结果又出现了一个问题,取消完所有的接收传输然后立即释放传输结构时会导致程序崩溃,原来取消传输也是属于异步操作,取消传输后不可以立即调用接口释放传输接口,而是要等待取消传输完成后再释放传输结构,取消传输完成后会调用回调函数同时当前传输结构已经取消,这个时候才可以释放传输结构

//取消传输结构
{
    foreach(auto i,qTransferList){
       libusb_cancel_transfer(i);
    }
    qTransferList.clear();
}
void callbackRevc(struct libusb_transfer *transfer)
{
    if (transfer->status == LIBUSB_TRANSFER_COMPLETED) {
}else if (transfer->status == LIBUSB_TRANSFER_CANCELLED) {
//取消完成,释放传输结构
        libusb_free_transfer(transfer);
    }else{
    }

}

三、同一份代码,换个设备就通讯不了了

在使用中出现过代码没动换个设备就用不了了,这是个非常简单的坑,稍微有点USB基础只是都不会出现这个错误,当然也可能是忘记了,不同设备可能他们的通讯接口号和端点号都不一样,需要修改声明的接口号和传输的端点。

Windows上可以使用“UsbTreeView.exe”这个软件查询设备信息。当然也可以使用libusb的查询设备描述符接口,我这里比较懒,直接查询各个设备的信息进行匹配的。

接下来补充个概念

接口:应用软件通过和设备之间的数据交换来完成设备的控制和数据传输。通常需要多个管道来完成数据交换,因为同一管道只支持一种类型的数据传输。用在一起来对设备进行控制的若干管道称为设备的接口。

所以首先要确定接口号是否正确,接口号若错了那么通讯的管道就错了,端点对也没用

端点:端点是USB 设备中的可以进行数据收发的最小单元,支持单向或者双向的数据传输。

所以端点号也不能错,而且输入输出的方向也要对应上