(翻译)libusb-api-1.0

这里先记录一点usb的基础知识:
USB HOST(主机)、USB HID(usb设备)
主机通过各种描述符来识别设备,有设备描述符,配置描述符,接口描述符,端点描述符,字符描述符,报告描述符等。USB描述符就像是USB的“身份证”一样,详细记录这外围设备的相关的一切信息。
usb设备是通过

设备描述符层级:设备(device)->配置(configuration)->接口(interface)->(设置)->端点(endpoint)
一个设备有一个设备描述符,多个配置描述符,一个配置有多个接口描述符,一个接口有多个端点描述符。
设备就是指usb设备;配置可以理解成高速设备还是低速设备;接口就是接的是USB存储设备还是USB视频设备。

一般USB HID可能提供一种或多种配置(例如高速、低速),由USB Host选择一个支持的配置才能使设备正常工作,这些配置对设备可执行的操作是相互排斥的;USB HID以一系列接口的形式公开其功能(例如音频接口、键盘接口、旋钮接口);每个接口包含一个或多个备用设置,默认情况下,选择某个配置会激活该配置中每个接口的首个备用配置;每个备用设置由一组端点组成,USB HID和USB Host实际是由端点进行通信的,每个端点独立的完成I | O请求,通常情况一个端点只负责I或O,一个端点组成一个I/O管道。

参考:
MSDN - 选择 USB 驱动程序中的 USB 配置


文章目录


1. 库初始化/取消初始化

此部分将会详细描述如何libusb初始化和取消初始化。初始化函数必须在使用其他任一libusb函数之前执行,相同的,任何libusb函数不能在执行取消初始化函数之后调用。

1.1 数据结构

// lisbusb版本信息
struct libusb_version

1.2 类型定义

typedef struct libusb_context libusb_context
libusb_context对象代表一个会话,两个独立的libusb_context可以独立的使用libusb库。两个libusb_context直接不会互相影响。

libusb_context由libusb_init()函数创建,由libusb_exit()释放。如果程序保证只由一个libusb用户,在需要传入libusb_context对象为参数的函数中赋值为NULL,将会使用默认的libusb_context。

1.3 枚举

enum libusb_log_level
libusb日志输出等级枚举
enum libusb_log_level {
LIBUSB_LOG_LEVEL_NONE = 0, // 不输出日志
LIBUSB_LOG_LEVEL_ERROR = 1, // 只输出error日志到stderr
LIBUSB_LOG_LEVEL_WARNING = 2, // 输出warning等级及以上日志(warning/error)到stderr
LIBUSB_LOG_LEVEL_INFO = 3, // 输出info/warning/error日志到stderr
LIBUSB_LOG_LEVEL_DEBUG =4 // 输出全部等级日志到stderr
}

enum libusb_option
libusb操作枚举
enum libusb_option {
LIBUSB_OPTION_LOG_LEVEL,
LIBUSB_OPTION_USE_USBDK
}
libusb_option是libusb_set_option()可用的选项值

LIBUSB_OPTION_LOG_LEVEL
设置日志输出等级,默认等级是LIBUSB_LOG_LEVEL_NONE,如果要提高日志输出等级,请确定应用程序的stderr输出文件描述符没有关闭。

建议使用LIBUSB_LOG_LEVEL_WARNING,libusb在大多数时候对日志的输出都是很保守的,只有在出现错误或者其他奇怪的情况才会输出日志。

如果在libusb初始化后设置了LIBUSB_DEBUG环境变量,再设置LIBUSB_OPTION_LOG_LEVEL将不会生效。

如果libusb被编译成不打印任何日志,此函数也将无效,将不会由任何日志输出。

如果libusb被编译成打印debug日志,此函数也不会生肖,所有等级的日志都将会被输出。

LIBUSB_OPTION_USE_USBDK
此选项必须在调用libusb_init()之后立即设置,否则可能不会生效。此选项只在Windows上有效。

1.4 函数/功能/方法

void libusb_set_debug(libusb_context *ctx,int level)

推荐libusb_set_option()使用LIBUSB_OPTION_LOG_LEVEL选项替代libusb_set_debug。

int libusb_set_option(libusb_context *ctx,enum libusb_option option,…)

设置库选项,使用此函数配置库的指定选项,有些选项需要提供一个或多个参数,详细参数要求请参考指定选项的文档。

在1.0.22,LIBUSB_API_VERSION >=0x01000106版本以后:
参数:
ctx 需要操作的libusb_context会话
option 需要设置的选项
… 指定选项需要的参数
返回值:
LIBUSB_SUCCESS 操作成功
LIBUSB_ERROR_INVALID_PARAM 非法参数,参数无效
LIBUSB_ERROR_NOT_SUPPORTED 选项合法,但是此平台不支持

