1

简而言之,我的总体目标是:我想通过 USB 将批量数据从我的 CC2538EM 发送到 PC。并且应该使用 C# 应用程序读取数据。

由于我无法安装 TI 的“CC2538 固件基础”(链接)的 CDC 驱动程序,我决定尝试使用 libusb-win32(以及用于 MS Visual Studio 的 LibUsbDotNet)。

但是我从主机和设备写入的数据都无法读取或写入。

USB 描述符:

const USB_DESCRIPTOR usbDescriptor = {
{ // device
    sizeof(USB_DEVICE_DESCRIPTOR),
    USB_DESC_TYPE_DEVICE,           // bDescriptorType
    0x0200,                         // bcdUSB (USB 2.0)
    0x02,                           // bDeviceClass (CDC)
    0x00,                           // bDeviceSubClass
    0x00,                           // bDeviceProtocol
    USB_EP0_PACKET_SIZE,            // bMaxPacketSize0
    0x0451,                         // idVendor (Texas Instruments)
    0x16C8,                         // idProduct (CC2538 CDC)
    0x0100,                         // bcdDevice (v1.0)
    0x01,                           // iManufacturer
    0x02,                           // iProduct
    0x00,                           // iSerialNumber
    0x01,                           // bNumConfigurations
},
    { // configuration0
        sizeof(USB_CONFIGURATION_DESCRIPTOR),
        USB_DESC_TYPE_CONFIG,           // bDescriptorType
        SIZEOF_CONFIGURATION0_DESC,     // wTotalLength
        0x02,                           // bNumInterfaces
        0x01,                           // bConfigurationValue
        0x00,                           // iConfiguration
        0xA0,                           // bmAttributes (7,4-0: res, 6: self-powered, 5: remote wakeup)
        25                              // bMaxPower (max 2 * 25 = 50 mA)
    },
        { // interface0
            sizeof(USB_INTERFACE_DESCRIPTOR),
            USB_DESC_TYPE_INTERFACE,        // bDescriptorType
            0x00,                           // bInterfaceNumber
            0x00,                           // bAlternateSetting (none)
            0x01,                           // bNumEndpoints
            0x02,                           // bInterfaceClass (CDC communication interface)
            0x02,                           // bInterfaceSubClass (Abstract control model)
            0x01,                           // bInterfaceProcotol (V25TER)
            0x00                            // iInterface
        },
            { // hdrFunc0
                sizeof(USBCDC_HEADER_FUNC_DESCRIPTOR),
                USB_DESC_TYPE_CS_INTERFACE,     // bDescriptorType
                USBCDC_FUNCDESC_HEADER,         // bDescriptorSubType
                0x0110                          // bcdCDC
            },
            { // absCallMgmtFunc0
                sizeof(USBCDC_ABSTRACT_CTRL_MGMT_FUNC_DESCRIPTOR),
                USB_DESC_TYPE_CS_INTERFACE,     // bDescriptorType
                USBCDC_FUNCDESC_ABS_CTRL_MGMT,  // bDescriptorSubType
                0x02                            // bmCapabilities (supported class requests)
            },
            { // unionIfFunc0
                sizeof(USBCDC_UNION_INTERFACE_FUNC_DESCRIPTOR),
                USB_DESC_TYPE_CS_INTERFACE,     // bDescriptorType
                USBCDC_FUNCDESC_UNION_IF,       // bDescriptorSubType
                0x00,                           // bMasterInterface
                0x01                            // bSlaveInterface0
            },
            { // callMgmtFunc0
                sizeof(USBCDC_CALL_MGMT_FUNC_DESCRIPTOR),
                USB_DESC_TYPE_CS_INTERFACE,     // bDescriptorType
                USBCDC_FUNCDESC_CALL_MGMT,      // bDescriptorSubType
                0x00,                           // bmCapabilities
                0x01                            // bDataInterface
            },
            { // endpoint0
                sizeof(USB_ENDPOINT_DESCRIPTOR),
                USB_DESC_TYPE_ENDPOINT,         // bDescriptorType
                0x82,                           // bEndpointAddress
                USB_EP_ATTR_INT,                // bmAttributes (INT)
                0x0040,                         // wMaxPacketSize
                0x40                            // bInterval (64 full-speed frames = 64 ms)
            },
        { // interface1
            sizeof(USB_INTERFACE_DESCRIPTOR),
            USB_DESC_TYPE_INTERFACE,        // bDescriptorType
            0x01,                           // bInterfaceNumber
            0x00,                           // bAlternateSetting (none)
            0x02,                           // bNumEndpoints
            0x02,                           // bInterfaceClass (CDC data interface)
            0x00,                           // bInterfaceSubClass (none)
            0x00,                           // bInterfaceProcotol (no protocol)
            0x00                            // iInterface
        },
            { // endpoint1
                sizeof(USB_ENDPOINT_DESCRIPTOR),
                USB_DESC_TYPE_ENDPOINT,         // bDescriptorType
                0x84,                           // bEndpointAddress
                USB_EP_ATTR_BULK,               // bmAttributes (BULK)
                0x0040,                         // wMaxPacketSize
                0x00                            // bInterval
            },
            { // endpoint2
                sizeof(USB_ENDPOINT_DESCRIPTOR),
                USB_DESC_TYPE_ENDPOINT,         // bDescriptorType
                0x04,                           // bEndpointAddress
                USB_EP_ATTR_BULK,               // bmAttributes (BULK)
                0x0040,                         // wMaxPacketSize
                0x00                            // bInterval
            },
{ // strings
    { // langIds
        sizeof(USB_STRING_0_DESCRIPTOR),
        USB_DESC_TYPE_STRING,
        0x0409 // English US
    },
    { // manufacturer
        sizeof(USB_STRING_1_DESCRIPTOR),
        USB_DESC_TYPE_STRING,
        'T', 'e', 'x', 'a', 's', ' ', 'I', 'n', 's', 't', 'r', 'u', 'm', 'e', 'n', 't', 's'
    },
    { // product
        sizeof(USB_STRING_2_DESCRIPTOR),
        USB_DESC_TYPE_STRING,
        'C', 'C', '2', '5', '3', '8', ' ', 'U', 'S', 'B', ' ', 'C', 'D', 'C'
    }
}

};

