欢迎光临
我们一直在努力

windows 驱动实例分析系列: libusb驱动分析-examples篇(下)

实现篇(基于 examples 目录)—— 技术细节、编译与使用

1. 编程接口与 API 使用详解
1.1 初始化与设备枚举

所有示例均遵循 libusb-win32 标准流程:

usb_init();
usb_find_busses();
usb_find_devices();

usb_init 初始化内部状态,usb_find_busses 扫描总线,usb_find_devices 枚举设备并填充设备描述符。随后可通过 usb_get_busses() 遍历链表。

1.2 设备打开与配置
  • – 通过遍历 usb_bus->devices 匹配 vid/pid,调用 usb_open(dev) 获得句柄。
  • – 必须调用 usb_set_configuration 设置配置(通常为 1),然后 usb_claim_interface 声明接口,才能进行数据传输。
  • – 可选 usb_set_altinterface 切换备用设置。
1.3 同步传输 API

直接调用 usb_bulk_read/write、usb_interrupt_read/write、usb_control_msg,这些函数阻塞直到传输完成或超时。返回值是实际传输字节数,负数表示错误。

1.4 异步传输 API(重点)

异步传输分四步:

  • 1. 创建上下文:根据端点类型调用 usb_bulk_setup_async、usb_interrupt_setup_async 或 usb_isochronous_setup_async,传入设备句柄和端点地址,返回 context 指针。
  • 2. 提交传输:usb_submit_async(context, buffer, length) 立即返回,传输在后台进行。
  • 3. 等待完成:usb_reap_async(context, timeout) 阻塞等待,若超时则自动取消传输;usb_reap_async_nocancel 不取消,仅等待。
  • 4. 释放上下文:usb_free_async(&context) 清理资源。

在 benchmark.c 的 TransferAsync 函数中,实现了循环提交和等待的流水线,并且每个上下文可复用(多次 submit/reap)。注意必须检查 InUse 标志避免重复提交。

1.5 控制传输

使用 usb_control_msg 发送标准或厂商请求。benchmark.c 通过它设置测试模式(SET_TEST/GET_TEST),传输 1 字节数据。bulk.c 也使用同样方式选择测试类型。

1.6 端点复位与错误恢复

当传输错误时,调用 usb_resetep(dev, ep) 清除端点停止状态,确保后续传输正常。

2. 多线程实现技术
  • – 使用 Windows API CreateThread 创建工作线程,传递传输参数结构。
  • – 主线程通过全局标志(IsCancelled)控制线程退出,线程循环中检查该标志。
  • – 统计信息更新使用 EnterCriticalSection/LeaveCriticalSection 保护,避免数据不一致。
  • – 主线程使用 GetTickCount 计算时间间隔,实现速率统计(字节/秒)。
3. 内存管理与缓冲区布局

benchmark.c 在结构体 BENCHMARK_TRANSFER_PARAM 末尾使用零长度数组 BYTE Buffer[0] 作为灵活数组成员,实际分配时一次性分配结构体 + 所有传输缓冲区(BufferCount * BufferSize),避免了多次 malloc 和碎片。每个异步句柄的 Data 指针指向相应的偏移位置。

4. 资源加载与字符串获取
  • – 帮助文本通过资源文件(benchmark_rc.rc)嵌入,运行时使用 FindResource、LoadResource 读取,并输出到标准错误(控制台)或忽略。
  • – 设备字符串(制造商、产品、序列号)通过 usb_get_string_simple 获取,该函数内部处理语言 ID 和 Unicode 转换。
5. 编译与构建

examples 目录下的源代码与主库共用头文件 lusb0_usb.h,编译时需要链接 libusb0.lib(或动态加载 libusb0.dll)。Makefile 在根目录定义了相应的编译规则:

  • – 使用 gcc 或 MinGW 编译 benchmark.c 和 bulk.c,链接 -lusb。

  • – 对于 Windows GUI 版本(如 testlibusb_win),需链接 -mwindows 和额外库。

  • – 资源文件(*.rc)通过 windres 处理。

6. Inno Setup 脚本实现细节
  • – 使用 [Files] 段复制驱动文件,通过 Check 参数根据 IsX64、IsX86 等函数选择正确的 DLL 版本。
  • – 使用 [Run] 段调用 rundll32 执行驱动安装,参数格式:`libusb0.dll,usb_install_driver_np_rundll {app}\\driver\\<your_inf>.inf`。
  • – 注意:rundll32 要求导出函数遵循特定调用约定(CALLBACK),libusb0.dll 已提供 usb_install_driver_np_rundll 等函数。
  • – 脚本还示范了如何处理系统 INF(如 input.inf)以绕过数字签名,但强烈建议仅在明确需要时使用。
7. 性能优化技术
  • – 异步流水线:通过并发多个传输隐藏延迟,提高吞吐量。
  • – 缓冲区大小对齐:要求 BufferSize 是端点最大包大小的整数倍,避免 USB 协议层面的拆分开销。
  • – 线程优先级调整:可将工作线程设为高于普通优先级,保证实时性。
  • – 使用 usb_reap_async_nocancel 避免超时取消额外开销(在流水线中,等待完成但不取消,由调用者管理取消)。
8. 调试与日志

示例中定义了 LOG 宏,输出到控制台。通过 usb_log_set_level(255) 启用库内部详细日志(需库编译时支持)。用户也可通过 usb_set_debug 控制日志级别。

9. 平台兼容性考虑

  • – 示例使用 Windows 专用 API(如 CreateThread、GetTickCount、临界区),因此仅适用于 Windows 平台。
  • – 但在 API 层面,libusb-win32 保持与跨平台 libusb 兼容,因此核心传输代码可移植。
10. 总结

examples 目录的代码充分利用了 libusb-win32 提供的同步/异步接口,展示了如何构建高性能、可配置的 USB 测试工具。同时,它们也作为最佳实践范例,指导开发者正确处理资源、并发和错误,并提供了完整的驱动部署解决方案。开发者可以直接基于这些示例进行二次开发,加速产品原型验证。

赞(0)
未经允许不得转载:171主机测评 » windows 驱动实例分析系列: libusb驱动分析-examples篇(下)
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址