int libusb_init(libusb_context **context)

初始化libusb,此函数必须在调用其他任何函数之前调用。如果参数context为NULL,将会创建一个默认的context。如果已经存在一个默认的context,调用此函数将不会创建新的默认context,而是复用此默认context。
参数:
context 可选的输出参数,返回值为0时有效。
返回值:
0 成功;其他 失败,参考LIBUSB_ERROR代码

void libusb_exit(struct libusb_context *ctx)

libusb取消初始化
在程序终止之前需调用此函数关闭所有打开的设备。
参数:
ctx 取消初始化的会话,默认的context为NULL


2. 设备处理和枚举

功能:

  • 枚举当前连接到系统的USB设备
  • 选择软件需要操作的设备
  • 打开和关闭选中的设备

接下来的描述确实使事情听起来比实际上更复杂。以下的函数调用顺序将会适合几乎所有的场景,而且不需要你对资源管理策略有很深入的了解。

// 发现设备
libusb_device **list;
libusb_device *found =NULL;
ssize_t cnt = libusb_get_device_list(NULL,&list);
ssize_t i = 0;
int err = 0;
if (cnt < 0)
	error();
for (i = 0; i < cnt; i++) {
	libusb_device *device = list[i];
	if (is_interesting(device)) {
		found = device;
		break;
	}
}
if (found) {
	libusb_device_handle *handle;
	err = libusb_open(found, &handle);
	if(err)
		error();
	// ...
}
libusb_free_device_list(list, 1);

有两个重点:

- 调用libusb_free_device_list()解除设备引用
- 需要在释放设备列表并且解除设备引用之前打开设备

如果最后获取到了一个设备句柄,你可以继续执行设备I/O。

设备和设备句柄

libusb有一个USB设备的概念,由libusb_device表示一个不透明的概念。device代表一个当前或之前与系统建立连接的USB设备。使用对设备的引用,你可以确定某些关于device的信息(例如:可以读取设备描述信息)。

libusb_get_device_list()函数可以用于获取当前连接到系统的设备列表,这被称为设备发现。

仅仅有设备的引用不意味着设备一定可用。设备可能移除、你可能没有权限操作此设备,或者其他程序或其他正在使用此设备。

当你找到一个你想要操作的设备,你必须使用libusb_open()函数请求libusb打开设备。假设打开成功,libusb将会返回一个设备句柄(libusb_device_handle 指针)。所有真实I/O操作都是在句柄上而不是原始设备指针。

设备发现和引用计数

设备发现(调用libusb_get_device_list())返回一个新分配的设备列表。当你使用完设备列表后必须释放掉。libusb也需要知道什么时候可以释放设备列表。
为了处理这个问题,libusb提供两个独立的选项:

- 释放设备列表的函数
- 设备内置的引用计数系统

所有libusb_get_device_list()函数列出的新设备的引用计数值都是1。你可以使用libusb_ref_device()和libusb_unref_device()增加或减少引用计数。当设备的引用计数为0时将会被销毁。

根据以上信息,打开设备的过程如下:

  1. 使用libusb_get_device_list()发现设备
  2. 调用libusb_open()选中想要操作的设备
  3. 解除所有被发现的设备列表中的设备
  4. 释放被发现的设备列表

顺序非常重要,一定不能在打开设备之前解除引用,因为解除引用后将会释放设备。

libusb_free_device_list()函数包含一个可选的参数解除所有在设备列表中的设备引用,这结合了上面的步骤3和4.

libusb_open()实际上增加了对设备的引用。设备通过libusb_get_device()获得句柄保持可用。在libusb_close()时删除引用。

2.1 类型定义

typedef struct libusb_device libusb_device

表示在系统中检测到的USB设备。这是一个不透明的类型,通常是从libusb_get_device_list()获得的一个指针。

设备可以执行一些操作,但是必须使用libusb_open()获取到设备句柄后才能执行I/O。

设备使用libusb_ref_device()和libusb_unref_device()计算引用,当引用计数为0时被释放。由libusb_get_device_list()获取到的新设备引用计数为1,libusb_free_device_list()可选的减少设备列表中设备的引用计数。libusb_open()也会增加引用,需要libusb_close()来销毁。

typedef struct libusb_device_handle libusb_device_handle

表示USB设备句柄。从libusb_open()获得的不透明类型指针。设备句柄用于执行I/O和其他操作。执行完后需要调用libusb_close()释放。

2.2 枚举

enum libusb_speed

USB设备速度代码。指示设备的运行速度。

