简而言之,我的总体目标是:我想通过 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 一起工作。
提前感谢您的帮助。