四联光电智能照明论坛

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 3126|回复: 3
打印 上一主题 下一主题

libusb异步中断传输使用说明

[复制链接]
  • TA的每日心情
    开心
    2018-12-28 16:25
  • 817

    主题

    1556

    帖子

    1万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    14941
    跳转到指定楼层
    楼主
    发表于 2016-12-5 15:14:49 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
    基于libusbx-1.0.18-rc1,libusbx现已重新merage到libusb。
    1. 初始化
    使用libusb_init初始化libusb,如果是单设备通信,ctx参数可以传NULL,表示使用默认Context.
    2. 注册hotplug事件侦听
    从1.0.16开始,libusb支持hotplug事件侦听,可以使用接口libusb_hotplug_register_callback注册基于以下几种filter的回调函数:
    libusb_hotplug_event: 分LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED和 LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT俩种;
    vendor_id:只有指定的vendor id匹配的设备能够触发回调,或设置LIBUSB_HOTPLUG_MATCH_ANY,使得任意vendor id的设备都能触发回调;
    product_id:只有指定的product id匹配的设备能够触发回调,或设置LIBUSB_HOTPLUG_MATCH_ANY,使得任意product id的设备都能触发回调;
    dev_class:只有指定的device class匹配的设备能够触发回调,或设置LIBUSB_HOTPLUG_MATCH_ANY,使得任意device class的设备都能触发回调。
    这几种filter之间可以以“与”的方式组合一起发生作用。
    3. 获取file descriptors
    使用libusb_get_pollfds可以取得当前context的fd列表,之后可以将这些fd放到main events loop中进行poll操作。可以参考《基于glib的单线程多事件源处理》这篇文章,使用GSource来实现。一旦检测到有事件发生,要使用libusb_handle_events_completed,触发后面提到的事件处理函数。还需要使用libusb_set_pollfd_notifiers注册俩个回调函数,用来处理设备接入或移除后,fd列表发生的变化。
    4. 设备接入
    设备接入后,会触发libusb_set_pollfd_notifiers注册的回调函数,通知应用程序有新增的fd,这时需要将新增的fd添加到poll的队列中。同时,libusb还会触发libusb_hotplug_register_callback注册的回调函数,通知应用程序有设备接入。在hotplug的回调函数中,需要基于传入的libusb_device,调用libusb_open接口,创建一个基于此设备的handle。之后根据需要,使用libusb_reset_device重置此设备。对于一些linux标准支持的设备(如HID设备),可能需要使用libusb_detach_kernel_driver,或libusb_set_auto_detach_kernel_driver,将kernel提供的驱动卸载掉,否则会与libusb的通信产生冲突。对于支持多configuration的设备,还需要使用libusb_set_configuration,选择要使用的configuration number。之后,调用libusb_claim_interface,选择要使用的interface。
    5. 建立通信
    调用libusb_alloc_transfer创建一个空的transfer数据结构,使用libusb_fill_interrupt_transfer填充这个数据结构,参数包括:通信基于的endpoint number,数据到达的buffer及大小,数据到达后的回调函数等。之后调用libusb_submit_transfer,将这个transfer提交给libusb侦听数据到达事件。
    6. 数据到达
    数据到达后,会触发回调函数,传入之前的transfer数据结构。首先要判断transfer中的status字段是否是LIBUSB_TRANSFER_COMPLETED,否则执行相应的异常处理。对于传输完成的数据,可以到transfer中的buffer字段获取,数据的长度使用actual_length表示。处理完成后,要使用libusb_submit_transfer重新提交这个transfer。
    到此,基于libusb的异步通信建立完毕,libusb异步通信对于同步通信来说有更好的性能,且不需要多线程支持,程序执行的时序可以得到更好的控制。
  • TA的每日心情
    开心
    2018-12-28 16:25
  • 817

    主题

    1556

    帖子

    1万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    14941
    沙发
     楼主| 发表于 2016-12-5 15:27:01 | 只看该作者
    1. static int count = 0;
    2. void hotplug_callback(struct libusb_context *ctx, struct libusb_device *dev,
    3.                       libusb_hotplug_event event, void *user_data) {
    4.   static libusb_device_handle *handle = NULL;
    5.   struct libusb_device_descriptor desc;
    6.   int rc;
    7.   (void)libusb_get_device_descriptor(dev, &desc);
    8.   if (LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED == event) {
    9.     rc = libusb_open(dev, &handle);
    10.     if (LIBUSB_SUCCESS != rc) {
    11.       printf("Could not open USB device\n");
    12.     }
    13.   } else if (LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT == event) {
    14.     if (handle) {
    15.       libusb_close(handle);
    16.       handle = NULL;
    17.     }
    18.   } else {
    19.     printf("Unhandled event %d\n", event);
    20.   }
    21.   count++;
    22. }
    23. int main (void) {
    24.   libusb_hotplug_callback callback;
    25.   libusb_init(NULL);
    26.   libusb_hotplug_prepare_callback(&callback, NULL, LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED |
    27.                                   LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT, 0, 0x045a, 0x5005,
    28.                                   LIBUSB_HOTPLUG_CLASS_ANY, hotplug_callback, NULL);
    29.   libusb_hotplug_register_callback(&callback);
    30.   while (count < 2) {
    31.     usleep(10000);
    32.   }
    33.   libusb_hotplug_deregister_callback(&callback);
    34.   libusb_exit(NULL);
    35.   return 0;
    36. }
    复制代码
  • TA的每日心情
    开心
    2018-11-9 08:52
  • 241

    主题

    691

    帖子

    7652

    积分

    论坛元老

    Rank: 8Rank: 8

    积分
    7652
    板凳
    发表于 2016-12-5 16:50:22 | 只看该作者
  • TA的每日心情
    开心
    2018-11-9 08:52
  • 241

    主题

    691

    帖子

    7652

    积分

    论坛元老

    Rank: 8Rank: 8

    积分
    7652
    地板
    发表于 2016-12-5 16:53:51 | 只看该作者
    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|Archiver|手机版|小黑屋|Silian Lighting+ ( 蜀ICP备14004521号-1 )

    GMT+8, 2024-5-15 15:33 , Processed in 1.078125 second(s), 22 queries .

    Powered by Discuz! X3.2

    © 2001-2013 Comsenz Inc.

    快速回复 返回顶部 返回列表