#c #io #raspberry-pi #usb #gadgetfs
Вопрос:
Я настроил пользовательский USB-гаджет на RasperryPi 4, следуя этому идентификатору guid: https://blog.soutade.fr/post/2016/07/create-your-own-usb-gadget-with-gadgetfs.html
Теперь у меня следующая проблема:
Я получаю запрос класса с дополнительными данными в DataStage. Итак, вызывается функция:
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 CONNECTn");
break;
case GADGETFS_DISCONNECT:
printf("EP0 DISCONNECTn");
return 0;
break;
case GADGETFS_SETUP:
printf("EP0 SETUPn");
handle_setup_request(fd, amp;(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 amp; 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
}
}
.
.
.
}