我按照这个指南在 RasperryPi 4 上设置了一个自定义 USB 小工具: https ://blog.soutade.fr/post/2016/07/create-your-own-usb-gadget-with-gadgetfs.html
现在我有以下问题:
我在 DataStage 中收到一个带有附加数据的类请求 OUT。所以调用函数:
void handle_setup_request(int fd, struct usb_ctrlrequest *setup)
和
setup->bRequestType: 0x21
setup->bRequest: 0x09
setup->wValue: 0x0202
setup->wIndex: 0x0001
setup->wLength: 0x00ff
因为它是带有附加数据的 OUT 请求(wLength > 0),所以我调用
ret = read(fd, request_buffer, setup->wLength);
读取确实读取了 255 个字节(ret == 255),但内容request_buffer
不是主机发送的数据。它实际上包含上次发送到主机的数据。
然后我添加了
struct pollfd fds[1];
fds[0].fd = fd;
fds[0].events = POLLIN;
poll(fds, 1, 400);
在前面read
。这总是会遇到超时(返回 0)。但timeout = 400
有时我在request_buffer
.
有人现在我做错了吗?我想念什么?
有关其他信息,我在此处提供了显示请求的 USB 分析器的屏幕截图。
这里是相关代码:
int init_device()
{
.
.
int fd = -1;
fd = open(USB_DEV, O_RDWR | O_SYNC );
.
.
handle_ep0(fd);
}
int handle_ep0(int fd)
{
.
.
struct usb_gadgetfs_event events[5];
struct pollfd fds[1];
fds[0].fd = fd;
fds[0].events = POLLIN;
while (1)
{
ret = poll(fds,1,10);
if (ret <= 0)
{
continue;
}
ret = read(fd, events, sizeof(events));
int nevents = ret / sizeof(events[0]);
for(i = 0; i < nevents; i++)
{
switch (events[i].type)
{
case GADGETFS_CONNECT:
printf("EP0 CONNECT\n");
break;
case GADGETFS_DISCONNECT:
printf("EP0 DISCONNECT\n");
return 0;
break;
case GADGETFS_SETUP:
printf("EP0 SETUP\n");
handle_setup_request(fd, &(events[i].u.setup));
break;
case GADGETFS_NOP:
case GADGETFS_SUSPEND:
default:
printf("NOP %d \n", events[i].type);
return 0;
break;
}
}
}
}
void handle_setup_request(int fd, struct usb_ctrlrequest *setup)
{
uint8_t buffer[512];
int ret = 0;
if((setup->bRequestType & USB_DIR_IN) == 0)
{
if(setup->wLength)
{
ret = read(fd, buffer, setup->wLength);
printf("Setup Read %d / %d \n", ret, setup->wLength);
//ret equals wLength but content of buffer is only sometimes correct
}
}
.
.
.
}