简单说明
本文使用的libusb版本是1.0.22
github地址:https://github.com/libusb/libusb
老版本的需要安装winusb/libusbk/libwin32(三选一)驱动程序,才能和usb设备进行通讯。驱动生成程序可以从这里下载:
https://download.youkuaiyun.com/download/lhangtk/10671424
有个c++扩展版本,使用起来很方便,但是这个是基于老版本的libusb实现,是需要装驱动的
github地址:https://github.com/zarthcode/Libusbpp
USB传输方式
libusb定义了5中传输类型,分别是:
控制传输(LIBUSB_TRANSFER_TYPE_CONTROL=0)
同步传输(LIBUSB_TRANSFER_TYPE_ISOCHRONOUS = 1)
批量传输(LIBUSB_TRANSFER_TYPE_BULK = 2)
中断传输(LIBUSB_TRANSFER_TYPE_INTERRUPT = 3)
批量流传输(LIBUSB_TRANSFER_TYPE_BULK_STREAM = 4)
说明参考:https://blog.youkuaiyun.com/myarrow/article/details/8484113
每个端点(endpoint)支持的IO类型和传输类型不一样,根据实际情况选取传输类型。
常用方法说明
重点说明使用到的几个方法,详细的可以参考官方文档(英文)
官方文档:http://libusb.sourceforge.net/api-1.0/
初始化和退出
//初始化,所有的libusb操作都要在此方法之后,返回0表示成功,-1异常
int LIBUSB_CALL libusb_init(libusb_context **ctx);
//卸载libusb,之后的libusb操作都会异常
void LIBUSB_CALL libusb_exit(libusb_context *ctx);
所有的libusb操作都要包括在这两个方法之间,一般情况下ctx参数为NULL。
说明一下libusb_context
结构体,是由libusb_init创建并由libusb_exit销毁,用于隔离用户操作,类似于会话。当一个被销毁时不至于影响到另外一个的操作。只有单个用户时可以为NULL,使用默认的context。
打开设备
/**
* 根据设备的vid和pid打开设备,pid和vid可以通过设备管理器查看
*
* @param ctx libusb_context
* @param vendor_id 设备vid
* @param product_id 设备pid
*
* @retrun 返回设备句柄,失败返回null。后续的设备读写,获取信息都依赖这个句柄
*/
libusb_device_handle * LIBUSB_CALL libusb_open_device_with_vid_pid(
libusb_context *ctx, uint16_t vendor_id, uint16_t product_id);
//关闭设备,释放设备句柄
void LIBUSB_CALL libusb_close(libusb_device_handle *dev_handle);
设备信息
/**
* 获取设备信息
*
*
*/
int LIBUSB_CALL libusb_get_device_descriptor(libusb_device *dev,
struct libusb_device_descriptor *desc);
/**
* 获取设备配置信息
* @param dev 设备句柄
* @param config_index 一个设备可能有多个配置信息,一般设置为0
* @param config 【输出参数】 设备配置信息指针的引用
*
* @return 成功返回0
*/
int LIBUSB_CALL libusb_get_config_descriptor(libusb_device *dev,
uint8_t config_index, struct libusb_config_descriptor **config);
//释放设备配置信息
void LIBUSB_CALL libusb_free_config_descriptor(
struct libusb_config_descriptor *config);
结构体说明,详细看官网吧
libusb_endpoint_descriptor
端点信息:描述传输类型,读/写端口,传输包大小等
libusb_interface_descriptor
接口信息:存放端点列表,
libusb_config_descriptor
配置信息:存放接口列表
libusb_device_descriptor
设备信息:描述配置数,vid,pid,序列号之类
声明接口
/**
* 声明接口,声明接口之后才能在基于该接口的端点(endpoint)读写数据
* @param dev_handle 设备句柄
* @param interface_number 接口号
* @return 成功返回0
*/
int LIBUSB_CALL libusb_claim_interface(libusb_device_handle *dev_handle, int interface_number);
/**
* 释放接口
* @param dev_handle 设备句柄
* @param interface_number 接口号
* @return 成功返回0
*/
int LIBUSB_CALL libusb_release_interface(libusb_device_handle *dev_handle,int interface_number);
读取数据
这里以同步传输的中断传输为例
/**
* 同步传输,中断传输。读/写依赖端口类型
* 在超时时间内一旦完成读/写一个数据包就返回,超出超时时间返回超时
*
* @param dev_handle 设备句柄
* @param endpoint 读写的端口,端口所在的接口需要声明,
* 端口的读写类型需要是interrupt
* @param data 写数据时的数据输入数组,读数据时的输出数组
* @param length 写数据时的数据长度,读数据时最大报文长度
* @param transferred 【输出值】实际传输的数据大小
* @param timeout 超时时间(毫秒ms)
* @return 成功返回0,其他异常代码
*/
int libusb_interrupt_transfer (
struct libusb_device_handle * dev_handle,
unsigned char endpoint,
unsigned char * data,
int length,
int * transferred,
unsigned int timeout
)