一、技术选型对比
| 库名称 | 适用场景 | 优势 | 局限性 |
|---|---|---|---|
| LibUsbDotNet | 通用USB设备通信 | 跨平台支持,API完善 | 需要安装libusb驱动 |
| HidSharp | HID类设备(键盘/鼠标等) | 封装简单,支持异步通信 | 仅限HID协议设备 |
| Windows API | 定制化USB开发 | 直接操作底层接口 | 代码复杂度高 |
二、核心实现方案(基于LibUsbDotNet)
1. 设备枚举与连接
using LibUsbDotNet;
using LibUsbDotNet.Main;
public class UsbService {
private UsbDevice _device;
private UsbEndpointReader _reader;
private UsbEndpointWriter _writer;
// 初始化设备
public bool Connect(int vid, int pid) {
var finder = new UsbDeviceFinder(vid, pid);
_device = UsbDevice.OpenUsbDevice(finder);
if (_device == null) return false;
try {
_device.Open();
IUsbDevice wholeDevice = _device as IUsbDevice;
if (wholeDevice != null) {
wholeDevice.SetConfiguration(1);
wholeDevice.ClaimInterface(0);
}
_reader = _device.OpenEndpointReader(ReadEndpointID.Ep01);
_writer = _device.OpenEndpointWriter(WriteEndpointID.Ep01);
return true;
} catch {
_device.Close();
return false;
}
}
// 断开连接
public void Disconnect() {
_reader?.Dispose();
_writer?.Dispose();
_device?.Close();
UsbDevice.Exit();
}
}
2. 数据传输实现
// 同步发送数据
public int SendData(byte[] data) {
int bytesWritten;
ErrorCode ec = _writer.Write(data, 1000, out bytesWritten);
return ec == ErrorCode.None ? bytesWritten : -1;
}
// 同步接收数据
public byte[] ReceiveData() {
byte[] buffer = new byte[1024];
int bytesRead;
ErrorCode ec = _reader.Read(buffer, 5000, out bytesRead);
return ec == ErrorCode.None ? buffer.Take(bytesRead).ToArray() : null;
}
// 异步接收(推荐)
public async Task<byte[]> AsyncReceive() {
var buffer = new byte;
var readTask = _reader.ReadAsync(buffer, 5000);
await readTask.ConfigureAwait(false);
return readTask.Result.Length > 0
? readTask.Result.Take(readTask.Result.Length).ToArray()
: null;
}
三、高级功能实现
1. 控制传输(配置设备)
public void SendControlCommand(byte requestType, byte request, ushort value, ushort index, byte[] data) {
int transferred;
_device.ControlTransfer(
(LibUsbDotNet.Main.ControlTransferFlags)requestType,
request,
value,
index,
data,
data.Length,
out transferred,
5000);
}
2. 批量传输(高速数据)
// 配置批量端点
public void ConfigureBulkTransfer() {
var deviceDesc = _device.DeviceDescriptor;
_writer = _device.OpenEndpointWriter(
ReadEndpointID.Ep02, // 批量输入端点
512, // 最大包尺寸
EndpointDirection.In);
}
// 执行批量传输
public int BulkWrite(byte[] data) {
int bytesWritten;
_writer.Write(data, 1000, out bytesWritten);
return bytesWritten;
}
四、工程实践要点
1. 设备热插拔检测
public static class UsbHotplug {
private static UsbDeviceList _devices = new();
public static void MonitorChanges(Action<UsbDevice> added, Action<UsbDevice> removed) {
_devices = UsbDevice.AllDevices;
Timer timer = new Timer(_ => {
var current = UsbDevice.AllDevices;
var addedDevices = current.Except(_devices).ToList();
var removedDevices = _devices.Except(current).ToList();
addedDevices.ForEach(added);
removedDevices.ForEach(removed);
_devices = current;
}, null, 1000, 1000);
}
}
2. 数据校验机制
// CRC16校验
public ushort CalculateCRC(byte[] data) {
ushort crc = 0xFFFF;
foreach (byte b in data) {
crc ^= (ushort)(b << 8);
for (int i = 0; i < 8; i++) {
crc <<= 1;
if ((crc & 0x10000) != 0) crc ^= 0x1021;
}
}
return crc;
}
// 数据封装
public byte[] CreatePacket(byte[] payload) {
ushort crc = CalculateCRC(payload);
return new byte[] {
0xAA, 0x55 }
.Concat(payload)
.Concat(BitConverter.GetBytes(crc))
.ToArray();
}
五、调试与优化
1. 调试工具推荐
- USBView:查看设备拓扑和端点信息
- Wireshark+USBPcap:抓取USB通信数据包
- Bus Hound:实时监控USB数据流量
2. 性能优化方案
// 双缓冲区技术
private byte[] _bufferA = new byte;
private byte[] _bufferB = new byte;
private bool _useBufferA = true;
// 零拷贝传输
public async Task<int> HighSpeedTransfer(byte[] data) {
var buffer = _useBufferA ? _bufferA : _bufferB;
Array.Copy(data, buffer, data.Length);
_useBufferA = !_useBufferA;
return await _writer.WriteAsync(buffer, 100);
}
参考代码 C# USB 发送和接收数据 www.youwenfan.com/contentalg/92801.html
六、完整项目结构
USBCommunication/
├── Libs/ # 第三方库
│ └── LibUsbDotNet.dll
├── Devices/ # 设备配置
│ └── DeviceConfig.json
├── Src/
│ ├── UsbService.cs # 核心通信类
│ ├── ProtocolHandler.cs # 协议解析
│ └── HotplugMonitor.cs
└── Tests/ # 单元测试
└── UsbCommunicationTests.cs
七、常见问题解决方案
- 访问被拒绝 以管理员身份运行程序 使用
Zadig工具安装WinUSB驱动 - 数据丢失 增加数据包序号校验 设置合理的超时时间(建议500-2000ms)
- 设备识别失败 检查VID/PID是否正确 使用
lsusb(Linux)或USBDeview(Windows)验证设备状态
该方案支持HID设备、CDC类设备等多种USB通信场景,可通过扩展以下功能增强系统:
- 多设备并发:使用
ConcurrentDictionary管理多个连接 - 固件升级:实现DFU协议支持
- 加密传输:集成AES-256加密算法