06_libusb的使用: 给API函数增加了中文件注释

This commit is contained in:
weidongshan
2022-09-17 17:59:42 +08:00
parent 1bea21f668
commit b1e7d69ca4

View File

@@ -45,8 +45,8 @@ unsigned char data[4];
int actual_length; int actual_length;
int r = libusb_bulk_transfer(dev_handle, LIBUSB_ENDPOINT_IN, data, sizeof(data), &actual_length, 0); int r = libusb_bulk_transfer(dev_handle, LIBUSB_ENDPOINT_IN, data, sizeof(data), &actual_length, 0);
if (r == 0 && actual_length == sizeof(data)) { if (r == 0 && actual_length == sizeof(data)) {
// results of the transaction can now be found in the data buffer // 接收到的数据保存在data数组里
// parse them here and report button press // 解析这些数据就可以知道按键状态
} else { } else {
error(); error();
} }
@@ -61,18 +61,17 @@ if (r == 0 && actual_length == sizeof(data)) {
### 2.2 初始化 ### 2.2 初始化
```c ```c
/** \ingroup libusb_lib /**
* Initialize libusb. This function must be called before calling any other * 初始化libusb这个函数必须先与其他libusb的函数执行
* libusb function.
* *
* If you do not provide an output location for a context pointer, a default * 如果传入NULL那么函数内部会穿件一个默认的context
* context will be created. If there was already a default context, it will * 如果已经创建过默认的context这个context会被重新使用(不会重新初始化它)
* be reused (and nothing will be initialized/reinitialized).
* *
* \param ctx Optional output location for context pointer. * 参数:
* Only valid on return code 0. * ctx : context pointer的位置也可以传入NULL
* \returns 0 on success, or a LIBUSB_ERROR code on failure * 返回值
* \see libusb_contexts * 0 - 成功
* 负数 - 失败
*/ */
int API_EXPORTED libusb_init(libusb_context **ctx); int API_EXPORTED libusb_init(libusb_context **ctx);
``` ```
@@ -87,24 +86,18 @@ int API_EXPORTED libusb_init(libusb_context **ctx);
```c ```c
/** @ingroup libusb_dev /** @ingroup libusb_dev
* Returns a list of USB devices currently attached to the system. This is * 返回一个listlist里含有当前系统中所有的USB设备
* your entry point into finding a USB device to operate.
* *
* You are expected to unreference all the devices when you are done with * 我们一般会在list里寻找需要访问的设备找到之后使用libusb_open函数打开它
* them, and then free the list with libusb_free_device_list(). Note that * 然后调用libusb_free_device_list释放list
* libusb_free_device_list() can unref all the devices for you. Be careful
* not to unreference a device you are about to open until after you have
* opened it.
* *
* This return value of this function indicates the number of devices in * 这个函数的返回值表示list中有多少个设备
* the resultant list. The list is actually one element larger, as it is * list的最后一项是NULL
* NULL-terminated.
* *
* \param ctx the context to operate on, or NULL for the default context * 参数:
* \param list output location for a list of devices. Must be later freed with * ctx : context
* libusb_free_device_list(). * list : output location for a list of devices, 最后必须调用libusb_free_device_list()来释放它
* \returns the number of devices in the outputted list, or any * 返回值: list中设备的个数, 或错误值
* \ref libusb_error according to errors encountered by the backend.
*/ */
ssize_t API_EXPORTED libusb_get_device_list(libusb_context *ctx, ssize_t API_EXPORTED libusb_get_device_list(libusb_context *ctx,
libusb_device ***list); libusb_device ***list);
@@ -114,11 +107,12 @@ ssize_t API_EXPORTED libusb_get_device_list(libusb_context *ctx,
```c ```c
/** \ingroup libusb_dev /** \ingroup libusb_dev
* Frees a list of devices previously discovered using * 前面使用libusb_get_device_list()获得了设备list,
* libusb_get_device_list(). If the unref_devices parameter is set, the * 使用完后要调用libusb_free_device_list()释放这个list
* reference count of each device in the list is decremented by 1. * 如果参数unref_devices为1, 则list中每个设备的引用计数值减小1
* \param list the list to free * 参数:
* \param unref_devices whether to unref the devices in the list * list : 要释放的设备list
* unref_devices : 是否要将设备的引用计数减1
*/ */
void API_EXPORTED libusb_free_device_list(libusb_device **list, void API_EXPORTED libusb_free_device_list(libusb_device **list,
int unref_devices); int unref_devices);
@@ -130,23 +124,21 @@ void API_EXPORTED libusb_free_device_list(libusb_device **list,
```c ```c
/** \ingroup libusb_dev /** \ingroup libusb_dev
* Open a device and obtain a device handle. A handle allows you to perform * 打开一个设备并得到它的句柄, 以后进行IO操作时都是使用句柄
* I/O on the device in question.
* *
* Internally, this function adds a reference to the device and makes it * 使用libusb_get_device()函数可以得到设备的list,
* available to you through libusb_get_device(). This reference is removed * 从list里确定你要访问的设备后, 使用libusb_open()去打开它。
* during libusb_close(). * libusb_open()函数内部会增加此设备的引用计数, 使用完毕后要调用libusb_close()减小引用计数。
* *
* This is a non-blocking function; no requests are sent over the bus. * 参数:
* * dev : 要打开的设备
* \param dev the device to open * dev_handle : 输出参数, 用来保存句柄
* \param dev_handle output location for the returned device handle pointer. Only * 返回值:
* populated when the return code is 0. * 0 - 成功
* \returns 0 on success * LIBUSB_ERROR_NO_MEM : 缺少内存
* \returns \ref LIBUSB_ERROR_NO_MEM on memory allocation failure * LIBUSB_ERROR_ACCESS : 权限不足
* \returns \ref LIBUSB_ERROR_ACCESS if the user has insufficient permissions * LIBUSB_ERROR_NO_DEVICE : 这个设备未连接
* \returns \ref LIBUSB_ERROR_NO_DEVICE if the device has been disconnected * 其他错误 : 其他LIBUSB_ERROR错误码
* \returns another LIBUSB_ERROR code on other failure
*/ */
int API_EXPORTED libusb_open(libusb_device *dev, int API_EXPORTED libusb_open(libusb_device *dev,
libusb_device_handle **dev_handle); libusb_device_handle **dev_handle);
@@ -158,15 +150,12 @@ int API_EXPORTED libusb_open(libusb_device *dev,
```c ```c
/** \ingroup libusb_dev /** \ingroup libusb_dev
* Close a device handle. Should be called on all open handles before your * 关闭设备句柄, 在程序退出之前应该使用它去关闭已经打开的句柄
* application exits.
* *
* Internally, this function destroys the reference that was added by * 设备的引用计数在前面被libusb_open()函数增加了。
* libusb_open() on the given device. * libusb_close()函数的内部,它会减小设备的引用计数。
* *
* This is a non-blocking function; no requests are sent over the bus. * 参数: dev_handle - 句柄
*
* \param dev_handle the device handle to close
*/ */
void API_EXPORTED libusb_close(libusb_device_handle *dev_handle); void API_EXPORTED libusb_close(libusb_device_handle *dev_handle);
``` ```
@@ -181,21 +170,23 @@ libusb_open_device_with_vid_pid函数原型如下
```c ```c
/** \ingroup libusb_dev /** \ingroup libusb_dev
* Convenience function for finding a device with a particular * 打开设备的常规做法是使用libusb_get_device_list()得到设备list
* <tt>idVendor</tt>/<tt>idProduct</tt> combination. This function is intended * 然后遍历list找到设备
* for those scenarios where you are using libusb to knock up a quick test * 接着使用libusb_open()函数得到句柄
* application - it allows you to avoid calling libusb_get_device_list() and
* worrying about traversing/freeing the list.
* *
* This function has limitations and is hence not intended for use in real * 如果知道USB设备的VID、PID那么可以使用libusb_open_device_with_vid_pid()函数快速打开它,得到句柄。
* applications: if multiple devices have the same IDs it will only
* give you the first one, etc.
* *
* \param ctx the context to operate on, or NULL for the default context * 这个函数有一个缺点: 如果系统中有多个ID相同的设备你只能打开第1个设备
* \param vendor_id the idVendor value to search for *
* \param product_id the idProduct value to search for * 参数:
* \returns a device handle for the first found device, or NULL on error * ctx : context, 或者传入NULL以使用默认的context
* or if the device could not be found. */ * vendor_id : 厂家ID
* product_id : 产品ID
*
* 返回值:
* 句柄 - 找到的第1个设备的句柄
* NULL - 没有找到设备
*/
DEFAULT_VISIBILITY DEFAULT_VISIBILITY
libusb_device_handle * LIBUSB_CALL libusb_open_device_with_vid_pid( libusb_device_handle * LIBUSB_CALL libusb_open_device_with_vid_pid(
libusb_context *ctx, uint16_t vendor_id, uint16_t product_id); libusb_context *ctx, uint16_t vendor_id, uint16_t product_id);
@@ -205,6 +196,8 @@ libusb_device_handle * LIBUSB_CALL libusb_open_device_with_vid_pid(
### 2.6 detach/attach驱动 ### 2.6 detach/attach驱动
#### 2.6.1 两种方法
使用libusb访问USB设备时需要先移除(detach)设备原来的驱动程序,然后安装(attach)libusb专用的驱动程序。有两种办法 使用libusb访问USB设备时需要先移除(detach)设备原来的驱动程序,然后安装(attach)libusb专用的驱动程序。有两种办法
* 方法1 * 方法1
@@ -230,28 +223,30 @@ libusb_device_handle * LIBUSB_CALL libusb_open_device_with_vid_pid(
#### 2.6.2 函数原型
函数`libusb_detach_kernel_driver`原型如下: 函数`libusb_detach_kernel_driver`原型如下:
```c ```c
* Detach a kernel driver from an interface. If successful, you will then be /** \ingroup libusb_dev
* able to claim the interface and perform I/O. * 给USB设备的接口(interface)移除驱动程序. If successful, you will then be
* 移除原来的驱动后才能"claim the interface"、执行IO操作
* *
* This functionality is not available on Windows. * 实际上libusb会给这个接口安装一个特殊的内核驱动,
* 所以本函数"移除驱动"是移除其他驱动,不是移除这个特殊的驱动。
* 若干这个接口已经安装了这个特殊的驱动本函数会返回LIBUSB_ERROR_NOT_FOUND.
* *
* Note that libusb itself also talks to the device through a special kernel * 参数:
* driver, if this driver is already attached to the device, this call will * dev_handle - 设备句柄
* not detach it and return \ref LIBUSB_ERROR_NOT_FOUND. * interface_number - 哪一个接口
* *
* \param dev_handle a device handle * 返回值:
* \param interface_number the interface to detach the driver from * 0 - 成功
* \returns 0 on success * LIBUSB_ERROR_NOT_FOUND - 这个接口没有安装其他驱动
* \returns \ref LIBUSB_ERROR_NOT_FOUND if no kernel driver was active * LIBUSB_ERROR_INVALID_PARAM - 没有这个接口
* \returns \ref LIBUSB_ERROR_INVALID_PARAM if the interface does not exist * LIBUSB_ERROR_NO_DEVICE - 这个设备未连接
* \returns \ref LIBUSB_ERROR_NO_DEVICE if the device has been disconnected * LIBUSB_ERROR_NOT_SUPPORTED - 系统不支持此操作, 比如Windows
* \returns \ref LIBUSB_ERROR_NOT_SUPPORTED on platforms where the functionality * 其他LIBUSB_ERROR错误码
* is not available
* \returns another LIBUSB_ERROR code on other failure
* \see libusb_kernel_driver_active()
*/ */
int API_EXPORTED libusb_detach_kernel_driver(libusb_device_handle *dev_handle, int API_EXPORTED libusb_detach_kernel_driver(libusb_device_handle *dev_handle,
int interface_number); int interface_number);
@@ -263,32 +258,27 @@ int API_EXPORTED libusb_detach_kernel_driver(libusb_device_handle *dev_handle,
```c ```c
/** \ingroup libusb_dev /** \ingroup libusb_dev
* Claim an interface on a given device handle. You must claim the interface * libusb使用内核里一个特殊的驱动程序
* you wish to use before you can perform I/O on any of its endpoints. * libusb_claim_interface()函数就是给某个usb接口安装这个特殊的驱动程序
* 在使用libusb的函数执行IO操作之前必须调用本函数。
* *
* It is legal to attempt to claim an already-claimed interface, in which * 你可以给"已经claim过的接口"再次调用本函数它直接返回0。
* case libusb just returns 0 without doing anything.
* *
* If auto_detach_kernel_driver is set to 1 for <tt>dev</tt>, the kernel driver * 如果这个接口的auto_detach_kernel_driver被设置为1
* will be detached if necessary, on failure the detach error is returned. * libusb_claim_interface()函数会先移除其他驱动。
* *
* Claiming of interfaces is a purely logical operation; it does not cause * 本函数时纯粹的逻辑操作只是替换接口的驱动程序而已不会导致USB硬件传输。
* any requests to be sent over the bus. Interface claiming is used to
* instruct the underlying operating system that your application wishes
* to take ownership of the interface.
* *
* This is a non-blocking function. * 参数:
* dev_handle - 句柄, 表示USB设备
* interface_number - 接口
* *
* \param dev_handle a device handle * 返回值:
* \param interface_number the <tt>bInterfaceNumber</tt> of the interface you * 0 - 成功
* wish to claim * LIBUSB_ERROR_NOT_FOUND - 没有这个接口
* \returns 0 on success * LIBUSB_ERROR_BUSY - 其他APP或者驱动正在使用这个接口
* \returns \ref LIBUSB_ERROR_NOT_FOUND if the requested interface does not exist * LIBUSB_ERROR_NO_DEVICE - 设备未连接
* \returns \ref LIBUSB_ERROR_BUSY if another program or driver has claimed the * 其他LIBUSB_ERROR错误码
* interface
* \returns \ref LIBUSB_ERROR_NO_DEVICE if the device has been disconnected
* \returns a LIBUSB_ERROR code on other failure
* \see libusb_set_auto_detach_kernel_driver()
*/ */
int API_EXPORTED libusb_claim_interface(libusb_device_handle *dev_handle, int API_EXPORTED libusb_claim_interface(libusb_device_handle *dev_handle,
int interface_number); int interface_number);
@@ -300,23 +290,23 @@ int API_EXPORTED libusb_claim_interface(libusb_device_handle *dev_handle,
```c ```c
/** \ingroup libusb_dev /** \ingroup libusb_dev
* Release an interface previously claimed with libusb_claim_interface(). You * 前面使用libusb_claim_interface()给接口安装了给libusb使用的特殊驱动程序,
* should release all claimed interfaces before closing a device handle. * 使用完毕后在调用libusb_close()关闭句柄之前,
* 可以调用libusb_release_interface()卸载特殊驱动程序
* 如果设备的auto_detach_kernel_driver为1还会重新安装普通驱动程序
* *
* This is a blocking function. A SET_INTERFACE control request will be sent * 这是一个阻塞函数, 它会给USB设备发送一个请求: SET_INTERFACE control,
* to the device, resetting interface state to the first alternate setting. * 用来把接口的状态复位到第1个setting(the first alternate setting)
* *
* If auto_detach_kernel_driver is set to 1 for <tt>dev</tt>, the kernel * 参数:
* driver will be re-attached after releasing the interface. * dev_handle - 设备句柄
* interface_number - 哪个接口
* *
* \param dev_handle a device handle * 返回值:
* \param interface_number the <tt>bInterfaceNumber</tt> of the * 0 - 成功
* previously-claimed interface * LIBUSB_ERROR_NOT_FOUND - 这个接口没有被claim(没有安装特殊的驱动程序)
* \returns 0 on success * LIBUSB_ERROR_NO_DEVICE - 设备未连接
* \returns \ref LIBUSB_ERROR_NOT_FOUND if the interface was not claimed * 其他LIBUSB_ERROR错误码
* \returns \ref LIBUSB_ERROR_NO_DEVICE if the device has been disconnected
* \returns another LIBUSB_ERROR code on other failure
* \see libusb_set_auto_detach_kernel_driver()
*/ */
int API_EXPORTED libusb_release_interface(libusb_device_handle *dev_handle, int API_EXPORTED libusb_release_interface(libusb_device_handle *dev_handle,
int interface_number); int interface_number);
@@ -326,54 +316,46 @@ int API_EXPORTED libusb_release_interface(libusb_device_handle *dev_handle,
### 2.7 描述符相关函数 ### 2.7 描述符相关函数
**获得设备描述符** #### 2.7.1 获得设备描述符
```c ```c
/** \ingroup libusb_desc /** \ingroup libusb_desc
* Get the USB device descriptor for a given device. * 获得设备描述符
* *
* This is a non-blocking function; the device descriptor is cached in memory. * 参数:
* dev - 哪个设备
* desc - 输出参数, 用来保存设备描述符
* *
* Note since libusb-1.0.16, \ref LIBUSB_API_VERSION >= 0x01000102, this * 返回值:
* function always succeeds. * 0 - 成功, 或其他LIBUSB_ERROR错误码
*
* \param dev the device
* \param desc output location for the descriptor data
* \returns 0 on success or a LIBUSB_ERROR code on failure
*/ */
int API_EXPORTED libusb_get_device_descriptor(libusb_device *dev, int API_EXPORTED libusb_get_device_descriptor(libusb_device *dev,
struct libusb_device_descriptor *desc); struct libusb_device_descriptor *desc);
``` ```
**获得/释放配置描述符** #### 2.7.2 获得/释放配置描述符
```c ```c
/** \ingroup libusb_desc /** \ingroup libusb_desc
* Get a USB configuration descriptor based on its index. * 获得指定的配置描述符
* This is a non-blocking function which does not involve any requests being
* sent to the device.
* *
* \param dev a device * 参数:
* \param config_index the index of the configuration you wish to retrieve * dev - 哪个设备
* \param config output location for the USB configuration descriptor. Only * config_index - 哪个配置
* valid if 0 was returned. Must be freed with libusb_free_config_descriptor() * config - 输出参数, 用来保存配置描述符, 使用完毕要调用libusb_free_config_descriptor()释放掉
* after use. *
* \returns 0 on success * 返回值:
* \returns LIBUSB_ERROR_NOT_FOUND if the configuration does not exist * 0 - 成功
* \returns another LIBUSB_ERROR code on error * LIBUSB_ERROR_NOT_FOUND - 没有这个配置
* \see libusb_get_active_config_descriptor() * 其他LIBUSB_ERROR错误码
* \see libusb_get_config_descriptor_by_value()
*/ */
int API_EXPORTED libusb_get_config_descriptor(libusb_device *dev, int API_EXPORTED libusb_get_config_descriptor(libusb_device *dev,
uint8_t config_index, struct libusb_config_descriptor **config); uint8_t config_index, struct libusb_config_descriptor **config);
/** \ingroup libusb_desc /** \ingroup libusb_desc
* Free a configuration descriptor obtained from * Free a configuration descriptor obtained from
* libusb_get_active_config_descriptor() or libusb_get_config_descriptor(). * 前面使用libusb_get_active_config_descriptor()libusb_get_config_descriptor()获得配置描述符,
* It is safe to call this function with a NULL config parameter, in which * 用完后调用libusb_free_config_descriptor()释放掉
* case the function simply returns.
*
* \param config the configuration descriptor to free
*/ */
void API_EXPORTED libusb_free_config_descriptor( void API_EXPORTED libusb_free_config_descriptor(
struct libusb_config_descriptor *config); struct libusb_config_descriptor *config);
@@ -387,35 +369,30 @@ void API_EXPORTED libusb_free_config_descriptor(
```c ```c
/** \ingroup libusb_syncio /** \ingroup libusb_syncio
* Perform a USB control transfer. * 启动控制传输
* *
* The direction of the transfer is inferred from the bmRequestType field of * 传输方向在bmRequestType
* the setup packet. * wValue,wIndex和wLength是host-endian字节序
* *
* The wValue, wIndex and wLength fields values should be given in host-endian * 参数:
* byte order. * dev_handle - 设备句柄
* bmRequestType - setup数据包的bmRequestType域
* bRequest - setup数据包的bRequest域
* wValue - setup数据包的wValue域
* wIndex - setup数据包的wIndex域
* data - 保存数据的buffer, 可以是in、out数据
* wLength - setup数据包的wLength域
* timeout - 超时时间(单位ms),就是这个函数能等待的最大时间; 0表示一直等待直到成功
* *
* \param dev_handle a handle for the device to communicate with * 返回值:
* \param bmRequestType the request type field for the setup packet * 正整数 - 成功传输的数据的长度
* \param bRequest the request field for the setup packet * LIBUSB_ERROR_TIMEOUT - 超时
* \param wValue the value field for the setup packet * LIBUSB_ERROR_PIPE - 设备不支持该请求
* \param wIndex the index field for the setup packet * LIBUSB_ERROR_NO_DEVICE - 设备未连接
* \param data a suitably-sized data buffer for either input or output * LIBUSB_ERROR_BUSY - 如果这个函数时在事件处理上下文(event handling context)里则返回这个错误
* (depending on direction bits within bmRequestType) * LIBUSB_ERROR_INVALID_PARAM - 传输的字节超过OS或硬件的支持
* \param wLength the length field for the setup packet. The data buffer should
* be at least this size.
* \param timeout timeout (in milliseconds) that this function should wait
* before giving up due to no response being received. For an unlimited
* timeout, use value 0.
* \returns on success, the number of bytes actually transferred
* \returns LIBUSB_ERROR_TIMEOUT if the transfer timed out
* \returns LIBUSB_ERROR_PIPE if the control request was not supported by the
* device
* \returns LIBUSB_ERROR_NO_DEVICE if the device has been disconnected
* \returns LIBUSB_ERROR_BUSY if called from event handling context
* \returns LIBUSB_ERROR_INVALID_PARAM if the transfer size is larger than
* the operating system and/or hardware can support (see \ref asynclimits) * the operating system and/or hardware can support (see \ref asynclimits)
* \returns another LIBUSB_ERROR code on other failures * 其他LIBUSB_ERROR错误码
*/ */
int API_EXPORTED libusb_control_transfer(libusb_device_handle *dev_handle, int API_EXPORTED libusb_control_transfer(libusb_device_handle *dev_handle,
uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex,
@@ -428,49 +405,34 @@ int API_EXPORTED libusb_control_transfer(libusb_device_handle *dev_handle,
```c ```c
/** \ingroup libusb_syncio /** \ingroup libusb_syncio
* Perform a USB bulk transfer. The direction of the transfer is inferred from * 启动批量传输
* the direction bits of the endpoint address. * 传输方向在endpoint的"方向位"里表示
* *
* For bulk reads, the <tt>length</tt> field indicates the maximum length of * 对于批量读参数length表示"期望读到的数据最大长度", 实际读到的长度保存在transferred参数里
* data you are expecting to receive. If less data arrives than expected,
* this function will return that data, so be sure to check the
* <tt>transferred</tt> output parameter.
* *
* You should also check the <tt>transferred</tt> parameter for bulk writes. * 对于批量写, transferred参数表示实际发送出去的数据长度
* Not all of the data may have been written.
* *
* Also check <tt>transferred</tt> when dealing with a timeout error code. * 发生超时错误时也应该检查transferred参数。
* libusb may have to split your transfer into a number of chunks to satisfy * libusb会根据硬件的特点把数据拆分为一小段一小段地发送出去,
* underlying O/S requirements, meaning that the timeout may expire after * 这意味着发送满某段数据后可能就发生超时错误需要根据transferred参数判断传输了多少数据。
* the first few chunks have completed. libusb is careful not to lose any data
* that may have been transferred; do not assume that timeout conditions
* indicate a complete lack of I/O. See \ref asynctimeout for more details.
* *
* \param dev_handle a handle for the device to communicate with * 参数:
* \param endpoint the address of a valid endpoint to communicate with * dev_handle - 设备句柄
* \param data a suitably-sized data buffer for either input or output * endpoint - 端点
* (depending on endpoint) * data - 保存数据的buffer, 可以是in、out数据
* \param length for bulk writes, the number of bytes from data to be sent. for * length - 对于批量写,它表示要发送的数据长度; 对于批量读,它表示"要读的数据的最大长度"
* bulk reads, the maximum number of bytes to receive into the data buffer. * transferred - 输出参数,表示实际传输的数据长度
* \param transferred output location for the number of bytes actually * timeout - 超时时间(单位ms),就是这个函数能等待的最大时间; 0表示一直等待直到成功
* transferred. Since version 1.0.21 (\ref LIBUSB_API_VERSION >= 0x01000105),
* it is legal to pass a NULL pointer if you do not wish to receive this
* information.
* \param timeout timeout (in milliseconds) that this function should wait
* before giving up due to no response being received. For an unlimited
* timeout, use value 0.
* *
* \returns 0 on success (and populates <tt>transferred</tt>) * 返回值:
* \returns LIBUSB_ERROR_TIMEOUT if the transfer timed out (and populates * 0 - 成功根据transferred参数判断传输了多少长度的数据
* <tt>transferred</tt>) * LIBUSB_ERROR_TIMEOUT - 超时, 根据transferred参数判断传输了多少长度的数据
* \returns LIBUSB_ERROR_PIPE if the endpoint halted * LIBUSB_ERROR_PIPE - 端点错误,端点被挂起了
* \returns LIBUSB_ERROR_OVERFLOW if the device offered more data, see * LIBUSB_ERROR_OVERFLOW - 溢出,设备提供的数据太多了
* \ref libusb_packetoverflow * LIBUSB_ERROR_NO_DEVICE - 设备未连接
* \returns LIBUSB_ERROR_NO_DEVICE if the device has been disconnected * LIBUSB_ERROR_BUSY - 如果这个函数时在事件处理上下文(event handling context)里则返回这个错误
* \returns LIBUSB_ERROR_BUSY if called from event handling context * LIBUSB_ERROR_INVALID_PARAM - 传输的字节超过OS或硬件的支持
* \returns LIBUSB_ERROR_INVALID_PARAM if the transfer size is larger than * 其他LIBUSB_ERROR错误码
* the operating system and/or hardware can support (see \ref asynclimits)
* \returns another LIBUSB_ERROR code on other failures
*/ */
int API_EXPORTED libusb_bulk_transfer(libusb_device_handle *dev_handle, int API_EXPORTED libusb_bulk_transfer(libusb_device_handle *dev_handle,
unsigned char endpoint, unsigned char *data, int length, unsigned char endpoint, unsigned char *data, int length,
@@ -483,50 +445,34 @@ int API_EXPORTED libusb_bulk_transfer(libusb_device_handle *dev_handle,
```c ```c
/** \ingroup libusb_syncio /** \ingroup libusb_syncio
* Perform a USB interrupt transfer. The direction of the transfer is inferred * 启动中断传输
* from the direction bits of the endpoint address. * 传输方向在endpoint的"方向位"里表示
* *
* For interrupt reads, the <tt>length</tt> field indicates the maximum length * 对于中断读参数length表示"期望读到的数据最大长度", 实际读到的长度保存在transferred参数里
* of data you are expecting to receive. If less data arrives than expected,
* this function will return that data, so be sure to check the
* <tt>transferred</tt> output parameter.
* *
* You should also check the <tt>transferred</tt> parameter for interrupt * 对于中断写, transferred参数表示实际发送出去的数据长度不一定能发送完全部数据。
* writes. Not all of the data may have been written.
* *
* Also check <tt>transferred</tt> when dealing with a timeout error code. * 发生超时错误时也应该检查transferred参数。
* libusb may have to split your transfer into a number of chunks to satisfy * libusb会根据硬件的特点把数据拆分为一小段一小段地发送出去,
* underlying O/S requirements, meaning that the timeout may expire after * 这意味着发送满某段数据后可能就发生超时错误需要根据transferred参数判断传输了多少数据。
* the first few chunks have completed. libusb is careful not to lose any data
* that may have been transferred; do not assume that timeout conditions
* indicate a complete lack of I/O. See \ref asynctimeout for more details.
* *
* The default endpoint bInterval value is used as the polling interval. * 参数:
* dev_handle - 设备句柄
* endpoint - 端点
* data - 保存数据的buffer, 可以是in、out数据
* length - 对于批量写,它表示要发送的数据长度; 对于批量读,它表示"要读的数据的最大长度"
* transferred - 输出参数,表示实际传输的数据长度
* timeout - 超时时间(单位ms),就是这个函数能等待的最大时间; 0表示一直等待直到成功
* *
* \param dev_handle a handle for the device to communicate with * 返回值:
* \param endpoint the address of a valid endpoint to communicate with * 0 - 成功根据transferred参数判断传输了多少长度的数据
* \param data a suitably-sized data buffer for either input or output * LIBUSB_ERROR_TIMEOUT - 超时, 根据transferred参数判断传输了多少长度的数据
* (depending on endpoint) * LIBUSB_ERROR_PIPE - 端点错误,端点被挂起了
* \param length for bulk writes, the number of bytes from data to be sent. for * LIBUSB_ERROR_OVERFLOW - 溢出,设备提供的数据太多了
* bulk reads, the maximum number of bytes to receive into the data buffer. * LIBUSB_ERROR_NO_DEVICE - 设备未连接
* \param transferred output location for the number of bytes actually * LIBUSB_ERROR_BUSY - 如果这个函数时在事件处理上下文(event handling context)里则返回这个错误
* transferred. Since version 1.0.21 (\ref LIBUSB_API_VERSION >= 0x01000105), * LIBUSB_ERROR_INVALID_PARAM - 传输的字节超过OS或硬件的支持
* it is legal to pass a NULL pointer if you do not wish to receive this * 其他LIBUSB_ERROR错误码
* information.
* \param timeout timeout (in milliseconds) that this function should wait
* before giving up due to no response being received. For an unlimited
* timeout, use value 0.
*
* \returns 0 on success (and populates <tt>transferred</tt>)
* \returns LIBUSB_ERROR_TIMEOUT if the transfer timed out
* \returns LIBUSB_ERROR_PIPE if the endpoint halted
* \returns LIBUSB_ERROR_OVERFLOW if the device offered more data, see
* \ref libusb_packetoverflow
* \returns LIBUSB_ERROR_NO_DEVICE if the device has been disconnected
* \returns LIBUSB_ERROR_BUSY if called from event handling context
* \returns LIBUSB_ERROR_INVALID_PARAM if the transfer size is larger than
* the operating system and/or hardware can support (see \ref asynclimits)
* \returns another LIBUSB_ERROR code on other error
*/ */
int API_EXPORTED libusb_interrupt_transfer(libusb_device_handle *dev_handle, int API_EXPORTED libusb_interrupt_transfer(libusb_device_handle *dev_handle,
unsigned char endpoint, unsigned char *data, int length, unsigned char endpoint, unsigned char *data, int length,
@@ -553,27 +499,28 @@ int API_EXPORTED libusb_interrupt_transfer(libusb_device_handle *dev_handle,
```c ```c
/** \ingroup libusb_asyncio /** \ingroup libusb_asyncio
* Allocate a libusb transfer with a specified number of isochronous packet * 分配一个libusb_transfer结构体,
* descriptors. The returned transfer is pre-initialized for you. When the new * 如果iso_packets不为0还会分配iso_packets个libusb_iso_packet_descriptor结构体
* transfer is no longer needed, it should be freed with * 使用完毕后需要调用libusb_free_transfer()函数释放掉
* libusb_free_transfer().
* *
* Transfers intended for non-isochronous endpoints (e.g. control, bulk, * 对于控制传输、批量传输、中断传输iso_packets参数需要设置为0
* interrupt) should specify an iso_packets count of zero.
* *
* For transfers intended for isochronous endpoints, specify an appropriate * 对于实时传输需要指定iso_packets参数
* number of packet descriptors to be allocated as part of the transfer. * 这个函数会一起分配iso_packets个libusb_iso_packet_descriptor结构体。
* The returned transfer is not specially initialized for isochronous I/O; * 这个函数返回的libusb_transfer结构体并未初始化
* you are still required to set the * 你还需要初始化它的这些成员:
* \ref libusb_transfer::num_iso_packets "num_iso_packets" and * libusb_transfer::num_iso_packets
* \ref libusb_transfer::type "type" fields accordingly. * libusb_transfer::type
* *
* It is safe to allocate a transfer with some isochronous packets and then * 你可以指定iso_packets参数意图给实时传输分配结构体
* use it on a non-isochronous endpoint. If you do this, ensure that at time * 但是你可以把这个结构题用于其他类型的传输,
* of submission, num_iso_packets is 0 and that type is set appropriately. * 在这种情况下只要确保num_iso_packets为0就可以。
* *
* \param iso_packets number of isochronous packet descriptors to allocate. Must be non-negative. * 参数:
* \returns a newly allocated transfer, or NULL on error * iso_packets - 分配多少个isochronous packet descriptors to allocate
*
* 返回值:
* 返回一个libusb_transfer结构体或NULL
*/ */
DEFAULT_VISIBILITY DEFAULT_VISIBILITY
struct libusb_transfer * LIBUSB_CALL libusb_alloc_transfer( struct libusb_transfer * LIBUSB_CALL libusb_alloc_transfer(
@@ -585,32 +532,31 @@ struct libusb_transfer * LIBUSB_CALL libusb_alloc_transfer(
#### 2.9.3 填充控制传输 #### 2.9.3 填充控制传输
```c ```c
* Helper function to populate the required \ref libusb_transfer fields /** \ingroup libusb_asyncio
* for a control transfer. * 构造控制传输结构体
* *
* If you pass a transfer buffer to this function, the first 8 bytes will * 如果你传入buffer参数那么buffer的前面8字节会被当做"control setup packet"来解析,
* be interpreted as a control setup packet, and the wLength field will be * buffer的最后2字节表示wLength它也会被用来设置libusb_transfer::length
* used to automatically populate the \ref libusb_transfer::length "length" * 所以,建议使用流程如下:
* field of the transfer. Therefore the recommended approach is: * 1. 分配buffer这个buffer的前面8字节对应"control setup packet",后面的空间可以用来保存其他数据
* -# Allocate a suitably sized data buffer (including space for control setup) * 2. 设置"control setup packet"通过调用libusb_fill_control_setup()函数来设置
* -# Call libusb_fill_control_setup() * 3. 如果是要把数据发送个设备把要发送的数据放在buffer的后面(从buffer[8]开始放)
* -# If this is a host-to-device transfer with a data stage, put the data * 4. 调用libusb_fill_bulk_transfer
* in place after the setup packet * 5. 提交传输: 调用libusb_submit_transfer()
* -# Call this function
* -# Call libusb_submit_transfer()
* *
* It is also legal to pass a NULL buffer to this function, in which case this * 也可以让buffer参数为NULL
* function will not attempt to populate the length field. Remember that you * 这种情况下libusb_transfer::length就不会被设置,
* must then populate the buffer and length fields later. * 需要手工去设置ibusb_transfer::buffer、ibusb_transfer::length
* *
* \param transfer the transfer to populate * 参数:
* \param dev_handle handle of the device that will handle the transfer * transfer - 要设置的libusb_transfer结构体
* \param buffer data buffer. If provided, this function will interpret the * dev_handle - 设备句柄
* first 8 bytes as a setup packet and infer the transfer length from that. * buffer - 数据buffer如果不是NULL的话它前面8直接会被当做"control setup packet"来处理,
* This pointer must be aligned to at least 2 bytes boundary. * 也会从buffer[6], buffer[7]把length提取出来用来设置libusb_transfer::length
* \param callback callback function to be invoked on transfer completion * 这个buffer必须是2字节对齐
* \param user_data user data to pass to callback function * callback - 传输完成时的回调函数
* \param timeout timeout for the transfer in milliseconds * user_data - 传给回调函数的参数
* timeout - 超时时间(单位: ms)
*/ */
static inline void libusb_fill_control_transfer( static inline void libusb_fill_control_transfer(
struct libusb_transfer *transfer, libusb_device_handle *dev_handle, struct libusb_transfer *transfer, libusb_device_handle *dev_handle,
@@ -624,17 +570,17 @@ static inline void libusb_fill_control_transfer(
```c ```c
/** \ingroup libusb_asyncio /** \ingroup libusb_asyncio
* Helper function to populate the required \ref libusb_transfer fields * 构造批量传输结构体
* for a bulk transfer.
* *
* \param transfer the transfer to populate * 参数:
* \param dev_handle handle of the device that will handle the transfer * transfer - 要设置的libusb_transfer结构体
* \param endpoint address of the endpoint where this transfer will be sent * dev_handle - 设备句柄
* \param buffer data buffer * endpoint - 端点
* \param length length of data buffer * buffer - 数据buffer
* \param callback callback function to be invoked on transfer completion * length - buffer的数据长度
* \param user_data user data to pass to callback function * callback - 传输完成时的回调函数
* \param timeout timeout for the transfer in milliseconds * user_data - 传给回调函数的参数
* timeout - 超时时间(单位: ms)
*/ */
static inline void libusb_fill_bulk_transfer(struct libusb_transfer *transfer, static inline void libusb_fill_bulk_transfer(struct libusb_transfer *transfer,
libusb_device_handle *dev_handle, unsigned char endpoint, libusb_device_handle *dev_handle, unsigned char endpoint,
@@ -648,17 +594,17 @@ static inline void libusb_fill_bulk_transfer(struct libusb_transfer *transfer,
```c ```c
/** \ingroup libusb_asyncio /** \ingroup libusb_asyncio
* Helper function to populate the required \ref libusb_transfer fields * 构造中断传输结构体
* for an interrupt transfer.
* *
* \param transfer the transfer to populate * 参数:
* \param dev_handle handle of the device that will handle the transfer * transfer - 要设置的libusb_transfer结构体
* \param endpoint address of the endpoint where this transfer will be sent * dev_handle - 设备句柄
* \param buffer data buffer * endpoint - 端点
* \param length length of data buffer * buffer - 数据buffer
* \param callback callback function to be invoked on transfer completion * length - buffer的数据长度
* \param user_data user data to pass to callback function * callback - 传输完成时的回调函数
* \param timeout timeout for the transfer in milliseconds * user_data - 传给回调函数的参数
* timeout - 超时时间(单位: ms)
*/ */
static inline void libusb_fill_interrupt_transfer( static inline void libusb_fill_interrupt_transfer(
struct libusb_transfer *transfer, libusb_device_handle *dev_handle, struct libusb_transfer *transfer, libusb_device_handle *dev_handle,
@@ -672,18 +618,18 @@ static inline void libusb_fill_interrupt_transfer(
```c ```c
/** \ingroup libusb_asyncio /** \ingroup libusb_asyncio
* Helper function to populate the required \ref libusb_transfer fields * 构造实时传输结构体
* for an isochronous transfer.
* *
* \param transfer the transfer to populate * 参数:
* \param dev_handle handle of the device that will handle the transfer * transfer - 要设置的libusb_transfer结构体
* \param endpoint address of the endpoint where this transfer will be sent * dev_handle - 设备句柄
* \param buffer data buffer * endpoint - 端点
* \param length length of data buffer * buffer - 数据buffer
* \param num_iso_packets the number of isochronous packets * length - buffer的数据长度
* \param callback callback function to be invoked on transfer completion * num_iso_packets - 实时传输包的个数
* \param user_data user data to pass to callback function * callback - 传输完成时的回调函数
* \param timeout timeout for the transfer in milliseconds * user_data - 传给回调函数的参数
* timeout - 超时时间(单位: ms)
*/ */
static inline void libusb_fill_iso_transfer(struct libusb_transfer *transfer, static inline void libusb_fill_iso_transfer(struct libusb_transfer *transfer,
libusb_device_handle *dev_handle, unsigned char endpoint, libusb_device_handle *dev_handle, unsigned char endpoint,
@@ -697,18 +643,18 @@ static inline void libusb_fill_iso_transfer(struct libusb_transfer *transfer,
```c ```c
/** \ingroup libusb_asyncio /** \ingroup libusb_asyncio
* Submit a transfer. This function will fire off the USB transfer and then * 提交传输Submit,这个函数会启动传输,然后立刻返回
* return immediately.
* *
* \param transfer the transfer to submit * 参数:
* \returns 0 on success * transfer - 要传输的libusb_transfer结构体
* \returns \ref LIBUSB_ERROR_NO_DEVICE if the device has been disconnected *
* \returns \ref LIBUSB_ERROR_BUSY if the transfer has already been submitted. * 返回值:
* \returns \ref LIBUSB_ERROR_NOT_SUPPORTED if the transfer flags are not supported * 0 - 成功
* by the operating system. * LIBUSB_ERROR_NO_DEVICE - 设备未连接
* \returns \ref LIBUSB_ERROR_INVALID_PARAM if the transfer size is larger than * LIBUSB_ERROR_BUSY - 这个传输已经提交过了
* the operating system and/or hardware can support (see \ref asynclimits) * LIBUSB_ERROR_NOT_SUPPORTED - 不支持这个传输
* \returns another LIBUSB_ERROR code on other failure * LIBUSB_ERROR_INVALID_PARAM - 传输的字节超过OS或硬件的支持
* 其他LIBUSB_ERROR错误码
*/ */
int API_EXPORTED libusb_submit_transfer(struct libusb_transfer *transfer); int API_EXPORTED libusb_submit_transfer(struct libusb_transfer *transfer);
``` ```
@@ -717,41 +663,96 @@ int API_EXPORTED libusb_submit_transfer(struct libusb_transfer *transfer);
#### 2.9.8 处理事件 #### 2.9.8 处理事件
2个函数 4个函数其中2个没有`completed`后缀的函数过时了
```c ```c
/** \ingroup libusb_poll /** \ingroup libusb_poll
* Handle any pending events * 处理任何"pengding的事件"
* *
* Like libusb_handle_events_timeout_completed(), but without the completed * 使用异步传输函数时提交的tranfer结构体后就返回了。
* parameter, calling this function is equivalent to calling * 可以使用本函数处理这些传输的返回结果。
* libusb_handle_events_timeout_completed() with a NULL completed parameter.
* *
* This function is kept primarily for backwards compatibility. * 如果timeval参数为0本函数会处理"当前、已经pending的事件",然后马上返回。
* All new code should call libusb_handle_events_completed() or
* libusb_handle_events_timeout_completed() to avoid race conditions.
* *
* \param ctx the context to operate on, or NULL for the default context * 如果timeval参数不为0并且当前没有待处理的事件本函数会阻塞以等待事件直到超时。
* \param tv the maximum time to block waiting for events, or an all zero * 在等待过程中,如果事件发生了、或者得到了信号(signal),那么这个函数会提前返回。
* timeval struct for non-blocking mode *
* \returns 0 on success, or a LIBUSB_ERROR code on failure * completed参数用来避免竞争如果它不为NULL:
* 本函数获得"event handling lock"后会判断completed指向的数值
* 如果这个数值非0(表示别的线程已经处理了、已经completed了)
* 则本函数会立刻返回(既然都completed了当然无需再处理)
*
* 参数:
* ctx - context(如果传入NULL则使用默认context)
* tv - 等待事件的最大时间0表示不等待
* completed - 指针可以传入NULL
*
* 返回值:
* 0 - 成功
* LIBUSB_ERROR_INVALID_PARAM - timeval参数无效
* 其他LIBUSB_ERROR错误码
*/
int API_EXPORTED libusb_handle_events_timeout_completed(libusb_context *ctx,
struct timeval *tv, int *completed);
/** \ingroup libusb_poll
* 处理任何"pengding的事件"
*
* 跟libusb_handle_events_timeout_completed()类似,
* 就是调用"libusb_handle_events_timeout_completed(ctx, tv, NULL);"
* 最后的completed参数为NULL。
*
* 这个函数只是为了保持向后兼容新的代码建议使用libusb_handle_events_completed()或
* libusb_handle_events_timeout_completed()
* 这2个新函数可以处理竞争。
*
* 参数:
* ctx - context(如果传入NULL则使用默认context)
* tv - 等待事件的最大时间0表示不等待
*
* 返回值:
* 0 - 成功
* LIBUSB_ERROR_INVALID_PARAM - timeval参数无效
* 其他LIBUSB_ERROR错误码
*/ */
int API_EXPORTED libusb_handle_events_timeout(libusb_context *ctx, int API_EXPORTED libusb_handle_events_timeout(libusb_context *ctx,
struct timeval *tv); struct timeval *tv);
/** \ingroup libusb_poll /** \ingroup libusb_poll
* Handle any pending events in blocking mode. There is currently a timeout * 处理任何"pengding的事件",以阻塞方式处理(blocking mode)
* hard-coded at 60 seconds but we plan to make it unlimited in future. For
* finer control over whether this function is blocking or non-blocking, or
* for control over the timeout, use libusb_handle_events_timeout_completed()
* instead.
* *
* This function is kept primarily for backwards compatibility. * 本函数的内部实现就是调用: libusb_handle_events_timeout_completed(ctx, &tv, completed);
* All new code should call libusb_handle_events_completed() or * 超时时间设置为60秒
* libusb_handle_events_timeout_completed() to avoid race conditions.
* *
* \param ctx the context to operate on, or NULL for the default context * 参数:
* \returns 0 on success, or a LIBUSB_ERROR code on failure * ctx - context(如果传入NULL则使用默认context)
* completed - 指针可以传入NULL
*
* 返回值:
* 0 - 成功
* LIBUSB_ERROR_INVALID_PARAM - timeval参数无效
* 其他LIBUSB_ERROR错误码
*/
int API_EXPORTED libusb_handle_events_completed(libusb_context *ctx,
int *completed);
/** \ingroup libusb_poll
* 处理任何"pengding的事件",以阻塞方式处理(blocking mode)
*
* 本函数的内部实现就是调用: libusb_handle_events_timeout_completed(ctx, &tv, NULL);
* 超时时间设置为60秒
*
* 这个函数只是为了保持向后兼容新的代码建议使用libusb_handle_events_completed()或
* libusb_handle_events_timeout_completed()
* 这2个新函数可以处理竞争。
*
* 参数:
* ctx - context(如果传入NULL则使用默认context)
*
* 返回值:
* 0 - 成功
* LIBUSB_ERROR_INVALID_PARAM - timeval参数无效
* 其他LIBUSB_ERROR错误码
*/ */
int API_EXPORTED libusb_handle_events(libusb_context *ctx); int API_EXPORTED libusb_handle_events(libusb_context *ctx);
``` ```
@@ -764,31 +765,20 @@ int API_EXPORTED libusb_handle_events(libusb_context *ctx);
```c ```c
/** \ingroup libusb_asyncio /** \ingroup libusb_asyncio
* Free a transfer structure. This should be called for all transfers * 释放libusb_transfer结构体
* allocated with libusb_alloc_transfer(). * 前面使用libusb_alloc_transfer()分配的结构体,要使用本函数来释放。
* *
* If the \ref libusb_transfer_flags::LIBUSB_TRANSFER_FREE_BUFFER * 如果libusb_transfer::flagsLIBUSB_TRANSFER_FREE_BUFFER位非0
* "LIBUSB_TRANSFER_FREE_BUFFER" flag is set and the transfer buffer is * 那么会使用free()函数释放ibusb_transfer::buffer
* non-NULL, this function will also free the transfer buffer using the
* standard system memory allocator (e.g. free()).
* *
* It is legal to call this function with a NULL transfer. In this case, * 不能使用本函数释放一个活动的传输结构体(active, 已经提交尚未结束)
* the function will simply return safely.
* *
* It is not legal to free an active transfer (one which has been submitted
* and has not yet completed).
*
* \param transfer the transfer to free
*/ */
void API_EXPORTED libusb_free_transfer(struct libusb_transfer *transfer); void API_EXPORTED libusb_free_transfer(struct libusb_transfer *transfer);
``` ```
## 3. 使用示例 ## 3. 使用示例
在libusb源码的examples目录下有示例程序我们也有一些真实的案列。 在libusb源码的examples目录下有示例程序我们也有一些真实的案列。