7

我正在开发一个 RNDIS 复合设备,其中包括一个 RNDIS 设备、一个 usbnet 设备、一个调制解调器设备和一个自定义 CDC 设备。

PC 运行 Win7 32 位,我使用的是默认的 RNDIS 驱动程序。当我只用 RNDIS 设备回答 Windows 枚举时,一切正常。但是当我将所有 4 个设备作为复合设备组合到描述符中时,Windows 仍然可以正确枚举,其他 3 个设备工作正常,但 RNDIS 设备遇到“无法启动错误代码 10”问题。

我用 USB 分析仪跟踪 USB 数据流,发现Windows RNDIS 驱动程序在“设置配置”后没有发送 RNDIS 初始化消息。

复合设备描述符如下所示:

         devDesc[0]  = 0x12; //  bLength             - Descriptor length
         devDesc[1]  = 0x01; //  bDescriptorType     - Descriptor  Type
         devDesc[2]  = bcdUSB_LSB; //  bcdUSB (LSB)        - Device Compliant to USB specification ..
         devDesc[3]  = bcdUSB_MSB; //  bcdUSB (MSB)
         devDesc[4]  = 0x00; //  bDeviceClass        - class of the device
         devDesc[5]  = 0x00; //  bDeviceSubClass     - subclass of the device
         devDesc[6]  = 0x00; //  bDeviceProtocol     - protocol of the device
         devDesc[7]  = bEp0MaxPacketSize; //  bMaxPacketSize0     - Max Packet Size for EP zero
         devDesc[8]  = 0x86; //  idVendor (LSB)      - Vendor ID
         devDesc[9]  = 0x12; //  idVendor (MSB)
         devDesc[10] = 0x0E; //  idProduct (LSB)     - Product ID
         devDesc[11] = 0x81; //  idProduct (MSB)
         devDesc[12] = 0x02; //  bcdDevice (LSB)     - The device release number
         devDesc[13] = 0x00; //  bcdDevice (MSB)
         devDesc[14] = 0x01; //  iManufacturer       - Index of string descriptor describing Manufacturer
         devDesc[15] = 0x03; //  iProduct            - Index of string descriptor describing Product
         devDesc[16] = 0x04; //  iSerialNumber       - Index of string descriptor describing Serial number
         devDesc[17] = 0x01; //  bNumConfigurations  - Number of configurations

         //Configuration Descriptor
         configDesc[0]  = 0x09; // bLength               - Descriptor length
         configDesc[1]  = 0x02; // bDescriptorType       - Descriptor Type
         configDesc[2]  = 177;   // wTotalLength (LSB)   - Total Data length for the configuration,
         configDesc[3]  = 0x00; // wTotalLength (MSB)    - includes all descriptors for this configuration
         configDesc[4]  = 0x05; // bNumInterfaces        - Number of interfaces this configuration supports
         configDesc[5]  = 0x01; // bConfigurationValue   - The Value that should be used to select this configuration
         configDesc[6]  = 0x00; // iConfiguration        - Index of string descriptor describing this configuration
         configDesc[7]  = 0xC0; // bmAttributes          - bit6: Self-Powered, bit5: RemoteWakeup
         configDesc[8]  = 0xfa; // MaxPower              - Maximum power consumption for this configuration (mA)


         //Interface Descriptor 0 usbnet
         configDesc[9]  = 0x09; // bLength               - Descriptor length
         configDesc[10] = 0x04; // bDescriptorType       - Descriptor Type
         configDesc[11] = 0x00; // bInterfaceNumber      - Index (Number) of this interfaces
         configDesc[12] = 0x00; // bAlternateSetting     - The value to select alternate setting of this interface
         configDesc[13] = 0x03; // bNumEndpoints         - Number endpoints  used by this interface
         configDesc[14] = 0xff; // bInterfaceClass       - Class of this Interface
         configDesc[15] = 0xff; // bInterfaceSubClass    - Sub class of this Interface
         configDesc[16] = 0x00; // bInterfaceProtocol    - Protocol of this Interface
         configDesc[17] = 0x05; // iInterface            - Index of string descriptor describing this Interface


         // usbnet Endpoint Descriptor
         configDesc[18] = 0x07; // bLength               - Descriptor length
         configDesc[19] = 0x05; // bDescriptorType       - Descriptor Type
         configDesc[20] = 0x85; // bEndpointAddress      - Endpoint Address & Direction
         configDesc[21] = 0x03; // bmAttributes          - BULK,ISO,Interrupt
         configDesc[22] = 0x0F; // wMaxPacketSize (LSB)  - Max packet size
         configDesc[23] = 0x00; // wMaxPacketSize (MSB)
         configDesc[24] = bInterval; // bInterval                - Polling Interval (ms)

         configDesc[25] = 0x07; // bLength               - Descriptor length
         configDesc[26] = 0x05; // bDescriptorType       - Descriptor Type
         configDesc[27] = 0x81; // bEndpointAddress      - Endpoint Address & Direction
         configDesc[28] = 0x02; // bmAttributes          - BULK,ISO,Interrupt
         configDesc[29] = bBulkMaxPacketSize_LSB; // wMaxPacketSize (LSB)  - Max packet size
         configDesc[30] = bBulkMaxPacketSize_MSB; // wMaxPacketSize (MSB)
         configDesc[31] = 0x00; // bInterval             - Polling Interval (ms)

         configDesc[32] = 0x07; // bLength               - Descriptor length
         configDesc[33] = 0x05; // bDescriptorType       - Descriptor Type
         configDesc[34] = 0x02; // bEndpointAddress      - Endpoint Address & Direction
         configDesc[35] = 0x02; // bmAttributes          - BULK,ISO,Interrupt
         configDesc[36] = bBulkMaxPacketSize_LSB; // wMaxPacketSize (LSB)  - Max packet size
         configDesc[37] = bBulkMaxPacketSize_MSB; // wMaxPacketSize (MSB)
         configDesc[38] = 0x00; // bInterval             - Polling Interval (ms)

         //Interface descriptor 1 ICAT
         configDesc[39] = 0x09; // bLength               - Descriptor length
         configDesc[40] = 0x04; // bDescriptorType       - Descriptor Type
         configDesc[41] = 0x01; // bInterfaceNumber      - Index (Number) of this interfaces
         configDesc[42] = 0x00; // bAlternateSetting     - The value to select alternate setting of this interface
         configDesc[43] = 0x02; // bNumEndpoints         - Number endpoints  used by this interface
         configDesc[44] = 0xFF; // bInterfaceClass       - Class of this Interface
         configDesc[45] = 0x00; // bInterfaceSubClass    - Sub class of this Interface
         configDesc[46] = 0x00; // bInterfaceProtocol    - Protocol of this Interface
         configDesc[47] = 0x00; // iInterface            - Index of string descriptor describing this Interface

         //ICAT endpoints
         configDesc[48] = 0x07; // bLength               - Descriptor length
         configDesc[49] = 0x05; // bDescriptorType       - Descriptor Type
         configDesc[50] = 0x87; // bEndpointAddress      - Endpoint Address & Direction
         configDesc[51] = 0x02; // bmAttributes          - BULK,ISO,Interrupt
         configDesc[52] = bBulkMaxPacketSize_LSB; // wMaxPacketSize (LSB)  - Max packet size
         configDesc[53] = bBulkMaxPacketSize_MSB; // wMaxPacketSize (MSB)
         configDesc[54] = 0x00; // bInterval             - Polling Interval (ms)

         configDesc[55] = 0x07; // bLength               - Descriptor length
         configDesc[56] = 0x05; // bDescriptorType       - Descriptor Type
         configDesc[57] = 0x08; // bEndpointAddress      - Endpoint Address & Direction
         configDesc[58] = 0x02; // bmAttributes          - BULK,ISO,Interrupt
         configDesc[59] = bBulkMaxPacketSize_LSB; // wMaxPacketSize (LSB)  - Max packet size
         configDesc[60] = bBulkMaxPacketSize_MSB; // wMaxPacketSize (MSB)
         configDesc[61] = 0x00; // bInterval             - Polling Interval (ms)

         //Modem class specific descriptors
         configDesc[62]  = 0x09; // bLength              - Descriptor length
         configDesc[63] = 0x04; // bDescriptorType       - Descriptor Type
         configDesc[64] = 0x02; // bInterfaceNumber      - Index (Number) of this interfaces
         configDesc[65] = 0x00; // bAlternateSetting     - The value to select alternate setting of this interface
         configDesc[66] = 0x03; // bNumEndpoints         - Number endpoints  used by this interface
         configDesc[67] = 0x02; // bInterfaceClass       - Class of this Interface
         configDesc[68] = 0x02; // bInterfaceSubClass    - Sub class of this Interface
         configDesc[69] = 0x01; // bInterfaceProtocol    - Protocol of this Interface
         configDesc[70] = 0x00; // iInterface            - Index of string descriptor describing this Interface

         configDesc[71] = 0x05; // descriptor length Comms Class CS_INTERFACE 'Functional Descriptors' Triplet
         configDesc[72] = 0x24; // descriptor type
         configDesc[73] = 0x00; // subtype = header
         configDesc[74] = 0x10; // BCD
         configDesc[75] = 0x01; //

         configDesc[76] = 0x05; // 2. descriptor length - Call Manangement Func Desc
         configDesc[77] = 0x24; // descriptor type
         configDesc[78] = 0x01; // subtype = Call management
         configDesc[79] = 0x00; //bmcapabilities; MS driver usbser.sys seems to ignore this bit and sends AT over the data,interface anyway
         configDesc[80] = 0x01; // Interface number of data class interface

         configDesc[81] = 0x04; // 3.descriptor length  Abstract Control Func Desc
         configDesc[82] = 0x24; // descriptor type
         configDesc[83] = 0x02; // subtype = Abstract CM
         configDesc[84] = 0x00; // bmcapabilities 

         configDesc[85] = 0x05; // Size of descriptor. Number of interfaces plus 3 bytes of header
         configDesc[86] = 0x24; // 0x24 - CS_INTERFACE
         configDesc[87] = 0x06; // 0x06 - See table 25 of document "USB Class definitions for Comms Devices"
         configDesc[88] = 0x00;
         configDesc[89] = 0x01;

         //Endpoint Descriptors MODEM
         configDesc[90] = 0x07; // bLength               - Descriptor length
         configDesc[91] = 0x05; // bDescriptorType       - Descriptor Type
         configDesc[92] = 0x86; // bEndpointAddress      - Endpoint Address & Direction
         configDesc[93] = 0x03; // bmAttributes          - BULK,ISO,Interrupt
         configDesc[94] = 0x0F; // wMaxPacketSize (LSB)  - Max packet size
         configDesc[95] = 0x00; // wMaxPacketSize (MSB)
         configDesc[96] = bInterval; // bInterval                - Polling Interval (ms)

         configDesc[97] = 0x07; // bLength               - Descriptor length
         configDesc[98] = 0x05; // bDescriptorType       - Descriptor Type
         configDesc[99] = 0x83; // bEndpointAddress      - Endpoint Address & Direction
         configDesc[100] = 0x02; // bmAttributes          - BULK,ISO,Interrupt
         configDesc[101] = bBulkMaxPacketSize_LSB; // wMaxPacketSize (LSB)  - Max packet size
         configDesc[102] = bBulkMaxPacketSize_MSB; // wMaxPacketSize (MSB)
         configDesc[103] = 0x00; // bInterval                - Polling Interval (ms)

         configDesc[104] = 0x07; // bLength              - Descriptor length
         configDesc[105] = 0x05; // bDescriptorType      - Descriptor Type
         configDesc[106] = 0x04; // bEndpointAddress     - Endpoint Address & Direction
         configDesc[107] = 0x02; // bmAttributes          - BULK,ISO,Interrupt
         configDesc[108] = bBulkMaxPacketSize_LSB; // wMaxPacketSize (LSB)  - Max packet size
         configDesc[109] = bBulkMaxPacketSize_MSB; // wMaxPacketSize (MSB)
         configDesc[110] = 0x00; // bInterval                - Polling Interval (ms)


        //rndis IAD
        configDesc[111] = 0x08; // bLength
        configDesc[112] = 0x0b; // INTERFACE ASSOCIATION DESCRIPTOR bDescriptorType
        configDesc[113] = 0x03; // bFirstInterface
        configDesc[114] = 0x02; // bInterfaceCount
        configDesc[115] = 0x02; // bFunctionClass
        configDesc[116] = 0x02; // bFunctionSubClass
        configDesc[117] = 0xFF; // bFunctionProtocol
        configDesc[118] = 0x03; // Index of string descriptor describing this function

        //rndis comm interface
        configDesc[119] = 0x09; // bLength             - Descriptor length
        configDesc[120] = 0x04; // bDescriptorType     - Descriptor Type
        configDesc[121] = 0x03; //bInterfaceNumber     - for RNDIS
        configDesc[122] = 0x00; // bAlt
        configDesc[123] = 0x01; // bNumEnd
        configDesc[124] = 0x02; //bInterfaceClass
        configDesc[125] = 0x02; // bInterfaceSubclass
        configDesc[126] = 0xFF; // bInterfaceprotocol
        configDesc[127] = 0x00; // iInterface  +++++++++++++++++++++++++++++++++++++need modified


        // Class specified descriptor

        configDesc[128] = 0x05; //
        configDesc[129] = 0x24; // bDescriptorType
        configDesc[130] = 0x00; //bDescriptorSubtype
        configDesc[131] = 0x10; // BCD
        configDesc[132] = 0x01; //

        configDesc[133] = 0x05; //
        configDesc[134] = 0x24; // bDescriptorType
        configDesc[135] = 0x01; // bDescriptorSubtype
        configDesc[136] = 0x00; // bmCapabilities
        configDesc[137] = 0x04; //bDataInterface

        configDesc[138] = 0x04; //
        configDesc[139] = 0x24; // bDescriptorType
        configDesc[140] = 0x02; // bDescriptorSubtype
        configDesc[141] = 0x00; // bmCapabilities

        configDesc[142] = 0x05; //
        configDesc[143] = 0x24; // bDescriptorType
        configDesc[144] = 0x06; // bDescriptorSubtype
        configDesc[145] = 0x03; // bControlInterface
        configDesc[146] = 0x04; // bsubordinateInterface

        //Interrupt In endpoint
        configDesc[147] = 0x07; //
        configDesc[148] = 0x05; //
        configDesc[149] = 0x8C; //bendpointAddress
        configDesc[150] = 0x03; //bmAttributes
        configDesc[151] = 0x08; // wMaxPacketSize
        configDesc[152] = 0x00; //
        configDesc[153] = 0x01; // bInterval

        //rndis data interface
        configDesc[154] = 0x09; // bLength             - Descriptor length
        configDesc[155] = 0x04; // bDescriptorType     - Descriptor Type
        configDesc[156] = 0x04; //bInterfaceNumber     --- for RNDIS
        configDesc[157] = 0x00; // bAlt
        configDesc[158] = 0x02; // NumEndpoints
        configDesc[159] = 0x0a; //bInterfaceClass
        configDesc[160] = 0x00; // bInterfaceSubclass
        configDesc[161] = 0x00; // bInterfaceprotocol
        configDesc[162] = 0x00; // iInterface  +++++++++++++++++++++++++++++++++++++need modified

        //Bulk In endpoint
        configDesc[163] = 0x07; //
        configDesc[164] = 0x05; //
        configDesc[165] = 0x8E; //bendpointAddress
        configDesc[166] = 0x02; //bmAttributes
        configDesc[167] = 0x00; // wMaxPacketSize
        configDesc[168] = 0x02; //
        configDesc[169] = 0x00; // bInterval

        //Bulk Out endpoint
        configDesc[170] = 0x07; //
        configDesc[171] = 0x05; //
        configDesc[172] = 0x0D; //bendpointAddress
        configDesc[173] = 0x02; //bmAttributes
        configDesc[174] = 0x00; // wMaxPacketSize
        configDesc[175] = 0x02; //
        configDesc[176] = 0x00; // bInterva
4

2 回答 2

4

让我回答我自己的问题,我已经弄清楚了这个问题:

RNDIS IAD 接口必须是复合设备的第一个和第二个。虽然问题解决了,但还是让我很困惑。

希望这篇笔记能帮助其他遇到类似问题的人。

于 2012-08-30T09:05:13.127 回答
0

对于那些遇到此线程的人,因为您在使用内置的 configfs libcomposite 设备时遇到类似的 RNDIS 问题和 windows 代码 10 错误,经过大量谷歌搜索并在互联网上浏览代码,代码在libcomposite 模块.....我发现如果我在 libcomposite 模块之后直接强制加载 usb_f_rndis 模块,而不是修补驱动程序,我可以解决这个问题,这会强制 usb_f_rndis 到第一个和第二个 iad 插槽。当您在 configfs 中添加设备时,将加载 libcomposite 设备的其余模块,Windows 会对此感到满意。

此外,要强制 Windows 加载正确的驱动程序,请确保设置了 os_desc 内容。这里有一个很好的指南:http: //irq5.io/2016/12/22/raspberry-pi-zero-as-multiple-usb-gadgets/

于 2018-03-14T23:54:48.783 回答