【问题标题】:Cross-platform USB communication using ASP.NET Core使用 ASP.NET Core 的跨平台 USB 通信
【发布时间】:2017-01-12 10:30:11
【问题描述】:

概述

我已将一个 Web 应用程序移植到 .NET Core,我发现它在 Windows 上运行时能够通过 USB 与微控制器通信,但在 Linux 上运行时却不能。我正在努力锻炼:

  • 为什么会这样(是我正在使用的库中的错误,还是我错误配置了 Linux 环境?)

  • 我如何解决或解决它(替代库、环境更改等)

如果有人成功地创建了一个基于 .NET Core 的应用程序,该应用程序可以通过 USB 以与平台无关的方式进行通信,我将非常感谢您的意见。

环境

作为本文其余部分的参考,以下是有关我当前环境的一些详细信息:

  • Windows 7 64 位主机
  • Dotnet 版本 1.0.0-preview2-003131
  • Docker 版本 1.12.0,构建 8eab29e
  • Docker 工具箱(我相信是 v1.12.3)
  • VirtualBox v5.0.30 r112061

详情

我以前有一个基于 .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),它作为WinUSBlibusb 库之上的跨平台C# 适配器分别在 Windows 和 Unix 上。这个项目是作为一个被网络服务使用的 Nuget 包分发的,这就是问题所在。

当我直接在 Windows 下运行该应用程序时,它运行良好。但是,如果我尝试在 Linux 虚拟机上运行它或将其作为 Docker 服务运行,Web 服务将无法初始化并出现错误,提示无法找到 libusb-1.0 library3

根据此错误消息,我已尝试检查我尝试在其上运行应用程序的 Linux VM 和 Docker 容器的环境。 4

在 Docker 虚拟机上挂载我的 USB 设备并以特权模式运行基于我的 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 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

我还确认 libusb-1.0 已安装 5 并检查它是否可从 ldconfig 缓存中获得:

root@19e8929e1814:/app# ldconfig -p | grep libusb
libusb-1.0.so.0 (libc6,x86-64) => /lib/x86_64-linux-gnu/libusb-1.0.so.0
libusb-1.0.so (libc6,x86-64) => /usr/lib/x86_64-linux-gnu/libusb-1.0.so
libusb-0.1.so.4 (libc6,x86-64) => /lib/x86_64-linux-gnu/libusb-0.1.so.4
libusb-0.1.so.4 (libc6,x86-64) => /usr/lib/x86_64-linux-gnu/libusb-0.1.so.4

基于此,我不知道为什么CoreCompat.LibUsbDotNet 会抛出无法找到libusb-1.0 的异常,只能假设这是库中的错误。

有没有人成功地使用这个库在 Unix 环境下进行通信?或者,是否有人为基于 .NET Core 的应用程序找到了另一种以与平台无关的方式与 USB 设备通信的方式?

参考文献

[1] project.json 用于 Web 服务项目

{
  "dependencies": {
    "<<Company>>.Communications.<<Product>>Usb": "0.4.9",
    "<<Company>>.<<Product>>Web.Core": {
      "target": "project"
    },
    "<<Company>>.<<Product>>WebComponentPackage": "0.4.9-beta0002",
    "Autofac": "4.2.1",
    "Common.Logging": "3.4.0-Beta2",
    "Microsoft.AspNetCore.Diagnostics": "1.1.0-preview1-final",
    "Microsoft.AspNetCore.Server.IISIntegration": "1.1.0-preview1-final",
    "Microsoft.AspNetCore.Server.Kestrel": "1.1.0",
    "Microsoft.AspNetCore.StaticFiles": "1.1.0",
    "Microsoft.AspNetCore.WebSockets.Server": "0.1.0",
    "Microsoft.Extensions.DependencyModel": "1.1.0-preview1-001100",
    "Microsoft.Extensions.Logging.Console": "1.1.0",
    "Microsoft.NETCore.App": {
      "version": "1.1.0",
      "type": "platform"
    },
    "Serilog.Enrichers.Thread": "3.0.0",
    "Serilog.Sinks.Literate": "2.1.0-dev-00034",
    "Serilog.Sinks.RollingFile": "3.3.0",
    "System.Runtime.Loader": "4.3.0",
    "Thrower": "3.0.4"
  },

  "tools": {
  },

  "frameworks": {
    "netcoreapp1.1": {
      "imports": [
        "dotnet5.6",
        "portable-net45+win8"
      ]
    }
  },

  "buildOptions": {
    "emitEntryPoint": true,
    "preserveCompilationContext": true
  },

  "runtimeOptions": {
    "configProperties": {
      "System.GC.Server": true
    }
  },

  "publishOptions": {
    "include": [
      "wwwroot",
      "web.config"
    ]
  },

  "scripts": {
    "postpublish": [ "dotnet publish-iis --publish-folder %publish:OutputPath% --framework %publish:FullTargetFramework%" ]
  }
}

