如何使用 libusb 中断回调实现通用 hid 读取

如何使用 libusb 中断回调实现通用 hid 读取

大家好,我已成功枚举 Linux 主机上的 STM32 HID 设备并从中接收输入。为了实现这一点,我使用了“hid read”函数和 Linux 源代码示例中的 hid-example。目前,此读取操作采用轮询方式。现在我想继续并将 hid read 操作作为带有 ISR 的回调来实现,而无需创建 read_thread。这可能吗?如果给出任何建议的文档或提示,那将非常有帮助。

答案1

我发现 HID API 包装器在与 libusb 一起使用时会自动创建一个中断读取线程。我将打印添加到“read_callback”,并将 LIBUSB 指定为库依赖项。在那里,我得到了使用 hid 中断回调打印读取数据的代码。

一些变化如下:


  1. 在 hidapi/libusb/hid.c 子模块中

diff --git a/libusb/hid.c b/libusb/hid.c
index b46b1c7..20d8ee4 100644
--- a/libusb/hid.c
+++ b/libusb/hid.c
@@ -41,7 +41,7 @@
 #include <wchar.h>
 
 /* GNU / LibUSB */
-#include <libusb.h>
+#include <libusb-1.0/libusb.h>
 #if !defined(__ANDROID__) && !defined(NO_ICONV)
 #include <iconv.h>
 #ifndef ICONV_CONST
@@ -912,6 +912,8 @@ static void read_callback(struct libusb_transfer *transfer)
 
        pthread_mutex_lock(&dev->mutex);
 
+       printf("transfer data complate, length = %d, %s\r\n",transfer->actual_length, rpt->data);
+

  1. main.c代码

/* Linux */
#include <linux/types.h>
#include <linux/input.h>
#include <linux/hidraw.h>

/* Unix */
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

/* C */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <stdint.h>

/* custoum */
#include "hidapi.h"


unsigned short vid_to_find = 0x0483; 
unsigned short pid_to_find = 0x5750; 

int main(int argc, int* argv[])
{
    char hid_dev_path[1024], buf[256] = {0};
    char *device = "/dev/hidraw1";//had used for test
        
    int i, fd, res, desc_size;
    i = fd = desc_size = 0;

    buf[0] = 0x1;
    buf[1] = 0x2;

    struct hidraw_report_descriptor rpt_desc = {0};
    struct hidraw_devinfo info = {0};

/* hid enumaration test code */
    
    // Enumarate HID divice on system 
    struct hid_device_info * dev, * cur_dev;
    hid_device * my_hid_handle = NULL;

        // 1. enumarate device
        dev = hid_enumerate(vid_to_find,pid_to_find);
    
    if(dev->vendor_id == vid_to_find && dev->product_id == pid_to_find)
    {
        strcpy( hid_dev_path, dev->path );
        printf("Found our device!\r\n");
    }
    else
    {
        printf("device not found!\r\n");
        return 1;
    }

    /* hid file open test code */
    // 2. based on file descriptor open path
    if(dev)
    {
        // Open the Device with non-blocking reads.
        my_hid_handle = hid_open(vid_to_find,pid_to_find,NULL);
        //fd = open(dev->path, O_RDWR|O_NONBLOCK);
        //fd = open(hid_dev_path, O_RDWR|O_NONBLOCK);   //had used for test
        //fd = open(device, O_RDWR|O_NONBLOCK);     //had used for test
        
        printf("dev path: %s, fd: %d\r\n",dev->path,fd);
        
        if (fd < 0) 
        {
                    //perror("Unable to open device");
                    printf("Unable to open device\r\n");
                    printf("tip: try to execute binary with sudo\r\n");
                    return 1;
            }
        else
        {
                    printf("device open success\r\n");
        }

    }

    if(fd && dev)
    {
        printf("before hid write:\n\t hid_write result: %d\r\n", res);//used for test
        //res = hid_write(dev, buf, sizeof(buf));
        res = hid_write(my_hid_handle, buf, 3);

        printf("after hid write:\n\t hid_write result: %d\r\n", res);
        if(res)
        {
                    printf("device write success\r\n");
        }
        else
        {
            printf("device write fail\r\n");
        }
    }
    
    while (1)
    {
        sleep(5);
    }

    
    //last step free device
    hid_close(my_hid_handle);
    hid_free_enumeration(dev);

    return 0;
}

  1. 使用下面的命令构建

gcc -I ../hidapi/hidapi/ ../hidapi/libusb/hid.c  -lusb-1.0 hid_libusb.c -o ../build/hid_libusb

相关内容