The 'linusb' is one of the most used open source library for work with usb devices. It allow to make the basic usb data transfers operation in a little bit easier way compared to standard system calls. Here a short tutorial regarding how to use asynchronous bulk transfer.
Asynchronous transfer allow to launch the transfer command and return immediately, a callback function will be called once the data will be transfer/received completely. Using such transfer mode is quite simple, let's go to see a practical example. At first we have to initialize libusb library and look for the USB device we want to communicate to. Usually device is referred using the two values called Vendor ID and Product ID. The first is a unique number "assigned" to each hardware device producer and the second is a number reporting the device type and model.
libusb_device_handle *dev_handle = NULL;
libusb_device **list;
size_t count, i; // Initialize library
libusb_init(NULL); // Get list of USB devices currently connected
count = libusb_get_device_list(NULL, &list); for(i = 0; i < count; i++)
{
struct libusb_device_descriptor desc; libusb_get_device_descriptor(list[i], &desc); // Is our device?
if(desc.idVendor == 0x1234 && desc.idProduct == 0x5678)
{
// Open USB device and get handle
libusb_open(list[i], &dev_handle);
break;
}
} libusb_free_device_list(list, 1);
Now we have the handle to the USB device we want to communicate. The steps to performs an asynchronous bulk transfer are basically two, first prepare the structure with all the data for "instruct" USB controller to make request operation and then submit the data for start the transfer. Please note that the transfer direction (IN or OUT) is determined by the USB endpoint type we want to communicate to/from. An USB device usually provide some connections called Endpoint for allow data transfer between host and device. An Endpoint is usually marked as IN and OUT where, please note, in/out direction are from host point of view. This mean an endpoint marked as IN, for example, transfer data from device to host (usually the PC where the USB device is connected). Once clarified this point we can move to see the asynchronous transfer procedure as follow:
struct libusb_transfer *xfr;
unsigned char *data;
const unsigned int size = 1024; data = malloc(size);
xfr = libusb_alloc_transfer(0); libusb_fill_bulk_transfer(xfr,
dev_handle,
0x82, // Endpoint ID
data,
size,
callbackUSBTransferComplete,
NULL,
5000
); if(libusb_submit_transfer(xfr) < 0)
{
// Error
libusb_free_transfer(xfr);
free(data);
}
Detailed explanation about each params used can be found at official documentation here. In this example we prepare for a bulk transfer from the device using endpoint 0x82. Data size to transfer are 1024 bytes and timeout is 5000 milliseconds. callbackUSBTransferComplete is the name of the function automatically called when the transfer will be completed. Please note here the function will be called also in case of errors. It's necessary to check params returned  as follow:
void callbackUSBTransferComplete(struct libusb_transfer *xfr)
{
switch(xfr->status)
{
case LIBUSB_TRANSFER_COMPLETED:
// Success here, data transfered are inside
// xfr->buffer
// and the length is
// xfr->actual_length
break;
case LIBUSB_TRANSFER_CANCELLED:
case LIBUSB_TRANSFER_NO_DEVICE:
case LIBUSB_TRANSFER_TIMED_OUT:
case LIBUSB_TRANSFER_ERROR:
case LIBUSB_TRANSFER_STALL:
case LIBUSB_TRANSFER_OVERFLOW:
// Various type of errors here
break;
}
}
Now the transfer code seem complete. However an additional step have to be made. What is not very clear here (at least it wasn't clear for me in the past) is that the "internal USB engine" who make the transfer and automatically call the callback function is not in a separate thread working in parallel but, for have it working as expected, need to be "keep alive" by continuously calling the function libusb_handle_events as follow:
while(1)
{
if(libusb_handle_events(NULL) != LIBUSB_SUCCESS) break;
}
As you can note this is an infinite loop with minimum of error check used just for example purpose. In case you need to manage additional error conditions and provide some way to exit from loop if your software require it. This small snippet is only to explain that if you don't continuously call the libusb_handle_events function your callback function will never be called also if the USB transfer was completed (and this can result in many hours lost insearch for the problem... ^_^).

转-Asynchronous bulk transfer using libusb的更多相关文章

  1. libusb 源码阅读

    libusb_init(NULL), 如果传入一个NULL, 则libusb 内部会有一个 usbi_default_context 变量在内部保存上下文. 这样以后调用 libusb 函数时可以不指 ...

  2. bulkTransfer通讯必须注意的问题:bulk buffer size(16K)

    Android USB host与HID使用bulkTransfer通讯接收和发送的数据长度不会超过16384,这个问题困扰了我很长一段时间,终于发现问题所在,不是出在我的程序设计,也不是硬件的发送/ ...

  3. C#开发usb通知之bulk传输

    usb通信分为4种传输方式,下位机通信协议用的是块传输,也就是bulk传输,C#下实现的usb通信使用的是开源的LibUsbDotNet,主要的就是需要在C#中添加LibUsbDotNet.dll引用 ...

  4. redis.conf配置详细解析

    # redis 配置文件示例 # 当你需要为某个配置项指定内存大小的时候,必须要带上单位, # 通常的格式就是 1k 5gb 4m 等酱紫: # # 1k => 1000 bytes # 1kb ...

  5. redis配置详解

    ##redis配置详解 # Redis configuration file example. # # Note that in order to read the configuration fil ...

  6. redis.conf配置详细翻译解析

    # redis 配置文件示例 # 当你需要为某个配置项指定内存大小的时候,必须要带上单位, # 通常的格式就是 1k 5gb 4m 等酱紫: # # 1k => 1000 bytes # 1kb ...

  7. Redis 配置文件

    # Redis configuration file example. # # Note that in order to read the configuration file, Redis mus ...

  8. Redis 配置文件详解

    # Redis 配置文件 # 当配置中需要配置内存大小时,可以使用 1k, 5GB, 4M 等类似的格式,其转换方式如下(不区分大小写)## 1k => 1000 bytes# 1kb => ...

  9. Redis基本配置

    # redis 配置文件示例 # 当你需要为某个配置项指定内存大小的时候,必须要带上单位, # 通常的格式就是 1k 5gb 4m 等酱紫: # # 1k => 1000 bytes # 1kb ...

随机推荐

  1. python记录_day01 初始

    一.python介绍 python的创始人为吉多·范罗苏姆(Guido van Rossum),人称龟叔.目前python主要应用于web开发.云计算.科学计算.人工智能.系统运维.金融.图形GUI等 ...

  2. 前端VUE框架

    一.什么是VUE?  它是一个构建用户界面的JAVASCRIPt框架  vue不关心你页面上的是什么标签,它操作的是变量或属性 为什么要使用VUE? 在前后端分离的时候,后端只返回json数据,再没有 ...

  3. leetcode-algorithms-25 Reverse Nodes in k-Group

    leetcode-algorithms-25 Reverse Nodes in k-Group Given a linked list, reverse the nodes of a linked l ...

  4. [contest 782] 9.7

    [contest 782] 9.7 - XJOI 个人觉得温暖题啊,,,可是卡毛空间呀!!! T1 传送

  5. button disable and enable

    1. disable <button id="buttonId" disabled>......</button> $("#buttonId&qu ...

  6. webapp检测安卓app是否安装并launch

    1. cordova插件 1)查看所有已安装的安卓app https://www.npmjs.com/package/cordova-plugin-packagemanager A simple pl ...

  7. 【转】js 对象按照键值(不分区大小写)排序,生成签名方法

    客户需求小程序端用js生成签名,我们按照要求一步一步解决,并且将请求方法封装到一个utils.js里: 第一步:对关联数组按照键名做正序排序. 第二步:拼接字符串 第三步:将拼接的字符串加上私钥 第四 ...

  8. Windows添加用户和组命令

    查看当前存在用户: net user 查看当前用户组: net localgroup 添加用户(以添加用户ls密码abcd1234为例): net user ls abcd1234 /add 添加用户 ...

  9. python格式化日期

    #!/usr/bin/python # -*- coding: UTF-8 -*- import time import calendar """ 时间元组(年.月.日. ...

  10. js之DOM元素遍历

    对于元素间的空格,IE9之前的版本不会返回文本节点,而且他所有浏览器都会返回文本节点.这样就导致 使用childNodes和firstChild等属性时的行为不一致.从而有了Element Trave ...