如何将 FTDI USB 设备挂载到 docker 容器?

问题描述 投票:0回答:1

我希望能够从 Docker 容器内访问插入主机的 FTDI 串行到 USB 桥接设备。从那里,我使用带有 pyusb 和 libusb 库的 Python 脚本来处理 USB 输出。这样,我可以将 FTDI 板及其连接的设备插入某些计算机,运行 docker 容器并处理数据。该容器是使用 docker-compose 构建的。

我们是如何来到这里的

作为在我的主机上进行的早期测试,我编写了以下 Python 脚本,该脚本将在我的设计开始时运行:

import usb.core
import usb.util

# Find the USB device
device = usb.core.find(idVendor = 0x0403, idProduct = 0x601c)

# Check if the device was found. If not, raise an error. If the device was found, print out its info. 
if (device == None):
    raise ValueError('Device not found')
else:
    print(device)

这会按预期打印出板上的所有信息 - 制造商、接口、端点等。 (我可以使用

lsusb -D /dev/bus/usb/003/007
找到供应商和产品 ID,其中数字是
lsusb
给出的总线和设备编号)。

然后我进入 vscode 中的 docker 容器,安装这两个库,并运行相同的脚本。这次,我遇到了错误:

usb.core.NoBackendError: No backend available

我访问了 pyusb 常见问题解答:https://github.com/pyusb/pyusb/blob/master/docs/faq.rst 并确保我没有找到导致错误的常见原因之一。即使我使用

usb.backend.libusb1.get_backend(...)
手动指定后端库,错误仍然存在。

我意识到问题的根本原因是 docker 容器首先无法访问 FTDI USB 设备。有了一周的 Docker 经验,我认为我需要使用以下命令将主机上的 USB 设备挂载到容器中:

已经尝试过什么

在 docker-compose 文件中的服务中,我尝试使用以下命令指定设备的安装位置:

devices: - "/dev/serial/by-id/<link>:/dev/ttyUSB0" privileged: true
为了找到 ,我进入了 

/dev/serial/by-id/

 目录并使用了 
dmesg | grep tty
。每当我插入不同的 USB 设备 (Arduino) 时,它都会显示一个新条目,但当我插入 FTDI 板时,它不会显示任何新条目。因此,我怀疑我的 FTDI 板是 TTY 设备,大多数现有线程似乎都集中在该设备上。我不知道如何为 docker-compose 提供安装设备所需的内容。

因为如果给定多个 USB 设备,pyusb 库就会找到我的设备,因此只需安装所有主机 USB 端口也应该可以解决我的问题。我也搜索了这组关键词,但没有找到太多有用的信息。

TL:博士

如何将主机上的单个 FTDI 串行到 USB 桥接设备或所有 USB 设备安装到 Docker 容器?如果可能的话,我想避免使用

privileged

。我已经使用 Ubuntu、Docker 和 Python 工作了大约一周,所以我可能需要详细说明。如果需要更多信息,请告诉我。

谢谢!

docker docker-compose ftdi usbserial pyusb
1个回答
0
投票
你有没有弄清楚这一点?我刚刚进行了一个非常类似的练习,它对我很有用!我的主板是 FT232H(使用 Adafruit 的

breakout)。我基本上只是按照 Adafruit here 上的说明进行操作。

认为“无后端”错误是因为没有安装 libusb。不知道为什么,正如你所说,你安装了它......但这是我采取的步骤,据我认为它们是相关的:

    在我的 Dockerfile 中我安装了 libusb。我的基本图像是 Alpine,所以这是
  1. RUN apk update && apk add libusb
    。在完整的 Ubuntu 上,它将是 
    RUN apt update && apt install libusb-1.0
    ,如 Adafruit 指南中所示。
  2. 创建 udev 规则。我
  3. 完全理解这些的作用,但也许没有这些就是您的董事会没有出现在dev/serial/by-id
    中的原因?在 
    host 上,创建包含以下内容的文件 /etc/udev/rules.d/11-ftdi.rules
# /etc/udev/rules.d/11-ftdi.rules SUBSYSTEM=="usb", ATTR{idVendor}=="0403", ATTR{idProduct}=="6001", GROUP="plugdev", MODE="0666" SUBSYSTEM=="usb", ATTR{idVendor}=="0403", ATTR{idProduct}=="6011", GROUP="plugdev", MODE="0666" SUBSYSTEM=="usb", ATTR{idVendor}=="0403", ATTR{idProduct}=="6010", GROUP="plugdev", MODE="0666" SUBSYSTEM=="usb", ATTR{idVendor}=="0403", ATTR{idProduct}=="6014", GROUP="plugdev", MODE="0666" SUBSYSTEM=="usb", ATTR{idVendor}=="0403", ATTR{idProduct}=="6015", GROUP="plugdev", MODE="0666"

    现在,当我拔下并重新插入设备时,我会在
  1. /dev/serial/by-usb
     中获得一个新条目,我可以按照您的预期将其添加到撰写文件中。我的文件中的这些行是:
devices: - "/dev/serial/by-id/usb-0403_6014-if00-port0:/dev/ftdi"
现在容器中的 pyusb 可以看到该设备(对我来说)。

编辑

当 pyusb 在容器中由 root 运行时,上述内容对我有用。我最近改用容器中的非管理员帐户,并且必须再执行两个步骤:

    与容器共享上述规则文件。在撰写文件中:
volumes: - /etc/udev/rules.d/11-ftdi.rules:/etc/udev/rules.d/11-ftdi.rules:ro

    创建规则文件中提到的组,并将容器用户添加到该组中。在 dockerfile 中:
RUN groupadd plugdev && usermod -a -G plugdev abc
您还可以查看上面链接的 Adafruit 指南的其余部分。它使用了更多的 Python 库(pyftdi 和 adafruit-blinka),这正是我用一行 Python 控制 GPIO 引脚所需要的。但你的用例可能比我的复杂得多!

© www.soinside.com 2019 - 2024. All rights reserved.