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(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(transfer->buffer),transfer->actual_length);
qObj = reinterpret_cast(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);
}
}
本文介绍了libusb在Linux上的异步传输使用,包括异步写入和读取的详细步骤,以及如何通过libusb_handle_events()持续检查设备事件以确保异步传输的正常进行。
2万+

被折叠的 条评论
为什么被折叠?



