这个例子适用于传统的USB硬件,不可以将此例子用于非USB设备,To meet the requirements, your usb hardware must implement loopback functionality in Config 1, Interface 0, Endpoints 0x01 and 0x81.
Read Write(Polling)
1 通过vendor和product id打开USB设备
2 打开类UsbEndpointReader进行读
3 打开类UsbEndpointWriter进行写
4 向Ep01写入
5 从Ep01中读取并显示usb设备的输出
HID class(人机交互类):使用HID设备的好处:操作系统自带了HID类的驱动程序,用户无需去开发很麻烦的驱动程序,只要直接使用API调用即可完成通信。
HID的通信管道:
所有的HID设备通过USB的控制管道(默认管道,即端点0)和中断管道与主机通信。
管道
控制(端点0)(必须):传输USB描述符、类请求代码已经供查询的消息数据等;
中断输入(必须):传输从设备到主机的输入数据
中断输出(可选):传输从主机到设备的输出数据
控制管道的主要应用:
1、接受/响应USB主机的控制请示及相关的类数据
2、在USB主机查询时传输数据(如响应Get_Report请求等)
3、接收USB主机的数据
中断管道的主要应用:
1、USB主机接收USB设备的异步传输数据
2、USB主机发送有实时性要求的数据给USB设备
从USB主机到USB设备的中断输出数据传输是可选的,当不支持中断输出数据传输时,USB主机通过控制管道将数据传输给USB设备。
USB HID类命令(请求)
HID设备类特定的命令(请求)有6个,分别为Get_Report Get_Idle Get_Protocol Set_Report Set_Idle Set_Protocol
数值
0x01
0x02
0x03
0x09
0x0A
0x0B
USB主机在请求HID设备的配置描述符时,设备首先返回的描述符为:配置描述符、接口描述符、HID描述符、端点描述符。HID描述符里包含了其附属的描述的类型和长度(如报告描述符),然后主机再根据HID描述符的信息请求其相关的描述符
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using LibUsbDotNet;
using LibUsbDotNet.Main;
namespace LibUsbDotNet_Learn
{
class Program
{
public static UsbDevice MyUsbDevice;
//设置USB的Vendor Product ID
public static UsbDeviceFinder MyUsbFinder = new UsbDeviceFinder(0x1f3b, 0x1000);
static void Main(string[] args)
{
//保存异常数据
ErrorCode ec = ErrorCode.None;
try
{
//找到并打开USB设备
MyUsbDevice = UsbDevice.OpenUsbDevice(MyUsbFinder);
if(MyUsbDevice==null)
{
throw new Exception("Device Not Found");
}
//如果设备打开and ready
//libusb-win32是"whole"USB device,为IUsbDevice interface,不是(WinUSB),则变量
//wholeUSBDevice变量为null,是device interface,不需要configuration 和 interface
//as is 判断两个变量是否相等,is 返回TRUE/FALSE; as 相同返回结果,不同返回null
IUsbDevice wholeUsbDevice = MyUsbDevice as IUsbDevice;
if(!ReferenceEquals(wholeUsbDevice,null))
{
//这是个"whole"USB device,使用前选择configuration interface
//选中配置1
wholeUsbDevice.SetConfiguration(1);
wholeUsbDevice.ClaimInterface(0);
}
//打开并读取read endpoint1
UsbEndpointReader reader = MyUsbDevice.OpenEndpointReader(ReadEndpointID.Ep01);
byte[] readBuffer=new byte[1024];
//如果5秒内设备没有发生数据,发生timeout error(ec=IoTimedOut)
while(ec==ErrorCode.None) //一直在读取
{
int bytesRead;
ec = reader.Read(readBuffer, 5000, out bytesRead);
if (bytesRead == 0) throw new Exception(string.Format("{0}:No more bytes",ec));
Console.WriteLine("{0} bytes read", bytesRead);
//将结果输出到控制台上
Console.Write(Encoding.Default.GetString(readBuffer, 0, bytesRead));
}
Console.WriteLine("\r\n Done! \r\n");
}
catch (System.Exception ex)
{
Console.WriteLine();
Console.WriteLine((ec != ErrorCode.None ? ec + ":" : string.Empty) + ex.Message);
}
//读取数据后执行
finally
{
if(MyUsbDevice!=null)
{
if (MyUsbDevice.IsOpen)
{
IUsbDevice wholeUsbDevice = MyUsbDevice as IUsbDevice;
if(!ReferenceEquals(wholeUsbDevice,null))
{
//释放interface 0
wholeUsbDevice.ReleaseInterface(0);
}
MyUsbDevice.Close();
}
MyUsbDevice = null;
//释放usb资源
UsbDevice.Exit();
}
Console.ReadKey();
}
}
}
}