Enumerator
LIBUSB_SPEED_UNKNOWN
LIBUSB_SPEED_LOW
LIBUSB_SPEED_FULL
LIBUSB_SPEED_HIGH
LIBUSB_SPEED_SUPER
LIBUSB_SPEED_SUPER_PLUS

2.3 函数

ssize_t libusb_get_device_list(libusb_context *ctx , libusb_device **list)

获取当前连接到系统的USB设备,这是查找目标设备的入口。

执行完此函数后,你需要解除所有设备的引用,然后使用libusb_free_device_list()释放list设备列表。一定要在打开你需要的设备后再解除所有设备引用。

参数:
ctx
list 输出的设备列表,需要调用libusb_free_device_list()释放
返回值:
获取到的设备数,或libusb_error错误代码

void libusb_free_device_list(libusb_device ** list , int unref_devices)

释放libusb_get_device_list()获取到的设备。如果设置了unref_devices参数,列表中的每一个设备的引用计数都将减1.

参数:
list 需要释放的设备列表
unref_devices 是否释放列表中的设备

uint8_t libusb_get_bus_number( libusb_device * dev)

获取设备连接的总线编号。

参数:
dev 设备
返回值:
总线编号

uint8_t libusb_get_port_number ( libusb_device * dev )

获取设备连接的端口号。
参数:
dev 设备
返回值:
端口号(0 设备不可用)

int libusb_get_port_numbers (libusb_device * dev,uint8_t * port_numbers,int ort_numbers_len )

从root获取指定设备的所有端口号。
自版本1.0.16,LIBUSB_API_VERSION >= 0x01000102
参数:
dev 设备
port_numbers 端口号列表
port_numbers_len 最大序列长度,USB 3.0最大深度限制为7
返回值:
端口号个数,或者 LIBUSB_ERROR_OVERFLOW

libusb_device* libusb_get_parent (libusb_device * dev )

获取指定设备的父级设备。
必须在调用libusb_get_device_list()之后调用此方法,且在调用libusb_free_device_list()之前访问父级设备。

uint8_t libusb_get_device_address(libusb_device * dev )

获取指定设备在总线上的地址。

int libusb_get_device_speed (libusb_device * dev )

获取设备协商的连接速度。

int libusb_get_max_packet_size(libusb_device * dev,unsigned char endpoint )

用于获取设备指定端点的wMaxPacketSize值。

int libusb_get_max_iso_packet_size(libusb_device * dev,unsigned char endpoint )

获取设备指定端点一帧的封包大小最大值。

libusb_device* libusb_ref_device( libusb_device * dev)

增加设备引用计数。

void libusb_unref_device(libusb_device *dev)

减少设备引用计数,当引用计数为0则销毁设备。

int libusb_open (libusb_device * dev, libusb_device_handle ** dev_handle )

打开设备并获取设备句柄。

libusb_device_handle* libusb_open_device_with_vid_pid(libusb_context * ctx,uint16_t vendor_id,uint16_t product_id )

通过pid和vid打开设备,并得到设备句柄。

void libusb_close(libusb_device_handle * dev_handle)

关闭设备句柄,在程序关闭之前必须调用此函数关闭所有打开的设备。此函数将会销毁libusb_open()获取的设备引用。
非阻塞函数。

libusb_device* libusb_get_device (libusb_device_handle * dev_handle)

通过设备句柄获取底层设备。

int libusb_get_configuration(libusb_device_handle * dev_handle,int * config )

获取设备的bConfigurationValue 值。

int libusb_set_configuration(libusb_device_handle * dev_handle,int configuration)

激活一个USB配置,在声明接口和执行操作之前,确认激活的是正确的usb配置。
如果你选的配置已经在设备上激活,此调用将会是一个轻量级的操作,重置相关usb设备的状态。
或者你可以先调用libusb_release_interface(),记住如果你这样做请确保dev的auto_detach_kernel_driver值为0,否则在你释放接口(interface)时,内核驱动将会重新附加。
如果其他应用程序或驱动声明了接口,你不能更改或重置usb设备配置。
你应该使这个函数而不是使用自己定义的SET_CONFIGURATION来控制请求。因为底层操作系统需要指定合适发生了改变。
这是一个阻塞的函数。

参数:
   ~~    dev_handle 设备句柄
   ~~    configuration 想要激活的配置的值,或-1(设为未配置状态)

返回值:
   ~~    0 成功
   ~~    LIBUSB_ERROR_NOT_FOUND 配置不存在
   ~~    LIBUSB_ERROR_BUSY 已经声明接口
   ~~    LIBUSB_ERROR_NO_DEVICE 设备断开连接
   ~~    其他LIBUSB_ERROR代码

int libusb_claim_interface(libusb_device_handle * dev_handle,int interface_number)

