From 9491bae4eb37005e1f2c1eeefe2e7ea0016dbbb3 Mon Sep 17 00:00:00 2001 From: weidongshan Date: Thu, 15 Sep 2022 15:10:03 +0800 Subject: [PATCH] tmp update --- IMX6ULL/doc_pic/12_USB/06_libusb的使用.md | 253 +++++++++++++++++++++- 1 file changed, 250 insertions(+), 3 deletions(-) diff --git a/IMX6ULL/doc_pic/12_USB/06_libusb的使用.md b/IMX6ULL/doc_pic/12_USB/06_libusb的使用.md index 3e03dfc..dff432d 100644 --- a/IMX6ULL/doc_pic/12_USB/06_libusb的使用.md +++ b/IMX6ULL/doc_pic/12_USB/06_libusb的使用.md @@ -85,7 +85,248 @@ int API_EXPORTED libusb_init(libusb_context **ctx); #### 2.2.2 获取设备 +可以使用`libusb_get_device_list`取出所有设备,函数接口如下: +```c +/** @ingroup libusb_dev + * Returns a list of USB devices currently attached to the system. This is + * your entry point into finding a USB device to operate. + * + * You are expected to unreference all the devices when you are done with + * them, and then free the list with libusb_free_device_list(). Note that + * 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 + * the resultant list. The list is actually one element larger, as it is + * 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 + * libusb_free_device_list(). + * \returns the number of devices in the outputted list, or any + * \ref libusb_error according to errors encountered by the backend. + */ +ssize_t API_EXPORTED libusb_get_device_list(libusb_context *ctx, + libusb_device ***list); +``` + +调用此函数后,所有设备的信息存入list,然后遍历list,找到想操作的设备。这个函数内部会分配list的空间,所以用完后要释放掉,使用以下函数释放: + +```c +/** \ingroup libusb_dev + * Frees a list of devices previously discovered using + * libusb_get_device_list(). If the unref_devices parameter is set, the + * reference count of each device in the list is decremented by 1. + * \param list the list to free + * \param unref_devices whether to unref the devices in the list + */ +void API_EXPORTED libusb_free_device_list(libusb_device **list, + int unref_devices); +``` + +#### 2.2.3 打开/关闭设备 + +使用libusb_get_device_list得到设备列表后,可以选择里面的某个设备,然后调用libusb_open: + +```c +/** \ingroup libusb_dev + * Open a device and obtain a device handle. A handle allows you to perform + * I/O on the device in question. + * + * Internally, this function adds a reference to the device and makes it + * available to you through libusb_get_device(). This reference is removed + * during libusb_close(). + * + * This is a non-blocking function; no requests are sent over the bus. + * + * \param dev the device to open + * \param dev_handle output location for the returned device handle pointer. Only + * populated when the return code is 0. + * \returns 0 on success + * \returns \ref LIBUSB_ERROR_NO_MEM on memory allocation failure + * \returns \ref LIBUSB_ERROR_ACCESS if the user has insufficient permissions + * \returns \ref LIBUSB_ERROR_NO_DEVICE if the device has been disconnected + * \returns another LIBUSB_ERROR code on other failure + */ +int API_EXPORTED libusb_open(libusb_device *dev, + libusb_device_handle **dev_handle); +``` + +使用libusb_open函数打开USB设备后,可以得到一个句柄:libusb_device_handle。以后调用各种数据传输函数时,就是使用libusb_device_handle。 + +使用完毕后,调用libusb_close关闭设备,函数原型如下: + +```c +/** \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() on the given device. + * + * This is a non-blocking function; no requests are sent over the bus. + * + * \param dev_handle the device handle to close + */ +void API_EXPORTED libusb_close(libusb_device_handle *dev_handle); +``` + + + +#### 2.2.4 根据ID打开设备 + +如果知道设备的VID、PID,那么可以使用libusb_open_device_with_vid_pid来找到它、打开它。这个函数的内部,先使用`libusb_get_device_list`列出所有设备,然后遍历它们根据ID选出设备,接着调用libusb_open打开它,最后调用libusb_free_device_list释放设备。 + +libusb_open_device_with_vid_pid函数原型如下: + +```c +/** \ingroup libusb_dev + * Convenience function for finding a device with a particular + * idVendor/idProduct combination. This function is intended + * for those scenarios where you are using libusb to knock up a quick test + * 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 + * 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 + * \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 + * or if the device could not be found. */ +DEFAULT_VISIBILITY +libusb_device_handle * LIBUSB_CALL libusb_open_device_with_vid_pid( + libusb_context *ctx, uint16_t vendor_id, uint16_t product_id); +``` + + + +#### 2.2.5 detach/attach驱动 + +使用libusb访问USB设备时,需要先移除(detach)设备原来的驱动程序,然后安装(attach)libusb专用的驱动程序。有两种办法: + +* 方法1: + + ```c + // 只是设置一个标记位表示libusb_claim_interface + // 使用libusb_claim_interface时会detach原来的驱动 + libusb_set_auto_detach_kernel_driver(hdev, 1); + + // 给interface安装驱动程序,标记这个interface已经被使用认领了 + libusb_claim_interface(hdev, interface_number); + ``` + +* 方法2: + + ```c + // detach原来的驱动 + libusb_detach_kernel_driver(hdev, interface_number); + + // 给interface安装驱动程序,标记这个interface已经被使用认领了 + libusb_claim_interface(hdev, interface_number); + ``` + + + +函数`libusb_detach_kernel_driver`原型如下: + +```c + * Detach a kernel driver from an interface. If successful, you will then be + * able to claim the interface and perform I/O. + * + * This functionality is not available on Windows. + * + * 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 + * not detach it and return \ref LIBUSB_ERROR_NOT_FOUND. + * + * \param dev_handle a device handle + * \param interface_number the interface to detach the driver from + * \returns 0 on success + * \returns \ref LIBUSB_ERROR_NOT_FOUND if no kernel driver was active + * \returns \ref LIBUSB_ERROR_INVALID_PARAM if the interface does not exist + * \returns \ref LIBUSB_ERROR_NO_DEVICE if the device has been disconnected + * \returns \ref LIBUSB_ERROR_NOT_SUPPORTED on platforms where the functionality + * 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 interface_number); +``` + + + +函数`libusb_claim_interface`原型如下: + +```c +/** \ingroup libusb_dev + * Claim an interface on a given device handle. You must claim the interface + * you wish to use before you can perform I/O on any of its endpoints. + * + * It is legal to attempt to claim an already-claimed interface, in which + * case libusb just returns 0 without doing anything. + * + * If auto_detach_kernel_driver is set to 1 for dev, the kernel driver + * will be detached if necessary, on failure the detach error is returned. + * + * Claiming of interfaces is a purely logical operation; it does not cause + * 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. + * + * \param dev_handle a device handle + * \param interface_number the bInterfaceNumber of the interface you + * wish to claim + * \returns 0 on success + * \returns \ref LIBUSB_ERROR_NOT_FOUND if the requested interface does not exist + * \returns \ref LIBUSB_ERROR_BUSY if another program or driver has claimed the + * 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 interface_number); +``` + + + +使用完USB设备后,在调用libusb_close之前,应该`libusb_release_interface`释放接口: + +```c +/** \ingroup libusb_dev + * Release an interface previously claimed with libusb_claim_interface(). You + * should release all claimed interfaces before closing a device handle. + * + * This is a blocking function. A SET_INTERFACE control request will be sent + * to the device, resetting interface state to the first alternate setting. + * + * If auto_detach_kernel_driver is set to 1 for dev, the kernel + * driver will be re-attached after releasing the interface. + * + * \param dev_handle a device handle + * \param interface_number the bInterfaceNumber of the + * previously-claimed interface + * \returns 0 on success + * \returns \ref LIBUSB_ERROR_NOT_FOUND if the interface was not claimed + * \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 interface_number); +``` + + + +#### 2.2.6 描述符相关函数 @@ -127,11 +368,17 @@ dnw是s3c2440时代的工具,使用它可以从PC给开发板传输文件。 -### 3.2 openocd +### 3.2 adb + + + + + +### 3.3 openocd openocd是一个开源的USB JTAG调试软件,它也是使用libusb,涉及USB的操作代码如下。 -#### 3.2.1 找到设备 +#### 3.3.1 找到设备 ```c static int cmsis_dap_usb_open(struct cmsis_dap *dap, uint16_t vids[], uint16_t pids[], const char *serial) @@ -473,7 +720,7 @@ static int cmsis_dap_usb_open(struct cmsis_dap *dap, uint16_t vids[], uint16_t p -#### 3.2.2 读写数据 +#### 3.3.2 读写数据 ```c static int cmsis_dap_usb_read(struct cmsis_dap *dap, int timeout_ms)