Linux USB Gadget: 处理 configfs HID 的 GET_REPORT 与 SET_REPORT

问题背景

gadget 创建的 /dev/hidg* 通过 read 读取的数据只有 INTERRUPT 侧的数据,而 S/GET_REPORT 是 FEATURE 类的的数据
但其实linux内核已经实现了设置GET_REPORT的数据,通过ioctl进行设置

内核版本:6.12及以上

示例代码

#include <sys/ioctl.h>
#include <linux/usb/g_hid.h>
#include <linux/hidraw.h>

uint8_t data[] = {
    0x20, 0x4a, 0x75, 0x6c, 0x20, 0x20, 0x34, 0x20,
    0x32, 0x30, 0x32, 0x35, 0x31, 0x30, 0x3a, 0x33,
    0x38, 0x3a, 0x34, 0x30, 0x03, 0x00, 0x0b, 0x00,
    0x11, 0x08, 0x00, 0x00, 0x2a, 0x00, 0x10, 0x01,
    0x00, 0x28, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x30, 0x06, 0x00, 0x00,
    0x01, 0x00, 0x03, 0x00, 0x10, 0x10, 0x03, 0x00, 
    0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};

usb_hidg_report report_0x20{};
report_0x20.report_id = 0x20;
report_0x20.userspace_req = 0;
report_0x20.length = sizeof(data);
memcpy(report_0x20.data,data,sizeof(data));

ioctl(fd,GADGET_HID_WRITE_GET_REPORT,&report_0x20);

关于userspace_req的参数,在头文件里面有这样的注释

  • @userspace_req:
  • !0 this report is used for any pending GET_REPORT request
  • but wait on userspace to issue a new report on future requests
  • 0 this report is to be used for any future GET_REPORT requests

但是我自己没用出区别

处理 SET_REPORT

通过 no_out_endpoint=1 让 Interrupt OUT 的数据fallback成SET_REPORT,这样在read函数就能接收到SET_REPORT与INTERRUPT OUT的数据了
示例:

echo 1 > functions/hid.usb0/no_out_endpoint

但是好像如果INTERRUPT OUT是高频数据就不适合用这个方法?请自行测试

小碎念

怎么网上都没有提到关于USB Gadget的GET_REPORT内容,让我找了好久。折腾ffs真是噩梦

相关链接

posted @ 2026-04-05 18:05  awalol  阅读(32)  评论(0)    收藏  举报