使用libusb异步函数读取USB鼠标、上机实验

This commit is contained in:
weidongshan
2022-09-29 14:35:24 +08:00
parent 7930aad9fa
commit 009d24494f
11 changed files with 1369 additions and 34 deletions

View File

@@ -208,7 +208,149 @@ USB规范里为每个按键定义了16位的按键值注意它是16位的
### 2.1 编写源码
```c
#include <errno.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <libusb-1.0/libusb.h>
int main(int argc, char **argv)
{
int err;
libusb_device *dev, **devs;
int num_devices;
int endpoint;
int interface_num;
int found = 0;
int transferred;
int count = 0;
unsigned char buffer[16];
struct libusb_config_descriptor *config_desc;
struct libusb_device_handle *dev_handle = NULL;
/* libusb_init */
err = libusb_init(NULL);
if (err < 0) {
fprintf(stderr, "failed to initialise libusb %d - %s\n", err, libusb_strerror(err));
exit(1);
}
/* get device list */
if ((num_devices = libusb_get_device_list(NULL, &devs)) < 0) {
fprintf(stderr, "libusb_get_device_list() failed\n");
libusb_exit(NULL);
exit(1);
}
fprintf(stdout, "libusb_get_device_list() ok\n");
/* for each device, get config descriptor */
for (int i = 0; i < num_devices; i++) {
dev = devs[i];
/* parse interface descriptor, find usb mouse */
err = libusb_get_config_descriptor(dev, 0, &config_desc);
if (err) {
fprintf(stderr, "could not get configuration descriptor\n");
continue;
}
fprintf(stdout, "libusb_get_config_descriptor() ok\n");
for (int interface = 0; interface < config_desc->bNumInterfaces; interface++) {
const struct libusb_interface_descriptor *intf_desc = &config_desc->interface[interface].altsetting[0];
interface_num = intf_desc->bInterfaceNumber;
if (intf_desc->bInterfaceClass != 3 || intf_desc->bInterfaceProtocol != 2)
continue;
else
{
/* 找到了USB鼠标 */
fprintf(stdout, "find usb mouse ok\n");
for (int ep = 0; ep < intf_desc->bNumEndpoints; ep++)
{
if ((intf_desc->endpoint[ep].bmAttributes & 3) == LIBUSB_TRANSFER_TYPE_INTERRUPT ||
(intf_desc->endpoint[ep].bEndpointAddress & 0x80) == LIBUSB_ENDPOINT_IN) {
/* 找到了输入的中断端点 */
fprintf(stdout, "find in int endpoint\n");
endpoint = intf_desc->endpoint[ep].bEndpointAddress;
found = 1;
break;
}
}
}
if (found)
break;
}
libusb_free_config_descriptor(config_desc);
if (found)
break;
}
if (!found)
{
/* free device list */
libusb_free_device_list(devs, 1);
libusb_exit(NULL);
exit(1);
}
if (found)
{
/* libusb_open */
err = libusb_open(dev, &dev_handle);
if (err)
{
fprintf(stderr, "failed to open usb mouse\n");
exit(1);
}
fprintf(stdout, "libusb_open ok\n");
}
/* free device list */
libusb_free_device_list(devs, 1);
/* claim interface */
libusb_set_auto_detach_kernel_driver(dev_handle, 1);
err = libusb_claim_interface(dev_handle, interface_num);
if (err)
{
fprintf(stderr, "failed to libusb_claim_interface\n");
exit(1);
}
fprintf(stdout, "libusb_claim_interface ok\n");
/* libusb_interrupt_transfer */
while (1)
{
err = libusb_interrupt_transfer(dev_handle, endpoint, buffer, 16, &transferred, 5000);
if (!err) {
/* parser data */
printf("%04d datas: ", count++);
for (int i = 0; i < transferred; i++)
{
printf("%02x ", buffer[i]);
}
printf("\n");
} else if (err == LIBUSB_ERROR_TIMEOUT){
fprintf(stderr, "libusb_interrupt_transfer timout\n");
} else {
fprintf(stderr, "libusb_interrupt_transfer err : %d\n", err);
//exit(1);
}
}
/* libusb_close */
libusb_release_interface(dev_handle, interface_num);
libusb_close(dev_handle);
libusb_exit(NULL);
}
```
@@ -230,7 +372,7 @@ gcc -o readmouse readmouse.c -lusb-1.0
#### 2.2.2 在开发板上实验
#### 2.2.2 在IMX6ULL开发板上实验
@@ -269,13 +411,295 @@ gcc -o readmouse readmouse.c -lusb-1.0
* 交叉编译app
```shell
arm-buildroot-linux-gnueabihf-gcc -o readmouse readmouse.c -lusb-1.0
arm-buildroot-linux-gnueabihf-gcc -o readmouse.c -lusb-1.0
```
* 在开发板上插入USB鼠标执行命令
```shell
./readmouse
```
#### 2.2.3 在STM32MP157开发板上实验
* STM32MP157的工具链里已经含有libusb所以无需交叉编译、安装libusb
* 交叉编译app
```shell
arm-buildroot-linux-gnueabihf-gcc -o readmouse readmouse.c -lusb-1.0
```
* 在开发板上插入USB鼠标执行命令
```shell
./readmouse
```
## 3. 使用异步接口读取鼠标数据
源码在GIT仓库如下位置
![image-20220929092859668](pic/61_libusb_async_usbmouse_src.png)
### 3.1 编写源码
```c
#include <errno.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <libusb-1.0/libusb.h>
struct usb_mouse {
struct libusb_device_handle *handle;
int interface;
int endpoint;
unsigned char buf[16];
int transferred;
struct libusb_transfer *transfer;
struct usb_mouse *next;
};
static struct usb_mouse *usb_mouse_list;
void free_usb_mouses(struct usb_mouse *usb_mouse_list)
{
struct usb_mouse *pnext;
while (usb_mouse_list)
{
pnext = usb_mouse_list->next;
free(usb_mouse_list);
usb_mouse_list = pnext;
}
}
/* */
int get_usb_mouses(libusb_device **devs, int num_devices, struct usb_mouse **usb_mouse_list)
{
int err;
libusb_device *dev;
int endpoint;
int interface_num;
struct libusb_config_descriptor *config_desc;
struct libusb_device_handle *dev_handle = NULL;
struct usb_mouse *pmouse;
struct usb_mouse *list = NULL;
int mouse_cnt = 0;
/* for each device, get config descriptor */
for (int i = 0; i < num_devices; i++) {
dev = devs[i];
/* parse interface descriptor, find usb mouse */
err = libusb_get_config_descriptor(dev, 0, &config_desc);
if (err) {
fprintf(stderr, "could not get configuration descriptor\n");
continue;
}
fprintf(stdout, "libusb_get_config_descriptor() ok\n");
for (int interface = 0; interface < config_desc->bNumInterfaces; interface++) {
const struct libusb_interface_descriptor *intf_desc = &config_desc->interface[interface].altsetting[0];
interface_num = intf_desc->bInterfaceNumber;
if (intf_desc->bInterfaceClass != 3 || intf_desc->bInterfaceProtocol != 2)
continue;
else
{
/* 找到了USB鼠标 */
fprintf(stdout, "find usb mouse ok\n");
for (int ep = 0; ep < intf_desc->bNumEndpoints; ep++)
{
if ((intf_desc->endpoint[ep].bmAttributes & 3) == LIBUSB_TRANSFER_TYPE_INTERRUPT ||
(intf_desc->endpoint[ep].bEndpointAddress & 0x80) == LIBUSB_ENDPOINT_IN) {
/* 找到了输入的中断端点 */
fprintf(stdout, "find in int endpoint\n");
endpoint = intf_desc->endpoint[ep].bEndpointAddress;
/* libusb_open */
err = libusb_open(dev, &dev_handle);
if (err)
{
fprintf(stderr, "failed to open usb mouse\n");
return -1;
}
fprintf(stdout, "libusb_open ok\n");
/* 记录下来: 放入链表 */
pmouse = malloc(sizeof(struct usb_mouse));
if (!pmouse)
{
fprintf(stderr, "can not malloc\n");
return -1;
}
pmouse->endpoint = endpoint;
pmouse->interface = interface_num;
pmouse->handle = dev_handle;
pmouse->next = NULL;
if (!list)
list = pmouse;
else
{
pmouse->next = list;
list = pmouse;
}
mouse_cnt++;
break;
}
}
}
}
libusb_free_config_descriptor(config_desc);
}
*usb_mouse_list = list;
return mouse_cnt;
}
static void mouse_irq(struct libusb_transfer *transfer)
{
static int count = 0;
if (transfer->status == LIBUSB_TRANSFER_COMPLETED)
{
/* parser data */
printf("%04d datas: ", count++);
for (int i = 0; i < transfer->actual_length; i++)
{
printf("%02x ", transfer->buffer[i]);
}
printf("\n");
}
if (libusb_submit_transfer(transfer) < 0)
{
fprintf(stderr, "libusb_submit_transfer err\n");
}
}
int main(int argc, char **argv)
{
int err;
libusb_device **devs;
int num_devices, num_mouse;
struct usb_mouse *pmouse;
/* libusb_init */
err = libusb_init(NULL);
if (err < 0) {
fprintf(stderr, "failed to initialise libusb %d - %s\n", err, libusb_strerror(err));
exit(1);
}
/* get device list */
if ((num_devices = libusb_get_device_list(NULL, &devs)) < 0) {
fprintf(stderr, "libusb_get_device_list() failed\n");
libusb_exit(NULL);
exit(1);
}
fprintf(stdout, "libusb_get_device_list() ok\n");
/* get usb mouse */
num_mouse = get_usb_mouses(devs, num_devices, &usb_mouse_list);
if (num_mouse <= 0)
{
/* free device list */
libusb_free_device_list(devs, 1);
libusb_exit(NULL);
exit(1);
}
fprintf(stdout, "get %d mouses\n", num_mouse);
/* free device list */
libusb_free_device_list(devs, 1);
/* claim interface */
pmouse = usb_mouse_list;
while (pmouse)
{
libusb_set_auto_detach_kernel_driver(pmouse->handle, 1);
err = libusb_claim_interface(pmouse->handle, pmouse->interface);
if (err)
{
fprintf(stderr, "failed to libusb_claim_interface\n");
exit(1);
}
pmouse = pmouse->next;
}
fprintf(stdout, "libusb_claim_interface ok\n");
/* for each mouse, alloc transfer, fill transfer, submit transfer */
pmouse = usb_mouse_list;
while (pmouse)
{
/* alloc transfer */
pmouse->transfer = libusb_alloc_transfer(0);
/* fill transfer */
libusb_fill_interrupt_transfer(pmouse->transfer, pmouse->handle, pmouse->endpoint, pmouse->buf,
sizeof(pmouse->buf), mouse_irq, pmouse, 0);
/* submit transfer */
libusb_submit_transfer(pmouse->transfer);
pmouse = pmouse->next;
}
/* handle events */
while (1) {
struct timeval tv = { 5, 0 };
int r;
r = libusb_handle_events_timeout(NULL, &tv);
if (r < 0) {
fprintf(stderr, "libusb_handle_events_timeout err\n");
break;
}
}
/* libusb_close */
pmouse = usb_mouse_list;
while (pmouse)
{
libusb_release_interface(pmouse->handle, pmouse->interface);
libusb_close(pmouse->handle);
pmouse = pmouse->next;
}
free_usb_mouses(usb_mouse_list);
libusb_exit(NULL);
}
```
### 3.2 在开发板上实验

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

