我已经将一个Web应用程序移植到.NET Core上,我发现它可以在Windows上运行时通过USB与微控制器通信,但在Linux上运行则不行.我正在尝试解决:
为什么会这样(这是我正在使用的库中的错误,还是我错误配置了Linux环境?)
我如何解决或解决它(替代图书馆,环境变化等)
如果有人成功设法创建一个基于.NET Core的应用程序,可以通过USB以平台无关的方式进行通信,我将非常感谢您的输入.
作为本文其余部分的参考,这些是关于我当前环境的一些细节:
我以前有一个基于.NET Framework的Web服务,我用来控制微控制器.基于.NET Framework,它仅限于在Windows上运行.为了实现跨平台支持,我开始将应用程序移植到.NET Core.这个任务现在或多或少是完整的 - 例如,我现在可以构建和运行我的应用程序作为Docker服务,我认为这将是非常有益的.
我的应用程序分为多个项目,但就本文而言,我只讨论两个:
基于ASP.NET Core的Web服务项目,它使应用程序的核心功能可以通过Web通信进行控制.1它将所有其他内容联系在一起,是我实际执行的内容dotnet <<application.dll>>.
一个USB通信服务项目,负责处理与USB设备的通信.2它目前使用CoreCompat.LibUsbDotNet库(v2.2.8-r101),它分别作为Windows和Unix上的库WinUSB和libusb库的跨平台C#适配器.该项目作为Nuget包分发,由Web服务使用,并且是问题所在.
当我在Windows下直接运行它时,应用程序运行正常.但是,如果我尝试在Linux虚拟机或Docker服务上运行它,Web服务将无法初始化,并出现错误,抱怨libusb-1.0 library无法找到它.3
根据此错误消息,我尝试检查我尝试运行该应用程序的Linux VM和Docker容器的环境. 4
将我的USB设备安装在Docker虚拟机上并在特权模式下运行基于我的Web应用程序映像的容器后,我可以确认它看到了我的USB设备:
root@19e8929e1814:/app# lsusb
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 002: ID 2b87:0001
Bus …Run Code Online (Sandbox Code Playgroud) 我正在执行 LibUsbDotNet 的示例代码,它将返回所有连接的 USB 设备的信息。您可以在下面找到此代码。
using System;
using LibUsbDotNet;
using LibUsbDotNet.Info;
using LibUsbDotNet.Main;
using System.Collections.ObjectModel;
namespace Examples
{
internal class ShowInfo
{
public static UsbDevice MyUsbDevice;
public static void Main(string[] args)
{
// Dump all devices and descriptor information to console output.
UsbRegDeviceList allDevices = UsbDevice.AllDevices;
foreach (UsbRegistry usbRegistry in allDevices)
{
if (usbRegistry.Open(out MyUsbDevice))
{
Console.WriteLine(MyUsbDevice.Info.ToString());
for (int iConfig = 0; iConfig < MyUsbDevice.Configs.Count; iConfig++)
{
UsbConfigInfo configInfo = MyUsbDevice.Configs[iConfig];
Console.WriteLine(configInfo.ToString());
ReadOnlyCollection<UsbInterfaceInfo> interfaceList = configInfo.InterfaceInfoList;
for (int iInterface = …Run Code Online (Sandbox Code Playgroud) 我在与简单 USB 设备通信的 WPF 应用程序中使用 LibUSBDotNet 库。我只向设备发送 3 个字节作为命令,没有预期的响应,我的代码就像一个魅力:
MyUsbFinder = new UsbDeviceFinder(vid, pid);
MyUsbDevice = UsbDevice.OpenUsbDevice(MyUsbFinder);
wholeUsbDevice = MyUsbDevice as IUsbDevice;
if (!ReferenceEquals(wholeUsbDevice, null))
{
wholeUsbDevice.SetConfiguration(1);
wholeUsbDevice.ClaimInterface(0);
}
writer = MyUsbDevice.OpenEndpointWriter(WriteEndpointID.Ep01);
Run Code Online (Sandbox Code Playgroud)
然后是写入设备的过程:
byte[] update = { 0x21, some_code_generated_byte, some_code_generated_byte };
int bytesWritten;
if (MyUsbDevice != null)
{
ec = writer.Write(update, 2000, out bytesWritten);
}
Run Code Online (Sandbox Code Playgroud)
我对使用 USB 还比较陌生,但到目前为止我已经掌握了一切,而且一切正常。但是,一段时间后,在尝试再次写入设备时,我会时不时地遇到以下两个错误之一:
Win32Error:GetOverlappedResult Ep 0x01
31:The parameter is incorrect.
Win32Error:PipeTransferSubmit Ep 0x01
87:The parameter is incorrect.
Run Code Online (Sandbox Code Playgroud)
通常我需要重新启动设备/应用程序几次,然后它才能再次开始工作,然后在它再次发生之前又像魅力一样工作了几个小时......到目前为止,我也无法在测试环境中复制崩溃.
我做了很多研究,试图找到与我类似的问题/解决方案,但没有成功。我留下的唯一建议是,在某些时候设备没有足够的电量,它会进入这种错误模式,但即使这样似乎也不太可能,因为它有一个单独的 12V 电源,它所做的只是打开和关闭几个继电器...
我还尝试用大量连续命令一个接一个地淹没设备,包括垃圾命令,但它仍然可以正常工作并且行为正常,只是稍后会崩溃。
欢迎任何建议或想法,谢谢!
编辑:经过多次尝试后,我仍然无法确定问题的根本原因,但我设法达到了代码正常工作的程度,并且能够使用尝试重置设备的重新连接功能从 OverlappedResult …
我有一个通过SX Virtual Link连接到网络的KODAK i2600扫描仪,该网络在该网络中的每台PC上都模拟了与扫描仪的USB连接。我可以像这样轻松地找到仿真的USB pid和vid:

或这个: 
我尝试使用LibUsbDotNet来检测信号,但以他们的示例为例,它只是行不通。我尝试了以下示例:
public static UsbDevice MyUsbDevice;
#region SET YOUR USB Vendor and Product ID!
public static UsbDeviceFinder MyUsbFinder = new UsbDeviceFinder(int.Parse("040a", System.Globalization.NumberStyles.HexNumber), int.Parse("601d", System.Globalization.NumberStyles.HexNumber));
#endregion
public static void Main(string[] args)
{
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) …Run Code Online (Sandbox Code Playgroud) 在WPF应用程序中使用USB设备,我可以成功连接并向设备发送命令.设备只接收命令,没有回复,所以我需要的是一个与之通信的EndpointWriter.
MyUsbFinder = new UsbDeviceFinder(vid, pid);
MyUsbDevice = UsbDevice.OpenUsbDevice(MyUsbFinder);
wholeUsbDevice = MyUsbDevice as IUsbDevice;
if (!ReferenceEquals(wholeUsbDevice, null))
{
wholeUsbDevice.SetConfiguration(1);
wholeUsbDevice.ClaimInterface(0);
}
writer = MyUsbDevice.OpenEndpointWriter(WriteEndpointID.Ep01);
Run Code Online (Sandbox Code Playgroud)
然后写入设备的过程:
byte[] update = { some bytes };
int bytesWritten;
if (MyUsbDevice != null)
{
ec = writer.Write(update, 2000, out bytesWritten);
}
Run Code Online (Sandbox Code Playgroud)
一切正常,包括关闭应用程序,除非在工作过程中USB设备断开然后重新连接.应用程序成功处理此方案并重新连接到设备,继续成功向其发送命令:
public bool reconnect()
{
//clear the info so far
if (MyUsbDevice != null)
{
writer.Dispose();
wholeUsbDevice.ReleaseInterface(0);
wholeUsbDevice.Close();
MyUsbDevice.Close();
UsbDevice.Exit();
}
//now start over
MyUsbFinder = new UsbDeviceFinder(vid, pid);
MyUsbDevice = UsbDevice.OpenUsbDevice(MyUsbFinder);
Run Code Online (Sandbox Code Playgroud)
......等等.
在发生此类断开/重新连接后关闭应用程序时会发生此问题.虽然该程序成功运行并与设备通信了很长一段时间,但在退出时我得到以下异常: …