在给定设备句柄上声明接口。
在操作I/O或其他端点的时候必须先声明接口。
声明已经声明的接口时合法的,函数会返回0但不做任何操作。
如果dev设置auto_detach_kernel_driver值为1,如果有必要内核驱动将会被分离,如果分离失败会返回error。
声明接口时一个单纯的逻辑操作;不会通过总线发送任何请求。接口声明用于告知底层操作系统你的程序想要取得此接口的所有权。
这是一个非阻塞的函数。

参数:
   ~~    dev_handle 设备句柄
   ~~    interface_number 想要声明的接口号bInterfaceNumber
返回值:
   ~~    0 成功
   ~~    LIBUSB_ERROR_NOT_FOUND 接口不存在
   ~~    LIBUSB_ERROR_BUSY 接口忙,被其他程序或驱动声明
   ~~    LIBUSB_ERROR_NO_DEVICE 设备断开连接
   ~~    LIBUSB_ERROR 失败

int libusb_release_interface (libusb_device_handle * dev_handle,int interface_number)

释放libusb_claim_interface()声明的接口。
在关闭设备句柄前应该释放所有声明的接口。
函数将会发送一个SET_INTERFACE控制请求给设备,为第一备用设置重置接口状态。
此函数是阻塞函数。
如果dev的auto_detach_kernel_driver设置为1,当接口被释放后内核将会被自动附加。

参数:
   ~~    dev_handle 设备句柄
   ~~    interface_number 之前声明的接口号bInterfaceNumber
返回值:
   ~~    0 成功
   ~~    LIBUSB_ERROR_NOT_FOUND 接口未声明
   ~~    LIBUSB_ERROR_NO_DEVICE 设备断开连接
   ~~    LIBUSB_ERROR 失败,参考LIBUSB_ERROR 代码

int libusb_set_interface_alt_setting(libusb_device_handle * dev_handle,int interface_number,int alternate_setting)

激活/更改接口备用设置。

一个接口实现功能,需要一个相应的驱动;而一个接口有一个或多个备用设置;一个设置对应多个端点,每个端点互相独立的完成一个输入或输出的与Host之间的管道通信;在配置设备的时候将会选择对应的默认备用设置。

使用此函数前需调用libusb_claim_interface()声明接口。
应该使用此函数,而不是定制自己的SET_INTERFACE控制请求去更改接口备用设置。因为底层操作系统需要指定声明时候发送了改变。
这是一个阻塞函数。

参数:
   ~~    dev_handle 设备句柄
   ~~    interface_number 之前已声明的接口编号
   ~~    需要激活的备用设置bAlternateSetting

返回值:
   ~~    0 成功
   ~~    LIBUSB_ERROR_NOT_FOUND 接口未声明
   ~~    LIBUSB_ERROR_NO_DEVICE 设备断开连接
   ~~    LIBUSB_ERROR 失败,参考LIBUSB_ERROR 代码

int libusb_clear_halt(libusb_device_handle * dev_handle,unsigned char endpoint)

清除端点的暂停条件。

int libusb_reset_device(libusb_device_handle * dev_handle)

重新初始化USB设备。

int libusb_kernel_driver_active(libusb_device_handle * dev_handle,int interface_number)

确认接口的内核驱动是否处于活跃状态。
如果接口的内核驱动处于活跃状态,你不能声明此接口,也不能执行设备I/O。
此函数再Windows上不可用。

int libusb_detach_kernel_driver(libusb_device_handle * dev_handle,int interface_number)

detach/attach应该如何理解?暂时没搞懂,先这样把,等我懂了再详细写一下。

从接口卸载内核驱动(接口变为可用状态?)。
如果成功,你可以声明接口并执行I/O操作。
此函数在Darwin和Windows上不可用。
注意,libusb自身也通过特殊的内核驱动与设备通信,若此时驱动程序已经连接到设备,调用此函数将不会分离接口并返回LIBUSB_ERROR_NOT_FOUND的错误。

int libusb_attach_kernel_driver(libusb_device_handle * dev_handle,int interface_number)

挂载接口内核驱动。
此函数只在Linux上有效,在其他平台上将会返回LIBUSB_ERROR_NOT_SUPPORT的错误。
此函数在Darwin和Windows上不可用。

int libusb_set_auto_detach_kernel_driver(libusb_device_handle * dev_handle,int enable)

libusb内核驱动自动卸载使能。
启用后,声明接口时内核驱动将会自动卸载;释放接口后会自动附加。
新打开的设备默认停用内核驱动自动卸载。

3. 杂项

3.1 宏定义

#define LIBUSB_CALL

libusb在windows下的调用约定(calling convention,在生成的汇编代码中给函数传递参数的方式)。