我以这种方式在设备上读/写的数据:

int main(void)
{

    initBoard();

    usbCdcInit(57600);  // Enable the USB interface


    memset(&usbCdcInBufferData, 0x00, sizeof(USB_EPIN_RINGBUFFER_DATA));
    usbCdcInBufferData.pBuffer = pInBuffer;
    usbCdcInBufferData.size = sizeof(pInBuffer);
    usbCdcInBufferData.endpointReg = USB_F4;
    usbCdcInBufferData.endpointIndex = 4;
    usbCdcInBufferData.endpointSize = 64;
    memset(&usbCdcOutBufferData, 0x00, sizeof(USB_EPOUT_RINGBUFFER_DATA));
    usbCdcOutBufferData.pBuffer = pOutBuffer;
    usbCdcOutBufferData.size = sizeof(pOutBuffer);
    usbCdcOutBufferData.endpointReg = USB_F4;
    usbCdcOutBufferData.endpointIndex = 4;



    uint8_t test[10];

    while (1)
    {
        //
        // Process USB events
        //
        usbProcessEvents();


        uint8_t test2[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
        uint16_t testLength = 10;

        usbobufPop(&usbCdcOutBufferData, test, testLength);
        usbibufPush(&usbCdcInBufferData, test2, testLength);

}

}

对于主机,我使用了 LibUsbDotNot 读/写示例:

private void button2_Click(object sender, EventArgs e)
    {
        //  LibUsbDotNet
        ErrorCode ec = ErrorCode.None;

        try
        {
            // Find and open the usb device.
            MyUsbDevice = UsbDevice.OpenUsbDevice(MyUsbFinder);

            // If the device is open and ready
            if (MyUsbDevice == null) throw new Exception("Device Not Found.");

            // If this is a "whole" usb device (libusb-win32, linux libusb-1.0)
            // it exposes an IUsbDevice interface. If not (WinUSB) the 
            // 'wholeUsbDevice' variable will be null indicating this is 
            // an interface of a device; it does not require or support 
            // configuration and interface selection.
            IUsbDevice wholeUsbDevice = MyUsbDevice as IUsbDevice;
            if (!ReferenceEquals(wholeUsbDevice, null))
            {
                // This is a "whole" USB device. Before it can be used, 
                // the desired configuration and interface must be selected.

                // Select config #1
                if (!wholeUsbDevice.SetConfiguration(1))
                    Console.Write("error setting config failed");

                // Claim interface #1.
                if (!wholeUsbDevice.ClaimInterface(1))
                    Console.Write("error: claiming interface failed");

            }
            Console.Write("");

            // open read endpoint 1.
            UsbEndpointReader reader = MyUsbDevice.OpenEndpointReader(ReadEndpointID.Ep04);

            // openwrite enpoint
            UsbEndpointWriter writer = MyUsbDevice.OpenEndpointWriter(WriteEndpointID.Ep04);

            int bytesWritten;
            String cmdLine = "blablub";
            ec = writer.Write(Encoding.Default.GetBytes(cmdLine), 2000, out bytesWritten);
            if (ec != ErrorCode.None) throw new Exception(UsbDevice.LastErrorString);



            byte[] readBuffer = new byte[1024];

            while (ec == ErrorCode.None)
            {
                int bytesRead;

                Console.WriteLine();

                // If the device hasn't sent data in the last 5 seconds,
                // a timeout error (ec = IoTimedOut) will occur. 
                ec = reader.Read(readBuffer, 50000, out bytesRead);

                if (bytesRead == 0) throw new Exception(string.Format("{0}: No more bytes!", ec));
                Console.WriteLine("{0} bytes read", bytesRead);

                // Write that output to the console.
                Console.Write(Encoding.Default.GetString(readBuffer, 0, bytesRead));
            }

            Console.WriteLine("\r\nDone!\r\n");
        }
        catch (Exception ex)
        {
            Console.WriteLine((ec != ErrorCode.None ? ec + ":" : String.Empty) + ex.Message);
        }
        finally
        {
            if (MyUsbDevice != null)
            {
                if (MyUsbDevice.IsOpen)
                {
                    // If this is a "whole" usb device (libusb-win32, linux libusb-1.0)
                    // it exposes an IUsbDevice interface. If not (WinUSB) the 
                    // 'wholeUsbDevice' variable will be null indicating this is 
                    // an interface of a device; it does not require or support 
                    // configuration and interface selection.
                    IUsbDevice wholeUsbDevice = MyUsbDevice as IUsbDevice;
                    if (!ReferenceEquals(wholeUsbDevice, null))
                    {
                        // Release interface #0.
                        wholeUsbDevice.ReleaseInterface(1);
                    }

                    MyUsbDevice.Close();
                }
                MyUsbDevice = null;

                // Free usb resources
                UsbDevice.Exit();

            }

        }
    }

至今:

  • 可以设置配置#1
  • 可以声明接口#1
  • endpointInfo 显示,即正确选择了端点

但尝试在 C# 应用程序中读/写总是会导致“IOTimedOut”错误。

所以我想知道我可能做错了什么,是否有可能使 cc2538 与 libusb-win32 一起工作。

提前感谢您的帮助。

4

0 回答 0