0

我按照这个指南在 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 分析器的屏幕截图。 USB-Sniffer 截图

这里是相关代码:

    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
            }
        }
        
        .
        .
        .
        
    }
4

0 回答 0