为了匹配Windows API,libusb使用WINAPI约定(stdcall)。公开的头文件也包含了适当的注释,所以你的软件将可以使用正确的约定,即使在你的代码库中使用了其他的约定。

需要注意的是所有的libusb回调函数也需要标记未LIBUSB_CALL,使得这些函数可以被正确编译。

非windows操作系统下,这个宏被定义为空,所以在跨平台时不需要担心LIBUSB_CALL。

#define LIBUSB_API_VERSION

libusb api版本号(0x01000106),从1.0.13开始,用于检测不同版本的特性。

#define libusb_le16_to_cpu libusb_cpu_to_le16

将16-bit值从小端字节序转换为主机字节序格式。
若主机字节序为小端模式,则什么都不做;若为大端字节序,则交换byte。

3.2 枚举

libusb_standard_request

在USB3.0协议【表9-5】中定义的标准请求。

枚举
LIBUSB_REQUEST_GET_STATUS
LIBUSB_REQUEST_CLEAR_FEATURE
LIBUSB_REQUEST_SET_FEATURE
LIBUSB_REQUEST_SET_ADDRESS
LIBUSB_REQUEST_GET_DESCRIPTOR
LIBUSB_REQUEST_SET_DESCRIPTOR
LIBUSB_REQUEST_GET_CONFIGURATION
LIBUSB_REQUEST_SET_CONFIGURATION
LIBUSB_REQUEST_GET_INTERFACE
LIBUSB_REQUEST_SET_INTERFACE
LIBUSB_REQUEST_SYNCH_FRAME
LIBUSB_REQUEST_SET_SEL
LIBUSB_REQUEST_ISOCH_DELAY

libusb_request_type

请求类型,控制传输

Enumerator
LIBUSB_REQUEST_TYPE_STANDARD
LIBUSB_REQUEST_TYPE_CLASS
LIBUSB_REQUEST_TYPE_VENDOR
LIBUSB_REQUEST_TYPE_RESERVED

libusb_request_recipient

请求的接收者

Enumerator
LIBUSB_RECIPIENT_DEVICE
LIBUSB_RECIPIENT_INTERFACE
LIBUSB_RECIPIENT_ENDPOINT
LIBUSB_RECIPIENT_OTHER

libusb_error

错误代码
大部分得libusb函数返回值0代表成功,其他失败值参考错误代码。也可以调用libusb_error_name()/libusb_strerror()获取错误代码的字符串含义。

Enumerator
LIBUSB_SUCCESS
LIBUSB_ERROR_IO
LIBUSB_ERROR_INVALID_PARAM
LIBUSB_ERROR_ACCESS
LIBUSB_ERROR_NO_DEVICE
LIBUSB_ERROR_NOT_FOUND
LIBUSB_ERROR_BUSY
LIBUSB_ERROR_TIMEOUT
LIBUSB_ERROR_OVERFLOW
LIBUSB_ERROR_PIPE
LIBUSB_ERROR_INTERRUPTED
LIBUSB_ERROR_NO_MEM
LIBUSB_ERROR_NOT_SUPPORTED
LIBUSB_ERROR_OTHER

libusb_capability

当前系统运行的libusb实例的支持能力。
调用libusb_has_capability()来测试加载的库是否支持给定的功能。

Enumerator
LIBUSB_CAP_HAS_CAPABILITY
LIBUSB_CAP_HAS_HOTPLUG
LIBUSB_CAP_HAS_HID_ACCESS
LIBUSB_CAP_SUPPORTS_DETACH_KERNEL_DRIVER

3.3 函数

int libusb_has_capability(uint32_t capability)

确认加载的库是否支持给定的功能。
此函数需再libusb_init()只后执行。

参数:
libusb_capability 的枚举
返回值:
非0支持,0 不支持

const char * libusb_error_name(int error_code)

根据错误代码获取错误内容。

const struct libusb_version * libusb_get_version(void)

获取当前当前版本信息。

static uint16_t libusb_cpu_to_le16(const uint16_t x)

将16bit值从主机的字节序模式转换为小端模式。

int libusb_setlocale (const char *locale)

语言设置。
如果没有调用libusb_set_locale(),所有的信息都是英文。

const char * libusb_strerror(enum libusb_error errcode)

获取错误描述。

3.4 变量

static const char * usbi_locale_supported [] = { “en”, “nl”, “fr”, “ru” }

libusb(错误描述)支持的语言。

如何添加新的libusb_strerror()翻译:

  1. 下载最新的strerror.c(下载libusb源码,libusb/strerror.c)
  2. 用支持UTF-8的编辑器打开
  3. 在usbi_locale_supported[]末尾添加两个字没的ISO 639-1代码,中文添加“zh”:
