mirror of
https://e.coding.net/weidongshan/linux/doc_and_source_for_drivers.git
synced 2025-11-30 12:01:02 +08:00
使用libusb同步函数读取USB鼠标、上机实验
This commit is contained in:
@@ -164,12 +164,13 @@ libusb_control_transfer(dev_handle, 0x21, 0x09, wValue, wIndex, &data, 1, timeou
|
||||
|
||||
通过中断传输可以读到鼠标数据,它是8字节的数据,格式如下:
|
||||
|
||||
| 偏移 | 大小 | 描述 |
|
||||
| ---- | ----- | -------- |
|
||||
| 0 | 1字节 | 按键状态 |
|
||||
| 1 | 1字节 | X位移 |
|
||||
| 2 | 1字节 | Y位移 |
|
||||
| 3 | 1字节 | 滚轮 |
|
||||
| 偏移 | 大小 | 描述 |
|
||||
| ---- | ------------ | -------- |
|
||||
| 0 | 1字节 | |
|
||||
| 1 | 1字节 | 按键状态 |
|
||||
| 2 | 2字节 | X位移 |
|
||||
| 4 | 2字节 | Y位移 |
|
||||
| 6 | 1字节或2字节 | 滚轮 |
|
||||
|
||||
|
||||
|
||||
@@ -196,5 +197,86 @@ USB规范里为每个按键定义了16位的按键值,注意:它是16位的
|
||||
|
||||
|
||||
|
||||
## 2. 使用同步接口读取鼠标数据
|
||||
|
||||
源码在GIT仓库如下位置:
|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
### 2.1 编写源码
|
||||
|
||||
```c
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
||||
### 2.2 上机实验
|
||||
|
||||
#### 2.2.1 在Ubuntu上实验
|
||||
|
||||
```shell
|
||||
// 1. 安装开发包
|
||||
$ sudo apt install libusb-1.0-0-dev
|
||||
|
||||
// 2. 修改源码,包含libusb.h 头文件时用如下代码
|
||||
#include <libusb-1.0/libusb.h>
|
||||
|
||||
// 3. 编译程序指定库
|
||||
gcc -o readmouse readmouse.c -lusb-1.0
|
||||
```
|
||||
|
||||
|
||||
|
||||
#### 2.2.2 在开发板上实验
|
||||
|
||||
|
||||
|
||||
* 交叉编译libusb
|
||||
|
||||
```shell
|
||||
sudo apt-get install libtool
|
||||
|
||||
unzip libusb-1.0.26.zip
|
||||
cd libusb-1.0.26
|
||||
./autogen.sh
|
||||
|
||||
./configure --host=arm-buildroot-linux-gnueabihf --prefix=$PWD/tmp
|
||||
|
||||
make
|
||||
|
||||
make install
|
||||
|
||||
ls tmp/
|
||||
include lib
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
||||
* 安装库、头文件到工具链的目录里
|
||||
|
||||
```shell
|
||||
libusb-1.0.26/tmp/lib$ cp * -rfd /home/book/100ask_imx6ull-sdk/ToolChain/arm-buildroot-linux-gnueabihf_sdk-buildroot/arm-buildroot-linux-gnueabihf/sysroot/usr/lib/
|
||||
|
||||
libusb-1.0.26/tmp/include$ cp libusb-1.0 -rf /home/book/100ask_imx6ull-sdk/ToolChain/arm-buildroot-linux-gnueabihf_sdk-buildroot/arm-buildroot-linux-gnueabihf/sysroot/usr/include/
|
||||
```
|
||||
|
||||
|
||||
|
||||
* 交叉编译app
|
||||
|
||||
```shell
|
||||
arm-buildroot-linux-gnueabihf-gcc -o readmouse readmouse.c -lusb-1.0
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Binary file not shown.
BIN
IMX6ULL/doc_pic/12_USB/pic/60_libusb_mouse_sync_src.png
Normal file
BIN
IMX6ULL/doc_pic/12_USB/pic/60_libusb_mouse_sync_src.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 5.7 KiB |
145
IMX6ULL/source/12_USB/02_libusb_mouse_sync/readmouse.c
Normal file
145
IMX6ULL/source/12_USB/02_libusb_mouse_sync/readmouse.c
Normal file
@@ -0,0 +1,145 @@
|
||||
#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);
|
||||
}
|
||||
|
||||
BIN
IMX6ULL/source/12_USB/libusb-1.0.26.zip
Normal file
BIN
IMX6ULL/source/12_USB/libusb-1.0.26.zip
Normal file
Binary file not shown.
@@ -666,6 +666,15 @@ git clone https://e.coding.net/weidongshan/linux/doc_and_source_for_drivers.git
|
||||
07.1_USB鼠标协议
|
||||
```
|
||||
|
||||
* 2022.09.28 发布"USB子系统"
|
||||
|
||||
```shell
|
||||
07.2_使用libusb同步函数读取USB鼠标
|
||||
07.3_上机实验1_在Ubuntu上实验
|
||||
07.4_上机实验2_交叉编译libusb
|
||||
07.5_上机实验3_在板上实验
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -164,12 +164,13 @@ libusb_control_transfer(dev_handle, 0x21, 0x09, wValue, wIndex, &data, 1, timeou
|
||||
|
||||
通过中断传输可以读到鼠标数据,它是8字节的数据,格式如下:
|
||||
|
||||
| 偏移 | 大小 | 描述 |
|
||||
| ---- | ----- | -------- |
|
||||
| 0 | 1字节 | 按键状态 |
|
||||
| 1 | 1字节 | X位移 |
|
||||
| 2 | 1字节 | Y位移 |
|
||||
| 3 | 1字节 | 滚轮 |
|
||||
| 偏移 | 大小 | 描述 |
|
||||
| ---- | ------------ | -------- |
|
||||
| 0 | 1字节 | |
|
||||
| 1 | 1字节 | 按键状态 |
|
||||
| 2 | 2字节 | X位移 |
|
||||
| 4 | 2字节 | Y位移 |
|
||||
| 6 | 1字节或2字节 | 滚轮 |
|
||||
|
||||
|
||||
|
||||
@@ -196,5 +197,86 @@ USB规范里为每个按键定义了16位的按键值,注意:它是16位的
|
||||
|
||||
|
||||
|
||||
## 2. 使用同步接口读取鼠标数据
|
||||
|
||||
源码在GIT仓库如下位置:
|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
### 2.1 编写源码
|
||||
|
||||
```c
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
||||
### 2.2 上机实验
|
||||
|
||||
#### 2.2.1 在Ubuntu上实验
|
||||
|
||||
```shell
|
||||
// 1. 安装开发包
|
||||
$ sudo apt install libusb-1.0-0-dev
|
||||
|
||||
// 2. 修改源码,包含libusb.h 头文件时用如下代码
|
||||
#include <libusb-1.0/libusb.h>
|
||||
|
||||
// 3. 编译程序指定库
|
||||
gcc -o readmouse readmouse.c -lusb-1.0
|
||||
```
|
||||
|
||||
|
||||
|
||||
#### 2.2.2 在开发板上实验
|
||||
|
||||
|
||||
|
||||
* 交叉编译libusb
|
||||
|
||||
```shell
|
||||
sudo apt-get install libtool
|
||||
|
||||
unzip libusb-1.0.26.zip
|
||||
cd libusb-1.0.26
|
||||
./autogen.sh
|
||||
|
||||
./configure --host=arm-buildroot-linux-gnueabihf --prefix=$PWD/tmp
|
||||
|
||||
make
|
||||
|
||||
make install
|
||||
|
||||
ls tmp/
|
||||
include lib
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
||||
* 安装库、头文件到工具链的目录里
|
||||
|
||||
```shell
|
||||
libusb-1.0.26/tmp/lib$ cp * -rfd /home/book/100ask_imx6ull-sdk/ToolChain/arm-buildroot-linux-gnueabihf_sdk-buildroot/arm-buildroot-linux-gnueabihf/sysroot/usr/lib/
|
||||
|
||||
libusb-1.0.26/tmp/include$ cp libusb-1.0 -rf /home/book/100ask_imx6ull-sdk/ToolChain/arm-buildroot-linux-gnueabihf_sdk-buildroot/arm-buildroot-linux-gnueabihf/sysroot/usr/include/
|
||||
```
|
||||
|
||||
|
||||
|
||||
* 交叉编译app
|
||||
|
||||
```shell
|
||||
arm-buildroot-linux-gnueabihf-gcc -o readmouse readmouse.c -lusb-1.0
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Binary file not shown.
BIN
STM32MP157/doc_pic/12_USB/pic/60_libusb_mouse_sync_src.png
Normal file
BIN
STM32MP157/doc_pic/12_USB/pic/60_libusb_mouse_sync_src.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 5.7 KiB |
145
STM32MP157/source/A7/12_USB/02_libusb_mouse_sync/readmouse.c
Normal file
145
STM32MP157/source/A7/12_USB/02_libusb_mouse_sync/readmouse.c
Normal file
@@ -0,0 +1,145 @@
|
||||
#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);
|
||||
}
|
||||
|
||||
BIN
STM32MP157/source/A7/12_USB/libusb-1.0.26.zip
Normal file
BIN
STM32MP157/source/A7/12_USB/libusb-1.0.26.zip
Normal file
Binary file not shown.
Reference in New Issue
Block a user