C#
获取设备端点,点击Start,启动线程不断接收USB设备传来的数据,并保存到文件中。
窗体设计
源码
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using System.IO;
using CyUSB;//需要添加CyUSB.dll引用
namespace USBSynDemo
{
public partial class Form1 : Form
{
//USB设备相关字段
USBDeviceList usbDevices;
CyUSBDevice MyDevice;
CyUSBEndPoint EndPoint;
const int XFERSIZE=512;
int BufSz = 512;
int QueueSz = 1;//4
int IsoPktBlockSize;
bool bRunning = false;
Thread tReceiveData = null;
string filePath = @"D:\testdata.dat";//存入字节数据
public Form1()
{
InitializeComponent();
usbDevices = new USBDeviceList(CyConst.DEVICES_CYUSB);
SetDevice();
}
private void SetDevice()
{
USBDevice dev = usbDevices[0x04B4, 0x1003];
if (dev != null)
{
MyDevice = (CyUSBDevice)dev;
GetEndpointsOfNode(MyDevice.Tree);
if (EndPointsComboBox.Items.Count > 0)
{
EndPointsComboBox.SelectedIndex = 0;
StartBtn.Enabled = true;
}
}
else
{
StartBtn.Enabled = false;
EndPointsComboBox.Items.Clear();
EndPointsComboBox.Text = "";
}
}
private void GetEndpointsOfNode(TreeNode devTree)
{
foreach (TreeNode node in devTree.Nodes)
{
if (node.Nodes.Count > 0)
GetEndpointsOfNode(node);
else
{
CyUSBEndPoint ept = node.Tag as CyUSBEndPoint;
if (ept == null)
{
//return;
}
else if (!node.Text.Contains("Control"))
{
CyUSBInterface ifc = node.Parent.Tag as CyUSBInterface;
string s = string.Format("ALT-{0}, {1} Byte, {2}", ifc.bAlternateSetting, ept.MaxPktSize, node.Text);
EndPointsComboBox.Items.Add(s);
}
}
}
}
private void Form1_Load(object sender, EventArgs e)
{
if (EndPointsComboBox.Items.Count > 0)
EndPointsComboBox.SelectedIndex = 0;
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
if (usbDevices != null)
usbDevices.Dispose();
}
//从列表中选择端点
private void EndPointsComboBox_SelectedIndexChanged(object sender, EventArgs e)
{
// Get the Alt setting
string sAlt = EndPointsComboBox.Text.Substring(4, 1);
byte a = Convert.ToByte(sAlt);
MyDevice.AltIntfc = a;
// Get the endpoint
int aX = EndPointsComboBox.Text.LastIndexOf("0x");
string sAddr = EndPointsComboBox.Text.Substring(aX, 4);
byte addr = (byte)Util.HexToInt(sAddr);
EndPoint = MyDevice.EndPointOf(addr);
}
private void StartBtn_Click(object sender, EventArgs e)
{
if (MyDevice == null)
return;
if (StartBtn.Text.Equals("Start"))
{
EndPointsComboBox.Enabled = false;
StartBtn.Text = "Stop";
StartBtn.BackColor = Color.Pink;
EndPoint.XferSize = XFERSIZE;
if (EndPoint is CyIsocEndPoint)
IsoPktBlockSize = (EndPoint as CyIsocEndPoint).GetPktBlockSize(XFERSIZE);
else
IsoPktBlockSize = 0;
bRunning = true;
tReceiveData = new Thread(new ThreadStart(XferThread));
tReceiveData.IsBackground = true;
tReceiveData.Priority = ThreadPriority.Highest;
tReceiveData.Start();
}
else
{
if (tReceiveData.IsAlive)
{
EndPointsComboBox.Enabled = true;
StartBtn.Text = "Start";
bRunning = false;
tReceiveData.Abort();
StartBtn.BackColor = Color.Aquamarine;
}
}
}
public unsafe void XferThread()
{
// Setup the queue buffers
byte[][] cmdBufs = new byte[QueueSz][];
byte[][] xferBufs = new byte[QueueSz][];
byte[][] ovLaps = new byte[QueueSz][];
ISO_PKT_INFO[][] pktsInfo = new ISO_PKT_INFO[QueueSz][];
int xStart = 0;
try
{
LockNLoad(ref xStart, cmdBufs, xferBufs, ovLaps, pktsInfo);
}
catch (NullReferenceException e)
{
// This exception gets thrown if the device is unplugged
// while we're streaming data
e.GetBaseException();
}
}
public unsafe void LockNLoad(ref int j, byte[][] cBufs, byte[][] xBufs, byte[][] oLaps, ISO_PKT_INFO[][] pktsInfo)
{
cBufs[j] = new byte[CyConst.SINGLE_XFER_LEN + IsoPktBlockSize + ((EndPoint.XferMode == XMODE.BUFFERED)? BufSz : 0)];
xBufs[j] = new byte[BufSz];
oLaps[j] = new byte[CyConst.OverlapSignalAllocSize];
pktsInfo[j] = new ISO_PKT_INFO[1];
fixed (byte* tL0 = oLaps[j], tc0 = cBufs[j], tb0 = xBufs[j]) // Pin the buffers in memory
{
OVERLAPPED* ovLapStatus = (OVERLAPPED*)tL0;
ovLapStatus->hEvent = (IntPtr)PInvoke.CreateEvent(0, 0, 0, 0);
// Pre-load the queue with a request
int len = BufSz;
EndPoint.BeginDataXfer(ref cBufs[j], ref xBufs[j], ref len, ref oLaps[j]);
j++;
if (j < QueueSz)
LockNLoad(ref j, cBufs, xBufs, oLaps, pktsInfo); // Recursive call to pin next buffers in memory
else
XferData(cBufs, xBufs, oLaps, pktsInfo); // All loaded. Let's go!
}
}
public unsafe void XferData(byte[][] cBufs, byte[][] xBufs, byte[][] oLaps, ISO_PKT_INFO[][] pktsInfo)
{
int k = 0;
int len = 0;
for (; bRunning; )
{
// WaitForXfer
fixed (byte* tmpOvlap = oLaps[k])
{
OVERLAPPED* ovLapStatus = (OVERLAPPED*)tmpOvlap;
if (!EndPoint.WaitForXfer(ovLapStatus->hEvent, 500))
{
EndPoint.Abort();
PInvoke.WaitForSingleObject(ovLapStatus->hEvent, 500);
}
}
len = BufSz;
// FinishDataXfer
if (EndPoint.FinishDataXfer(ref cBufs[k], ref xBufs[k], ref len, ref oLaps[k]))
{
//保存接收的数据到文件中
FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read);
fs.Write(xBufs[k], 0, len);
fs.Close();
}
// Re-submit this buffer into the queue
EndPoint.BeginDataXfer(ref cBufs[k], ref xBufs[k], ref len, ref oLaps[k]);
k++;
if (k == QueueSz) // Only update displayed stats once each time through the queue
{
k = 0;
}
} // End infinite loop
}
}
}