// 原始
usbi_locale_supported[] = { "en", "nl", "fr" };
// 添加zh
usbi_locale_supported[] = { "en", "nl", "fr", "zh" };
  1. 拷贝usbi_localized_errors下的{/* English (en) * / … }节放到最后,修改为
	{ /* English (en) */
		"Success",
		"Input/Output Error",
		"Invalid parameter",
		"Access denied (insufficient permissions)",
		"No such device (it may have been disconnected)",
		"Entity not found",
		"Resource busy",
		"Operation timed out",
		"Overflow",
		"Pipe error",
		"System call interrupted (perhaps due to signal)",
		"Insufficient memory",
		"Operation not supported or unimplemented on this platform",
		"Other error",
	},
	...
	{ /* Chinese (zh) */
		"成功",
		"I/O错误",
		"非法参数",
		"拒绝访问 Access denied (insufficient permissions)",
		"No such device (it may have been disconnected)",
		"Entity not found",
		"Resource busy",
		"Operation timed out",
		"Overflow",
		"Pipe error",
		"System call interrupted (perhaps due to signal)",
		"Insufficient memory",
		"Operation not supported or unimplemented on this platform",
		"Other error",
	},
  1. 对照英文逐条翻译
  2. 保存文件为UTF-8格式。(发送至libusb-devel@lists.sourceforge.net)

4. USB描述符

4.1 数据结构

libusb_device_descriptor
libusb_endpoint_descriptor
libusb_interface_descriptor
libusb_interface
libusb_config_descriptor
libusb_ss_endpoint_companion_descriptor
libusb_bos_dev_capability_descriptor
libusb_bos_descriptor
libusb_usb_2_0_extension_descriptor
libusb_ss_usb_device_capability_descriptor
libusb_container_id_descriptor

4.2 枚举

libusb_class_code
libusb_class_code { 
  LIBUSB_CLASS_PER_INTERFACE = 0, LIBUSB_CLASS_AUDIO = 1, LIBUSB_CLASS_COMM = 2, LIBUSB_CLASS_HID = 3, 
  LIBUSB_CLASS_PHYSICAL = 5, LIBUSB_CLASS_PRINTER = 7, LIBUSB_CLASS_PTP = 6, LIBUSB_CLASS_IMAGE = 6, 
  LIBUSB_CLASS_MASS_STORAGE = 8, LIBUSB_CLASS_HUB = 9, LIBUSB_CLASS_DATA = 10, LIBUSB_CLASS_SMART_CARD = 0x0b, 
  LIBUSB_CLASS_CONTENT_SECURITY = 0x0d, LIBUSB_CLASS_VIDEO = 0x0e, LIBUSB_CLASS_PERSONAL_HEALTHCARE = 0x0f, LIBUSB_CLASS_DIAGNOSTIC_DEVICE = 0xdc, 
  LIBUSB_CLASS_WIRELESS = 0xe0, LIBUSB_CLASS_APPLICATION = 0xfe, LIBUSB_CLASS_VENDOR_SPEC = 0xff 
}
libusb_descriptor_type
libusb_endpoint_direction
libusb_transfer_type
libusb_iso_sync_type
libusb_iso_usage_type

4.3 函数

