libusb开发(关于异步IO)

小王子🤴 2020-08-18 21:37:52 10483
libusb开发(关于异步IO)

上一篇介绍了libusb的同步传输接口,但是很多情况下使用同步传输远远达不到我们的要求,那么这个时候就应该使用异步传输。接下来的内容是我学习libusb时遇到的问题以及异步IO如何使用。

//异步写

void QUniversalSerialBus::AsyncWrite(unsigned char sendBuffer[],size_t len)
{
int rc = 0;
//创建异步传输结构
libusb_transfer* transfer = libusb_alloc_transfer(0);
//填充异步传输结构 
//transfer  传输结构
//dHand 设备句柄
//sendBuffer 要发送的数据
//len 数据长度
//callbackSend 回调函数,发送完成、失败、或者超时都会调用词回调
//this 用户数据,此处可以放任意数据,
//10 超时时间此处写的是10毫秒
libusb_fill_bulk_transfer(transfer,dHand,2,sendBuffer,static_cast<int>(len),&callbackSend,this,10);
//提交传输结构
rc = libusb_submit_transfer(transfer);
//判断是否传输成功
if(rc < 0)
{
//释放传输结构
    libusb_free_transfer(transfer);
 }
}

void callbackSend(struct libusb_transfer *transfer)
{
    if (transfer->status != LIBUSB_TRANSFER_COMPLETED) {

    //传输失败,可以尝试重新提交传输结构
    rc = libusb_submit_transfer(transfer);
    //判断是否传输成功
        if(rc < 0)
        {
        //释放传输结构
            libusb_free_transfer(transfer);
         }
    }

//传输完成
printf("LIBUSB_TRANSFER_COMPLETED");
//释放传输结构
    libusb_free_transfer(transfer);
    transfer = nullptr;
}

//异步接收

void QUniversalSerialBus::AsyncRead()
{
    int rc = 0;

//循环100次 提交100次传输结构,类似于提交了100个缓存等待接受,这样不会丢包
    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;
//填充传输结构
//transfer   传输结构
//dHand 设备句柄
//0x82 设备端点,这里是我使用的读数据端点
//buf 数据接受存放缓存
//64 缓存大小 此处我开辟的是64个字节大小的缓存
//callbackRevc 接收回调,接收完成、超时、失败等状态都会调用第回调
//this 用户数据 ,此处可以放任意数据,
//0超时时间此处写的是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;
            return;
        }

        qTransferList.append(transfer);
    }

}
void callbackRevc(struct libusb_transfer *transfer)
{
QUniversalSerialBus* qObj = nullptr;
//数据传输完成
    if (transfer->status == LIBUSB_TRANSFER_COMPLETED) {
        if(transfer->actual_length > 0)
        {
//有数据接受,这里我用的是Qt的语法,将接收到的数据通过对象传出去
   QByteArray s(reinterpret_cast<char*>(transfer->buffer),transfer->actual_length);
   qObj = reinterpret_cast<QUniversalSerialBus*>(transfer->user_data);
   emit qObj->revice(s);
        }
//再次提交传输用于接受
        int rv = libusb_submit_transfer(transfer);
        if (rv < 0)
        {
   printf("error libusb_submit_transfer : %s\n", libusb_strerror(libusb_error(rv)));
            libusb_cancel_transfer(transfer);   //异步取消之前提交传输
        }
}else if (transfer->status == LIBUSB_TRANSFER_CANCELLED) {//取消传输
//释放传输结构
        libusb_free_transfer(transfer);
    }else{
    }
}

以上就是异步IO的输入输出的用法,但是只有上面的步骤是完不成异步传输的,

异步传输还有一个特别重要的步骤:

//检测句柄事件

libusb_handle_events(context);

开启线程,不停的检查上下文环境变量,只有不停的调用此接口,设备传输才是能,才可以出发输入输出回调函数:

void QEventHandler::run()
{
    while(!stop)
    {
        libusb_handle_events(context);
    }
}
声明:本文内容由易百纳平台入驻作者撰写,文章观点仅代表作者本人,不代表易百纳立场。如有内容侵权或者其他问题,请联系本站进行删除。
红包 点赞 收藏 评论 打赏
评论
1个
内容存在敏感词
手气红包
  • fffzz16 2022-07-25 16:40:38
    回复
    前辈您好,我在复现您的代码时,在fill_bulk_transfer出现了回调函数出现类型不匹配这个问题? 希望您可以解答,万分感激
相关专栏
置顶时间设置
结束时间
删除原因
  • 广告/SPAM
  • 恶意灌水
  • 违规内容
  • 文不对题
  • 重复发帖
打赏作者
易百纳技术社区
小王子🤴
您的支持将鼓励我继续创作!
打赏金额:
¥1易百纳技术社区
¥5易百纳技术社区
¥10易百纳技术社区
¥50易百纳技术社区
¥100易百纳技术社区
支付方式:
微信支付
支付宝支付
易百纳技术社区微信支付
易百纳技术社区
打赏成功!

感谢您的打赏,如若您也想被打赏,可前往 发表专栏 哦~

举报反馈

举报类型

  • 内容涉黄/赌/毒
  • 内容侵权/抄袭
  • 政治相关
  • 涉嫌广告
  • 侮辱谩骂
  • 其他

详细说明

审核成功

发布时间设置
发布时间:
是否关联周任务-专栏模块

审核失败

失败原因
备注
拼手气红包 红包规则
祝福语
恭喜发财,大吉大利!
红包金额
红包最小金额不能低于5元
红包数量
红包数量范围10~50个
余额支付
当前余额:
可前往问答、专栏板块获取收益 去获取
取 消 确 定

小包子的红包

恭喜发财,大吉大利

已领取20/40,共1.6元 红包规则

    易百纳技术社区