[2] project.json 用于 USB 通信项目

{
  "version": "0.4.9-*",
  "description": "Provides a type of communication service that facilitates communication between .NET applications and <<Product>> over USB.",
  "authors": ["<<Author>>"],

  "dependencies": {
    "Microsoft.Composition": "1.0.30",
    "Microsoft.NETCore.Portable.Compatibility": "1.0.1",
    "Thrower": "3.0.4",
    "CoreCompat.LibUsbDotNet": "2.2.8-r101",
    "Common.Logging": "3.4.0-Beta2",
    "<<Company>>.Message": "0.4.3",
    "NETStandard.Library": "1.6.1",
    "<<Company>>.Communications.Core": "0.4.5",
    "Serilog": "2.3.0"
  },
  "packOptions": {
    "owners": ["<<Company>>"],
    "repository": {
      "type": "git",
      "url": "https://bitbucket.org/<<Company>>-dev/<<Product>>usb"
    }
  },
  "frameworks": {
    "netstandard1.4": {
      "imports": [ "dnxcore50", "portable-net45+win8" ]
    }
  },
  "buildOptions": {
    "xmlDoc": true
  }
}

[3] USB通讯失败异常

Unhandled Exception: System.DllNotFoundException: libusb-1.0 library not found.  This is often an indication that libusb-1.0 was installed to '/usr/local/lib' and
 mono.net is not looking for it there. To resolve this, add the path '/usr/local/lib' to '/etc/ld.so.conf' and run 'ldconfig' as root. (http://www.mono-project.co
m/DllNotFoundException) ---> System.DllNotFoundException: Unable to load DLL 'libusb-1.0.dll': The specified module could not be found.
 (Exception from HRESULT: 0x8007007E)
   at MonoLibUsb.MonoUsbApi.Init(IntPtr& pContext)
   at MonoLibUsb.MonoUsbSessionHandle..ctor()
   --- End of inner exception stack trace ---
   at MonoLibUsb.MonoUsbSessionHandle..ctor()
   at MonoLibUsb.MonoUsbEventHandler.Init(UnixNativeTimeval unixNativeTimeval)
   at MonoLibUsb.MonoUsbEventHandler.Init()
   at MonoLibUsb.MonoUsbApi.InitAndStart()
   at LibUsbDotNet.LudnMonoLibUsb.MonoUsbDevice.get_MonoUsbDeviceList()
   at LibUsbDotNet.Main.LegacyUsbRegistry.get_DeviceList()
   at LibUsbDotNet.UsbDevice.get_AllLibUsbDevices()
   at LibUsbDotNet.UsbDevice.get_AllDevices()
   at LibUsbDotNet.UsbDevice.OpenUsbDevice(Predicate`1 findDevicePredicate)
   at LibUsbDotNet.UsbDevice.OpenUsbDevice(UsbDeviceFinder usbDeviceFinder)
   at <<Company>>.Communications.<<Product>>Usb.UsbCommunicationService.Start()
   at <<Company>>.<<Product>>Web.Core.DeviceController.Initialize()
   at <<Company>>.<<Product>>Web.ServiceAdapters.WebSockets.Startup.ConfigureServices(IServiceCollection services)
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at Microsoft.AspNetCore.Hosting.ConventionBasedStartup.ConfigureServices(IServiceCollection services)
   at Microsoft.AspNetCore.Hosting.Internal.WebHost.EnsureApplicationServices()
   at Microsoft.AspNetCore.Hosting.Internal.WebHost.BuildApplication()
   at Microsoft.AspNetCore.Hosting.WebHostBuilder.Build()
   at <<Company>>.<<Product>>Web.ServiceAdapters.WebSockets.Program.Main(String[] args)

[4] Web 服务 Dockerfile

FROM microsoft/aspnetcore:1.1.0
ENTRYPOINT ["dotnet", "bin/Debug/netcoreapp1.1/publish/<<Company>>.<<Product>>Web.ServiceAdapters.WebSockets.dll"]
ARG source=.
WORKDIR /app
EXPOSE 80
COPY $source .
RUN apt-get update
RUN apt-get install -y libusb-1.0-0-dev usbutils

[5] find / -name libusb* 在 Docker 容器上的输出

root@19e8929e1814:/app# find / -name libusb*
/lib/x86_64-linux-gnu/libusb-1.0.so.0
/lib/x86_64-linux-gnu/libusb-1.0.so.0.1.0
/lib/x86_64-linux-gnu/libusb-0.1.so.4.4.4
/lib/x86_64-linux-gnu/libusb-0.1.so.4
/usr/lib/x86_64-linux-gnu/libusb-1.0.a
/usr/lib/x86_64-linux-gnu/pkgconfig/libusb-1.0.pc
/usr/lib/x86_64-linux-gnu/libusb-1.0.so
/usr/lib/x86_64-linux-gnu/libusb-0.1.so.4
/usr/include/libusb-1.0
/usr/include/libusb-1.0/libusb.h
/usr/share/doc/libusb-1.0-0
/usr/share/doc/libusb-1.0-doc
/usr/share/doc/libusb-1.0-doc/html/libusb_8h_source.html
/usr/share/doc/libusb-1.0-0-dev
/usr/share/doc/libusb-0.1-4
/usr/share/doc-base/libusb-1.0-doc
/var/lib/dpkg/info/libusb-1.0-0-dev:amd64.md5sums
/var/lib/dpkg/info/libusb-1.0-doc.list
/var/lib/dpkg/info/libusb-1.0-0:amd64.md5sums
/var/lib/dpkg/info/libusb-1.0-0:amd64.symbols
/var/lib/dpkg/info/libusb-1.0-0:amd64.shlibs
/var/lib/dpkg/info/libusb-1.0-0:amd64.list
/var/lib/dpkg/info/libusb-1.0-0:amd64.postrm
/var/lib/dpkg/info/libusb-1.0-0:amd64.postinst
/var/lib/dpkg/info/libusb-1.0-doc.md5sums
/var/lib/dpkg/info/libusb-1.0-0-dev:amd64.list
/var/lib/dpkg/info/libusb-0.1-4:amd64.postrm
/var/lib/dpkg/info/libusb-0.1-4:amd64.shlibs
/var/lib/dpkg/info/libusb-0.1-4:amd64.symbols
/var/lib/dpkg/info/libusb-0.1-4:amd64.postinst
/var/lib/dpkg/info/libusb-0.1-4:amd64.list
/var/lib/dpkg/info/libusb-0.1-4:amd64.md5sums

【问题讨论】:

  • (1) USB库有样品吗?您可以运行该示例以确保 .NET 库在您的 Linux/Docker 环境中运行(或不运行)。并且 (2) - 你在 frameworks 中有 netcoreapp1.0 但在依赖项中有 Microsoft.NETCore.App 1.1.0....尝试将它们对齐到相同的版本。
  • (1) CoreCompat.LibUsbDotNet 库?没有我知道的样品。事实上,我能够为该库找到的只是 Nuget 页面。有基于 .NET Framework 的 LibUsbDotNet 的成熟版本的示例,但在这种情况下对我没有帮助。 (2) 感谢您指出这一点,我已经更正了。

标签: c# asp.net-core usb libusb-1.0 libusbdotnet


【解决方案1】:

将实际共享库链接到您拥有的 .Net Core 版本的共享库位置。我已设法使用以下方法加载库:

ln -s /lib/x86_64-linux-gnu/libusb-1.0.so.0 /opt/dotnet/shared/Microsoft.NETCore.App/1.1.0/libusb-1.0.dll

我还没有得到设备列表。

this issue on Github

【讨论】:

  • 说真的,你用单行命令解决了一个困扰我好几个月的问题。我只需要稍作改动:/usr/share/dotnet/shared/Microsoft.NETCore.App/1.1.0/libusb-1.0.dll。在我接受这一点并奖励赏金之前,您能否简要解释一下为什么创建该符号链接有助于我和未来读者的利益?
  • 好吧,看来你不会回来了,所以我就接受这个。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-06-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多