int libusb_get_device_descriptor (libusb_device *dev, struct libusb_device_descriptor *desc)
Get the USB device descriptor for a given device. More...
int libusb_get_active_config_descriptor (libusb_device *dev, struct libusb_config_descriptor **config)
Get the USB configuration descriptor for the currently active configuration. More...
int libusb_get_config_descriptor (libusb_device *dev, uint8_t config_index, struct libusb_config_descriptor **config)
Get a USB configuration descriptor based on its index. More...
int libusb_get_config_descriptor_by_value (libusb_device *dev, uint8_t bConfigurationValue, struct libusb_config_descriptor **config)
Get a USB configuration descriptor with a specific bConfigurationValue. More...
void libusb_free_config_descriptor (struct libusb_config_descriptor *config)
Free a configuration descriptor obtained from libusb_get_active_config_descriptor() or libusb_get_config_descriptor(). More...
int libusb_get_ss_endpoint_companion_descriptor (struct libusb_context *ctx, const struct libusb_endpoint_descriptor *endpoint, struct libusb_ss_endpoint_companion_descriptor **ep_comp)
Get an endpoints superspeed endpoint companion descriptor (if any) More...
void libusb_free_ss_endpoint_companion_descriptor (struct libusb_ss_endpoint_companion_descriptor *ep_comp)
Free a superspeed endpoint companion descriptor obtained from libusb_get_ss_endpoint_companion_descriptor(). More...
int libusb_get_bos_descriptor (libusb_device_handle *dev_handle, struct libusb_bos_descriptor **bos)
Get a Binary Object Store (BOS) descriptor This is a BLOCKING function, which will send requests to the device. More...
void libusb_free_bos_descriptor (struct libusb_bos_descriptor *bos)
Free a BOS descriptor obtained from libusb_get_bos_descriptor(). More...
int libusb_get_usb_2_0_extension_descriptor (struct libusb_context *ctx, struct libusb_bos_dev_capability_descriptor *dev_cap, struct libusb_usb_2_0_extension_descriptor **usb_2_0_extension)
Get an USB 2.0 Extension descriptor. More...
void libusb_free_usb_2_0_extension_descriptor (struct libusb_usb_2_0_extension_descriptor *usb_2_0_extension)
Free a USB 2.0 Extension descriptor obtained from libusb_get_usb_2_0_extension_descriptor(). More...
int libusb_get_ss_usb_device_capability_descriptor (struct libusb_context *ctx, struct libusb_bos_dev_capability_descriptor *dev_cap, struct libusb_ss_usb_device_capability_descriptor **ss_usb_device_cap)
Get a SuperSpeed USB Device Capability descriptor. More...
void libusb_free_ss_usb_device_capability_descriptor (struct libusb_ss_usb_device_capability_descriptor *ss_usb_device_cap)
Free a SuperSpeed USB Device Capability descriptor obtained from libusb_get_ss_usb_device_capability_descriptor(). More...
int libusb_get_container_id_descriptor (struct libusb_context *ctx, struct libusb_bos_dev_capability_descriptor *dev_cap, struct libusb_container_id_descriptor **container_id)
Get a Container ID descriptor. More...
void libusb_free_container_id_descriptor (struct libusb_container_id_descriptor *container_id)
Free a Container ID descriptor obtained from libusb_get_container_id_descriptor(). More...
int libusb_get_string_descriptor_ascii (libusb_device_handle *dev_handle, uint8_t desc_index, unsigned char *data, int length)
Retrieve a string descriptor in C style ASCII. More...
static int libusb_get_descriptor (libusb_device_handle *dev_handle, uint8_t desc_type, uint8_t desc_index, unsigned char *data, int length)
Retrieve a descriptor from the default control pipe. More...
static int libusb_get_string_descriptor (libusb_device_handle *dev_handle, uint8_t desc_index, uint16_t langid, unsigned char *data, int length)

5 设备热插拔事件通知

5.1 宏定义

LIBUSB_HOTPLUG_MATCH_ANY

LIBUSB_HOTPLUG_MATCH_ANY -1
热插拔时间通配符。

5.2 Typedefs

typedef int libusb_hotplug_callback_handle

回调句柄。
libusb_hotplug_register_callback()生成的回调句柄,可用于注销回调。在每一个libusb_context上回调句柄都是唯一的,在已经注销的回调上调用libusb_hotplug_deregister_callback()是安全的。

typedef int(* libusb_hotplug_callback_fn) (libusb_context *ctx, libusb_device *device, libusb_hotplug_event event, void *user_data)

热插拔回调函数类型。

5.3 枚举

5.3.1 libusb_hotplug_flag
5.3.2 libusb_hotplug_event

5.4 函数

int libusb_hotplug_register_callback(libusb_context *ctx, libusb_hotplug_event events, libusb_hotplug_flag flags, int vendor_id, int product_id, int dev_class, libusb_hotplug_callback_fn cb_fn, void *user_data, libusb_hotplug_callback_handle *callback_handle)
void libusb_hotplug_deregister_callback (libusb_context *ctx, libusb_hotplug_callback_handle callback_handle)

6 异步设备I/O

此章节将详细描述libusb的异步(非阻塞)操作USB设备I/O的接口。
此章节描述的接口都非常强大,但是也相当复杂。简单的应用可以考虑使用同步I/O接口。
异步接口围绕着分离传输提交和处理传输完成的想法来创建的(同步模式将两者合一)。在提交和完成之间可能需要很长的时间,然而异步提交函数是非阻塞的,因此会在可能的长时间延迟期间将控制返回到你的应用程序。

Transfer Abstraction(传输的抽象)

在异步I/O中,libusb为所有的I/O类型(控制、)实现了通用的传输实体概念。

6.1 数据结构

struct libusb_control_setup

用于控制传输的设置封包。

struct libusb_iso_packet_descriptor

同步包描述符。

struct libusb_transfer

通用的USB传输结构体。

6.2 Typedefs

typedef void(* libusb_transfer_cb_fn) (struct libusb_transfer *transfer)

异步传输回调函数类型。

6.3 枚举

enum libusb_transfer_status

传输状态码