View File

@@ -8,8 +8,8 @@
int main(int argc, char **argv)
{
int err;
libusb_device *dev, **devs;
int err;
libusb_device *dev, **devs;
int num_devices;
int endpoint;
int interface_num;
@@ -22,11 +22,11 @@ int main(int argc, char **argv)
/* libusb_init */
err = libusb_init(NULL);
if (err < 0) {
fprintf(stderr, "failed to initialise libusb %d - %s\n", err, libusb_strerror(err));
exit(1);
}
err = libusb_init(NULL);
if (err < 0) {
fprintf(stderr, "failed to initialise libusb %d - %s\n", err, libusb_strerror(err));
exit(1);
}
/* get device list */
if ((num_devices = libusb_get_device_list(NULL, &devs)) < 0) {
@@ -37,7 +37,7 @@ int main(int argc, char **argv)
fprintf(stdout, "libusb_get_device_list() ok\n");
/* for each device, get config descriptor */
for (int i = 0; i < num_devices; i++) {
for (int i = 0; i < num_devices; i++) {
dev = devs[i];
/* parse interface descriptor, find usb mouse */
@@ -80,7 +80,7 @@ int main(int argc, char **argv)
libusb_free_config_descriptor(config_desc);
if (found)
break;
break;
}
if (!found)
@@ -118,21 +118,21 @@ int main(int argc, char **argv)
/* libusb_interrupt_transfer */
while (1)
{
err = libusb_interrupt_transfer(dev_handle, endpoint, buffer, 16, &transferred, 5000);
if (!err) {
{
err = libusb_interrupt_transfer(dev_handle, endpoint, buffer, 16, &transferred, 5000);
if (!err) {
/* parser data */
printf("%04d datas: ", count++);
for (int i = 0; i < transferred; i++)
{
printf("%02x ", buffer[i]);
}
printf("\n");
printf("\n");
} else if (err == LIBUSB_ERROR_TIMEOUT){
fprintf(stderr, "libusb_interrupt_transfer timout\n");
fprintf(stderr, "libusb_interrupt_transfer timout\n");
} else {
fprintf(stderr, "libusb_interrupt_transfer err : %d\n", err);
//exit(1);
//exit(1);
}
}

View File

@@ -0,0 +1,240 @@
#include <errno.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <libusb-1.0/libusb.h>
struct usb_mouse {
struct libusb_device_handle *handle;
int interface;
int endpoint;
unsigned char buf[16];
int transferred;
struct libusb_transfer *transfer;
struct usb_mouse *next;
};
static struct usb_mouse *usb_mouse_list;
void free_usb_mouses(struct usb_mouse *usb_mouse_list)
{
struct usb_mouse *pnext;
while (usb_mouse_list)
{
pnext = usb_mouse_list->next;
free(usb_mouse_list);
usb_mouse_list = pnext;
}
}
/* */
int get_usb_mouses(libusb_device **devs, int num_devices, struct usb_mouse **usb_mouse_list)
{
int err;
libusb_device *dev;
int endpoint;
int interface_num;
struct libusb_config_descriptor *config_desc;
struct libusb_device_handle *dev_handle = NULL;
struct usb_mouse *pmouse;
struct usb_mouse *list = NULL;
int mouse_cnt = 0;
/* for each device, get config descriptor */
for (int i = 0; i < num_devices; i++) {
dev = devs[i];
/* parse interface descriptor, find usb mouse */
err = libusb_get_config_descriptor(dev, 0, &config_desc);
if (err) {
fprintf(stderr, "could not get configuration descriptor\n");
continue;
}
fprintf(stdout, "libusb_get_config_descriptor() ok\n");
for (int interface = 0; interface < config_desc->bNumInterfaces; interface++) {
const struct libusb_interface_descriptor *intf_desc = &config_desc->interface[interface].altsetting[0];
interface_num = intf_desc->bInterfaceNumber;
if (intf_desc->bInterfaceClass != 3 || intf_desc->bInterfaceProtocol != 2)
continue;
else
{
/* 找到了USB鼠标 */
fprintf(stdout, "find usb mouse ok\n");
for (int ep = 0; ep < intf_desc->bNumEndpoints; ep++)
{
if ((intf_desc->endpoint[ep].bmAttributes & 3) == LIBUSB_TRANSFER_TYPE_INTERRUPT ||
(intf_desc->endpoint[ep].bEndpointAddress & 0x80) == LIBUSB_ENDPOINT_IN) {
/* 找到了输入的中断端点 */
fprintf(stdout, "find in int endpoint\n");
endpoint = intf_desc->endpoint[ep].bEndpointAddress;
/* libusb_open */
err = libusb_open(dev, &dev_handle);
if (err)
{
fprintf(stderr, "failed to open usb mouse\n");
return -1;
}
fprintf(stdout, "libusb_open ok\n");
/* 记录下来: 放入链表 */
pmouse = malloc(sizeof(struct usb_mouse));
if (!pmouse)
{
fprintf(stderr, "can not malloc\n");
return -1;
}
pmouse->endpoint = endpoint;
pmouse->interface = interface_num;
pmouse->handle = dev_handle;
pmouse->next = NULL;
if (!list)
list = pmouse;
else
{
pmouse->next = list;
list = pmouse;
}
mouse_cnt++;
break;
}
}
}
}
libusb_free_config_descriptor(config_desc);
}
*usb_mouse_list = list;
return mouse_cnt;
}
static void mouse_irq(struct libusb_transfer *transfer)
{
static int count = 0;
if (transfer->status == LIBUSB_TRANSFER_COMPLETED)
{
/* parser data */
printf("%04d datas: ", count++);
for (int i = 0; i < transfer->actual_length; i++)
{
printf("%02x ", transfer->buffer[i]);
}
printf("\n");
}
if (libusb_submit_transfer(transfer) < 0)
{
fprintf(stderr, "libusb_submit_transfer err\n");
}
}
int main(int argc, char **argv)
{
int err;
libusb_device **devs;
int num_devices, num_mouse;
struct usb_mouse *pmouse;
/* libusb_init */
err = libusb_init(NULL);
if (err < 0) {
fprintf(stderr, "failed to initialise libusb %d - %s\n", err, libusb_strerror(err));
exit(1);
}
/* get device list */
if ((num_devices = libusb_get_device_list(NULL, &devs)) < 0) {
fprintf(stderr, "libusb_get_device_list() failed\n");
libusb_exit(NULL);
exit(1);
}
fprintf(stdout, "libusb_get_device_list() ok\n");
/* get usb mouse */
num_mouse = get_usb_mouses(devs, num_devices, &usb_mouse_list);
if (num_mouse <= 0)
{
/* free device list */
libusb_free_device_list(devs, 1);
libusb_exit(NULL);
exit(1);
}
fprintf(stdout, "get %d mouses\n", num_mouse);
/* free device list */
libusb_free_device_list(devs, 1);
/* claim interface */
pmouse = usb_mouse_list;
while (pmouse)
{
libusb_set_auto_detach_kernel_driver(pmouse->handle, 1);
err = libusb_claim_interface(pmouse->handle, pmouse->interface);
if (err)
{
fprintf(stderr, "failed to libusb_claim_interface\n");
exit(1);
}
pmouse = pmouse->next;
}
fprintf(stdout, "libusb_claim_interface ok\n");
/* for each mouse, alloc transfer, fill transfer, submit transfer */
pmouse = usb_mouse_list;
while (pmouse)
{
/* alloc transfer */
pmouse->transfer = libusb_alloc_transfer(0);
/* fill transfer */
libusb_fill_interrupt_transfer(pmouse->transfer, pmouse->handle, pmouse->endpoint, pmouse->buf,
sizeof(pmouse->buf), mouse_irq, pmouse, 0);
/* submit transfer */
libusb_submit_transfer(pmouse->transfer);
pmouse = pmouse->next;
}
/* handle events */
while (1) {
struct timeval tv = { 5, 0 };
int r;
r = libusb_handle_events_timeout(NULL, &tv);
if (r < 0) {
fprintf(stderr, "libusb_handle_events_timeout err\n");
break;
}
}
/* libusb_close */
pmouse = usb_mouse_list;
while (pmouse)
{
libusb_release_interface(pmouse->handle, pmouse->interface);
libusb_close(pmouse->handle);
pmouse = pmouse->next;
}
free_usb_mouses(usb_mouse_list);
libusb_exit(NULL);
}

View File

@@ -675,6 +675,13 @@ git clone https://e.coding.net/weidongshan/linux/doc_and_source_for_drivers.git
07.5_上机实验3_在板上实验
```
* 2022.09.28 发布"USB子系统"
```shell
07.6_使用libusb异步函数读取USB鼠标
07.7_异步方式上机实验
```

View File

@@ -208,7 +208,149 @@ USB规范里为每个按键定义了16位的按键值注意它是16位的
### 2.1 编写源码
```c
#include <errno.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <libusb-1.0/libusb.h>
int main(int argc, char **argv)
{
int err;
libusb_device *dev, **devs;
int num_devices;
int endpoint;
int interface_num;
int found = 0;
int transferred;
int count = 0;
unsigned char buffer[16];
struct libusb_config_descriptor *config_desc;
struct libusb_device_handle *dev_handle = NULL;
/* libusb_init */
err = libusb_init(NULL);
if (err < 0) {
fprintf(stderr, "failed to initialise libusb %d - %s\n", err, libusb_strerror(err));
exit(1);
}
/* get device list */
if ((num_devices = libusb_get_device_list(NULL, &devs)) < 0) {
fprintf(stderr, "libusb_get_device_list() failed\n");
libusb_exit(NULL);
exit(1);
}
fprintf(stdout, "libusb_get_device_list() ok\n");
/* for each device, get config descriptor */
for (int i = 0; i < num_devices; i++) {
dev = devs[i];
/* parse interface descriptor, find usb mouse */
err = libusb_get_config_descriptor(dev, 0, &config_desc);
if (err) {
fprintf(stderr, "could not get configuration descriptor\n");
continue;
}
fprintf(stdout, "libusb_get_config_descriptor() ok\n");
for (int interface = 0; interface < config_desc->bNumInterfaces; interface++) {
const struct libusb_interface_descriptor *intf_desc = &config_desc->interface[interface].altsetting[0];
interface_num = intf_desc->bInterfaceNumber;
if (intf_desc->bInterfaceClass != 3 || intf_desc->bInterfaceProtocol != 2)
continue;
else
{
/* 找到了USB鼠标 */
fprintf(stdout, "find usb mouse ok\n");
for (int ep = 0; ep < intf_desc->bNumEndpoints; ep++)
{
if ((intf_desc->endpoint[ep].bmAttributes & 3) == LIBUSB_TRANSFER_TYPE_INTERRUPT ||
(intf_desc->endpoint[ep].bEndpointAddress & 0x80) == LIBUSB_ENDPOINT_IN) {
/* 找到了输入的中断端点 */
fprintf(stdout, "find in int endpoint\n");
endpoint = intf_desc->endpoint[ep].bEndpointAddress;
found = 1;
break;
}
}
}
if (found)
break;
}
libusb_free_config_descriptor(config_desc);
if (found)
break;
}
if (!found)
{
/* free device list */
libusb_free_device_list(devs, 1);
libusb_exit(NULL);
exit(1);
}
if (found)
{
/* libusb_open */
err = libusb_open(dev, &dev_handle);
if (err)
{
fprintf(stderr, "failed to open usb mouse\n");
exit(1);
}
fprintf(stdout, "libusb_open ok\n");
}
/* free device list */
libusb_free_device_list(devs, 1);
/* claim interface */
libusb_set_auto_detach_kernel_driver(dev_handle, 1);
err = libusb_claim_interface(dev_handle, interface_num);
if (err)
{
fprintf(stderr, "failed to libusb_claim_interface\n");
exit(1);
}
fprintf(stdout, "libusb_claim_interface ok\n");
/* libusb_interrupt_transfer */
while (1)
{
err = libusb_interrupt_transfer(dev_handle, endpoint, buffer, 16, &transferred, 5000);
if (!err) {
/* parser data */
printf("%04d datas: ", count++);
for (int i = 0; i < transferred; i++)
{
printf("%02x ", buffer[i]);
}
printf("\n");
} else if (err == LIBUSB_ERROR_TIMEOUT){
fprintf(stderr, "libusb_interrupt_transfer timout\n");
} else {
fprintf(stderr, "libusb_interrupt_transfer err : %d\n", err);
//exit(1);
}
}
/* libusb_close */
libusb_release_interface(dev_handle, interface_num);
libusb_close(dev_handle);
libusb_exit(NULL);
}
```
@@ -230,7 +372,7 @@ gcc -o readmouse readmouse.c -lusb-1.0
#### 2.2.2 在开发板上实验
#### 2.2.2 在IMX6ULL开发板上实验
@@ -269,13 +411,295 @@ gcc -o readmouse readmouse.c -lusb-1.0
* 交叉编译app
```shell
arm-buildroot-linux-gnueabihf-gcc -o readmouse readmouse.c -lusb-1.0
arm-buildroot-linux-gnueabihf-gcc -o readmouse.c -lusb-1.0
```
* 在开发板上插入USB鼠标执行命令
```shell
./readmouse
```
#### 2.2.3 在STM32MP157开发板上实验
* STM32MP157的工具链里已经含有libusb所以无需交叉编译、安装libusb
* 交叉编译app
```shell
arm-buildroot-linux-gnueabihf-gcc -o readmouse readmouse.c -lusb-1.0
```
* 在开发板上插入USB鼠标执行命令
```shell
./readmouse
```
## 3. 使用异步接口读取鼠标数据
源码在GIT仓库如下位置
![image-20220929092859668](pic/61_libusb_async_usbmouse_src.png)
### 3.1 编写源码
```c
#include <errno.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <libusb-1.0/libusb.h>
struct usb_mouse {
struct libusb_device_handle *handle;
int interface;
int endpoint;
unsigned char buf[16];
int transferred;
struct libusb_transfer *transfer;
struct usb_mouse *next;
};
static struct usb_mouse *usb_mouse_list;
void free_usb_mouses(struct usb_mouse *usb_mouse_list)
{
struct usb_mouse *pnext;
while (usb_mouse_list)
{
pnext = usb_mouse_list->next;
free(usb_mouse_list);
usb_mouse_list = pnext;
}
}
/* */
int get_usb_mouses(libusb_device **devs, int num_devices, struct usb_mouse **usb_mouse_list)
{
int err;
libusb_device *dev;
int endpoint;
int interface_num;
struct libusb_config_descriptor *config_desc;
struct libusb_device_handle *dev_handle = NULL;
struct usb_mouse *pmouse;
struct usb_mouse *list = NULL;
int mouse_cnt = 0;
/* for each device, get config descriptor */
for (int i = 0; i < num_devices; i++) {
dev = devs[i];
/* parse interface descriptor, find usb mouse */
err = libusb_get_config_descriptor(dev, 0, &config_desc);
if (err) {
fprintf(stderr, "could not get configuration descriptor\n");
continue;
}
fprintf(stdout, "libusb_get_config_descriptor() ok\n");
for (int interface = 0; interface < config_desc->bNumInterfaces; interface++) {
const struct libusb_interface_descriptor *intf_desc = &config_desc->interface[interface].altsetting[0];
interface_num = intf_desc->bInterfaceNumber;
if (intf_desc->bInterfaceClass != 3 || intf_desc->bInterfaceProtocol != 2)
continue;
else
{
/* 找到了USB鼠标 */
fprintf(stdout, "find usb mouse ok\n");
for (int ep = 0; ep < intf_desc->bNumEndpoints; ep++)
{
if ((intf_desc->endpoint[ep].bmAttributes & 3) == LIBUSB_TRANSFER_TYPE_INTERRUPT ||
(intf_desc->endpoint[ep].bEndpointAddress & 0x80) == LIBUSB_ENDPOINT_IN) {
/* 找到了输入的中断端点 */
fprintf(stdout, "find in int endpoint\n");
endpoint = intf_desc->endpoint[ep].bEndpointAddress;
/* libusb_open */
err = libusb_open(dev, &dev_handle);
if (err)
{
fprintf(stderr, "failed to open usb mouse\n");
return -1;
}
fprintf(stdout, "libusb_open ok\n");
/* 记录下来: 放入链表 */
pmouse = malloc(sizeof(struct usb_mouse));
if (!pmouse)
{
fprintf(stderr, "can not malloc\n");
return -1;
}
pmouse->endpoint = endpoint;
pmouse->interface = interface_num;
pmouse->handle = dev_handle;
pmouse->next = NULL;
if (!list)
list = pmouse;
else
{
pmouse->next = list;
list = pmouse;
}
mouse_cnt++;
break;
}
}
}
}
libusb_free_config_descriptor(config_desc);
}
*usb_mouse_list = list;
return mouse_cnt;
}
static void mouse_irq(struct libusb_transfer *transfer)
{
static int count = 0;
if (transfer->status == LIBUSB_TRANSFER_COMPLETED)
{
/* parser data */
printf("%04d datas: ", count++);
for (int i = 0; i < transfer->actual_length; i++)
{
printf("%02x ", transfer->buffer[i]);
}
printf("\n");
}
if (libusb_submit_transfer(transfer) < 0)
{
fprintf(stderr, "libusb_submit_transfer err\n");
}
}
int main(int argc, char **argv)
{
int err;
libusb_device **devs;
int num_devices, num_mouse;
struct usb_mouse *pmouse;
/* libusb_init */
err = libusb_init(NULL);
if (err < 0) {
fprintf(stderr, "failed to initialise libusb %d - %s\n", err, libusb_strerror(err));
exit(1);
}
/* get device list */
if ((num_devices = libusb_get_device_list(NULL, &devs)) < 0) {
fprintf(stderr, "libusb_get_device_list() failed\n");
libusb_exit(NULL);
exit(1);
}
fprintf(stdout, "libusb_get_device_list() ok\n");
/* get usb mouse */
num_mouse = get_usb_mouses(devs, num_devices, &usb_mouse_list);
if (num_mouse <= 0)
{
/* free device list */
libusb_free_device_list(devs, 1);
libusb_exit(NULL);
exit(1);
}
fprintf(stdout, "get %d mouses\n", num_mouse);
/* free device list */
libusb_free_device_list(devs, 1);
/* claim interface */
pmouse = usb_mouse_list;
while (pmouse)
{
libusb_set_auto_detach_kernel_driver(pmouse->handle, 1);
err = libusb_claim_interface(pmouse->handle, pmouse->interface);
if (err)
{
fprintf(stderr, "failed to libusb_claim_interface\n");
exit(1);
}
pmouse = pmouse->next;
}
fprintf(stdout, "libusb_claim_interface ok\n");
/* for each mouse, alloc transfer, fill transfer, submit transfer */
pmouse = usb_mouse_list;
while (pmouse)
{
/* alloc transfer */
pmouse->transfer = libusb_alloc_transfer(0);
/* fill transfer */
libusb_fill_interrupt_transfer(pmouse->transfer, pmouse->handle, pmouse->endpoint, pmouse->buf,
sizeof(pmouse->buf), mouse_irq, pmouse, 0);
/* submit transfer */
libusb_submit_transfer(pmouse->transfer);
pmouse = pmouse->next;
}
/* handle events */
while (1) {
struct timeval tv = { 5, 0 };
int r;
r = libusb_handle_events_timeout(NULL, &tv);
if (r < 0) {
fprintf(stderr, "libusb_handle_events_timeout err\n");
break;
}
}
/* libusb_close */
pmouse = usb_mouse_list;
while (pmouse)
{
libusb_release_interface(pmouse->handle, pmouse->interface);
libusb_close(pmouse->handle);
pmouse = pmouse->next;
}
free_usb_mouses(usb_mouse_list);
libusb_exit(NULL);
}
```
### 3.2 在开发板上实验

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

View File

@@ -8,8 +8,8 @@
int main(int argc, char **argv)
{
int err;
libusb_device *dev, **devs;
int err;
libusb_device *dev, **devs;
int num_devices;
int endpoint;
int interface_num;
@@ -22,11 +22,11 @@ int main(int argc, char **argv)
/* libusb_init */
err = libusb_init(NULL);
if (err < 0) {
fprintf(stderr, "failed to initialise libusb %d - %s\n", err, libusb_strerror(err));
exit(1);
}
err = libusb_init(NULL);
if (err < 0) {
fprintf(stderr, "failed to initialise libusb %d - %s\n", err, libusb_strerror(err));
exit(1);
}
/* get device list */
if ((num_devices = libusb_get_device_list(NULL, &devs)) < 0) {
@@ -37,7 +37,7 @@ int main(int argc, char **argv)
fprintf(stdout, "libusb_get_device_list() ok\n");
/* for each device, get config descriptor */
for (int i = 0; i < num_devices; i++) {
for (int i = 0; i < num_devices; i++) {
dev = devs[i];
/* parse interface descriptor, find usb mouse */
@@ -80,7 +80,7 @@ int main(int argc, char **argv)
libusb_free_config_descriptor(config_desc);
if (found)
break;
break;
}
if (!found)
@@ -118,21 +118,21 @@ int main(int argc, char **argv)
/* libusb_interrupt_transfer */
while (1)
{
err = libusb_interrupt_transfer(dev_handle, endpoint, buffer, 16, &transferred, 5000);
if (!err) {
{
err = libusb_interrupt_transfer(dev_handle, endpoint, buffer, 16, &transferred, 5000);
if (!err) {
/* parser data */
printf("%04d datas: ", count++);
for (int i = 0; i < transferred; i++)
{
printf("%02x ", buffer[i]);
}
printf("\n");
printf("\n");
} else if (err == LIBUSB_ERROR_TIMEOUT){
fprintf(stderr, "libusb_interrupt_transfer timout\n");
fprintf(stderr, "libusb_interrupt_transfer timout\n");
} else {
fprintf(stderr, "libusb_interrupt_transfer err : %d\n", err);
//exit(1);
//exit(1);
}
}

View File

@@ -0,0 +1,240 @@
#include <errno.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <libusb-1.0/libusb.h>
struct usb_mouse {
struct libusb_device_handle *handle;
int interface;
int endpoint;
unsigned char buf[16];
int transferred;
struct libusb_transfer *transfer;
struct usb_mouse *next;
};
static struct usb_mouse *usb_mouse_list;
void free_usb_mouses(struct usb_mouse *usb_mouse_list)
{
struct usb_mouse *pnext;
while (usb_mouse_list)
{
pnext = usb_mouse_list->next;
free(usb_mouse_list);
usb_mouse_list = pnext;
}
}
/* */
int get_usb_mouses(libusb_device **devs, int num_devices, struct usb_mouse **usb_mouse_list)
{
int err;
libusb_device *dev;
int endpoint;
int interface_num;
struct libusb_config_descriptor *config_desc;
struct libusb_device_handle *dev_handle = NULL;
struct usb_mouse *pmouse;
struct usb_mouse *list = NULL;
int mouse_cnt = 0;
/* for each device, get config descriptor */
for (int i = 0; i < num_devices; i++) {
dev = devs[i];
/* parse interface descriptor, find usb mouse */
err = libusb_get_config_descriptor(dev, 0, &config_desc);
if (err) {
fprintf(stderr, "could not get configuration descriptor\n");
continue;
}
fprintf(stdout, "libusb_get_config_descriptor() ok\n");
for (int interface = 0; interface < config_desc->bNumInterfaces; interface++) {
const struct libusb_interface_descriptor *intf_desc = &config_desc->interface[interface].altsetting[0];
interface_num = intf_desc->bInterfaceNumber;
if (intf_desc->bInterfaceClass != 3 || intf_desc->bInterfaceProtocol != 2)
continue;
else
{
/* 找到了USB鼠标 */
fprintf(stdout, "find usb mouse ok\n");
for (int ep = 0; ep < intf_desc->bNumEndpoints; ep++)
{
if ((intf_desc->endpoint[ep].bmAttributes & 3) == LIBUSB_TRANSFER_TYPE_INTERRUPT ||
(intf_desc->endpoint[ep].bEndpointAddress & 0x80) == LIBUSB_ENDPOINT_IN) {
/* 找到了输入的中断端点 */
fprintf(stdout, "find in int endpoint\n");
endpoint = intf_desc->endpoint[ep].bEndpointAddress;
/* libusb_open */
err = libusb_open(dev, &dev_handle);
if (err)
{
fprintf(stderr, "failed to open usb mouse\n");
return -1;
}
fprintf(stdout, "libusb_open ok\n");
/* 记录下来: 放入链表 */
pmouse = malloc(sizeof(struct usb_mouse));
if (!pmouse)
{
fprintf(stderr, "can not malloc\n");
return -1;
}
pmouse->endpoint = endpoint;
pmouse->interface = interface_num;
pmouse->handle = dev_handle;
pmouse->next = NULL;
if (!list)
list = pmouse;
else
{
pmouse->next = list;
list = pmouse;
}
mouse_cnt++;
break;
}
}
}
}
libusb_free_config_descriptor(config_desc);
}
*usb_mouse_list = list;
return mouse_cnt;
}
static void mouse_irq(struct libusb_transfer *transfer)
{
static int count = 0;
if (transfer->status == LIBUSB_TRANSFER_COMPLETED)
{
/* parser data */
printf("%04d datas: ", count++);
for (int i = 0; i < transfer->actual_length; i++)
{
printf("%02x ", transfer->buffer[i]);
}
printf("\n");
}
if (libusb_submit_transfer(transfer) < 0)
{
fprintf(stderr, "libusb_submit_transfer err\n");
}
}
int main(int argc, char **argv)
{
int err;
libusb_device **devs;
int num_devices, num_mouse;
struct usb_mouse *pmouse;
/* libusb_init */
err = libusb_init(NULL);
if (err < 0) {
fprintf(stderr, "failed to initialise libusb %d - %s\n", err, libusb_strerror(err));
exit(1);
}
/* get device list */
if ((num_devices = libusb_get_device_list(NULL, &devs)) < 0) {
fprintf(stderr, "libusb_get_device_list() failed\n");
libusb_exit(NULL);
exit(1);
}
fprintf(stdout, "libusb_get_device_list() ok\n");
/* get usb mouse */
num_mouse = get_usb_mouses(devs, num_devices, &usb_mouse_list);
if (num_mouse <= 0)
{
/* free device list */
libusb_free_device_list(devs, 1);
libusb_exit(NULL);
exit(1);
}
fprintf(stdout, "get %d mouses\n", num_mouse);
/* free device list */
libusb_free_device_list(devs, 1);
/* claim interface */
pmouse = usb_mouse_list;
while (pmouse)
{
libusb_set_auto_detach_kernel_driver(pmouse->handle, 1);
err = libusb_claim_interface(pmouse->handle, pmouse->interface);
if (err)
{
fprintf(stderr, "failed to libusb_claim_interface\n");
exit(1);
}
pmouse = pmouse->next;
}
fprintf(stdout, "libusb_claim_interface ok\n");
/* for each mouse, alloc transfer, fill transfer, submit transfer */
pmouse = usb_mouse_list;
while (pmouse)
{
/* alloc transfer */
pmouse->transfer = libusb_alloc_transfer(0);
/* fill transfer */
libusb_fill_interrupt_transfer(pmouse->transfer, pmouse->handle, pmouse->endpoint, pmouse->buf,
sizeof(pmouse->buf), mouse_irq, pmouse, 0);
/* submit transfer */
libusb_submit_transfer(pmouse->transfer);
pmouse = pmouse->next;
}
/* handle events */
while (1) {
struct timeval tv = { 5, 0 };
int r;
r = libusb_handle_events_timeout(NULL, &tv);
if (r < 0) {
fprintf(stderr, "libusb_handle_events_timeout err\n");
break;
}
}
/* libusb_close */
pmouse = usb_mouse_list;
while (pmouse)
{
libusb_release_interface(pmouse->handle, pmouse->interface);
libusb_close(pmouse->handle);
pmouse = pmouse->next;
}
free_usb_mouses(usb_mouse_list);
libusb_exit(NULL);
}