enum libusb_transfer_flags

6.4 函数

7 轮询和定时器

8 同步设备I/O

此章节描述了libusb同步(阻塞)操作usb设备I/O的接口。
此章节的接口都非常简单,但是有一些限制。更高级的用户可以考虑使用异步I/O API。

8.1 函数

int libusb_control_transfer

控制usb传输。
从bmRequestType参数推断传输的方向。
wValue,wIndex和wLength参数值需要根据CPU字节序给出。

int libusb_control_transfer	(	libusb_device_handle * 	dev_handle,
uint8_t 	bmRequestType,
uint8_t 	bRequest,
uint16_t 	wValue,
uint16_t 	wIndex,
unsigned char * 	data,
uint16_t 	wLength,
unsigned int 	timeout 
)

参数:
dev_handle 设备句柄
bmRequestType 数据包传输的请求类型
bRequest 数据包的请求字段
wValue 数据包的值
wIndex 数据包的索引
data 合适大小的data buffer,不管是输入还是输出(方向根据bmRequestType确定)
wLength data的长度必须不小于此值
timeout 毫秒,I/O超时时间,0:无超时限制

返回值:
成功,返回实际传输的字节数
LIBUSB_ERROR_TIMEOUT 传输超时
LIBUSB_ERROR_PIPE 设备不支持此请求类型(bRequest)
LIBUSB_ERROR_NO_DEVICE 设备断开连接
LIBUSB_ERROR_BUSY 设备忙
LIBUSB_ERROR_INVALID_PARAM 非法参数
another LIBUSB_ERROR 参考其他error代码

int libusb_bulk_transfer

执行usb数据批量传输。
传输方向从endpoint地址中的direction比特推断。
批量读时,length字段表明期望接收的最大的data长度。如果data中收到的数据比期望的少,函数将会返回data数据,务必检查transferred参数。
在处理超时错误时也要检查transferred参数。libusb可能需要将传输的数据分成多个块以满足O/S的要求,这意味着在前几块完成后有可能超时。小心不要丢失任何可能已经传输的数据,不要认为发生超时就表明完全没有I/O。

int libusb_bulk_transfer	(	struct libusb_device_handle * 	dev_handle,
unsigned char 	endpoint,
unsigned char * 	data,
int 	length,
int * 	transferred,
unsigned int 	timeout 
)	

参数:
dev_handle 设备句柄
endpoint 合法的通信地址
data 合适大小的输出/输出data buffer
length 写,data长度;读,data可接收的最大长度
transferred 实际传输的比特数量;1.0.21版本以后如果不想接收此信息,允许传入NULL值
timeout 毫秒,超时时间,0 无限制

返回值:
0 成功(transferred有值)
LIBUSB_ERROR_TIMEOUT 超时(transferred有值)
LIBUSB_ERROR_PIPE endpoint停止
LIBUSB_ERROR_OVERFLOW 数据溢出
LIBUSB_ERROR_NO_DEVICE 设备断开连接
LIBUSB_ERROR_BUSY 设备忙
其他LIBUSB_ERROR代码

int libusb_interrupt_transfer

执行usb中断传输。(中断该如何理解???)
传输方向从endpoint地址中的direction比特推断。
中断读,length字段表明期望接收的最大的data长度。如果data中收到的数据比期望的少,函数将会返回data数据,务必检查transferred参数。
中断写,需要检查transferred参数,可能并不是所有的数据都会被写入。
处理超时错误时需要检查transferred,libusb可能需要将传输的数据分成多个块以满足O/S的要求,这意味着在前几块完成后有可能超时。小心不要丢失任何可能已经传输的数据,不要认为发生超时就表明完全没有I/O。
默认的endpoint bInterval值被认为是轮询间隔。

int libusb_interrupt_transfer	(	struct libusb_device_handle * 	dev_handle,
unsigned char 	endpoint,
unsigned char * 	data,
int 	length,
int * 	transferred,
unsigned int 	timeout 
)	

参数:
dev_handle 设备句柄
endpoint 合法的通信地址
data 合适大小的输出/输出data buffer
length 写,data长度;读,data可接收的最大长度
transferred 实际传输的比特数量;1.0.21版本以后如果不想接收此信息,允许传入NULL值
timeout 毫秒,超时时间,0 无限制

返回值:
0 成功(transferred有值)
LIBUSB_ERROR_TIMEOUT 超时(transferred有值)
LIBUSB_ERROR_PIPE endpoint停止
LIBUSB_ERROR_OVERFLOW 数据溢出
LIBUSB_ERROR_NO_DEVICE 设备断开连接
LIBUSB_ERROR_BUSY 设备忙
其他LIBUSB_ERROR代码

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值