分类
折腾 笔记

用树莓派网络共享 USB 设备

本文讲述如何配置树莓派(或其他 Linux 机器),使其在检测到指定 USB 设备插入后,通过网络共享该 USB 设备。

应用场景实例

可以解决以下场景之需求:

  • 多个人需要调试开发板,但是串口线只有一个,来回插拔串口线麻烦;
  • 搭建调试农场,待调试设备统一托管与连接,开发者无需移动调试设备,只需通过网络将远程 USB 设备附加到本地机器,远程 USB 设备就如插在本机一样,进行调试;
  • 希望远程使用 USB 设备。

我们会用到的软件

  • usbip(需安装)
    一个 Linux 内核模组,可以将裸 USB 协议通过网络转发。客户端通过 usbip,将远端 USB 设备附加在本地后,即相当于客户端的 USB 接口上物理连接了远端 USB 设备。随后即可以像使用本地 USB 设备一样,使用远端的 USB 设备。
  • udev(已内建于 Linux)
    Linux 中,事件驱动的设备管理器。如果需要监听设备的某一事件,然后执行某些动作,那么只需要一个 udev 规则即可实现。

以网络分享 USB 转串口设备为例,当树莓派(usbip 服务器端)与客户端都采用网线连接交换机的情况下,在客户端上使用远程 USB 串口设备,感受不到任何延迟,如同 USB 转串口设备直接连接本机一样。

我的树莓派配置

树莓派会被用来做 usbip 的服务器端,要共享的 USB 设备需要连接树莓派。

  • Raspberry Pi 3B
  • Ubuntu 20.04 LTS Server(64-bit)

3B 的 USB 2.0 ,以及百兆以太网,对于转发 USB 串口已经足够。选用 Ubuntu 20.04 LTS Server 原因是因为其是一个受官方支持、社区资源丰富,没有 GUI,且稳定的服务器系统。这样的一个操作系统可以大大地排除不同 Linux 发行版本身带来的其他干扰因素,降低时间成本。

开始配置

安装 usbip

树莓派:
$ sudo apt install linux-tools-raspi

对于 PC 机器:
$ sudo apt install linux-tools-common

完成后,执行一下 usbip 命令,会有类似的输出:

catboy@pi:~$ usbip
 WARNING: usbip not found for kernel 5.4.0-31
 You may need to install the following packages for this specific kernel:
     linux-tools-5.4.0-31-generic
     linux-cloud-tools-5.4.0-31-generic
 You may also want to install one of the following packages to keep up to date:
     linux-tools-generic
     linux-cloud-tools-generic
 apt install linux-tools-generic

提示没有安装相应内核版本的 linux-tools 软件包,那么接下来,安装它即可:

$ sudo apt install linux-tools-5.4.0-31-generic

开机自动加载 usbip 模组:

$ sudo echo "usbip_host" >> /etc/modules

接下来,我们需要创建一个服务,让 usbip 服务器端开机启动:

$ sudo vi /lib/systemd/system/usbipd.service

输入以下内容:

[Unit]
Description=usbip server
After=network.target

[Service]
Type=forking
ExecStart=/usr/bin/usbipd -D
ExecStop=/bin/sh -c "killall usbipd"

[Install]
WantedBy=multi-user.target

启用并启动 usbip 服务:

$ sudo systemctl enable usbipd.service
$ sudo systemctl start usbipd.service

安装设备信息库

$ sudo apt insall hwdata

如果不安装这个软件包,那么列出 USB 设备的时候,就不能看到制造商和设备的名字,而是看见 “unknown”。

配置 udev

配置 udev 前,我们需要知道要分享的 USB 设备的“制造商 ID”和“产品 ID”:

$ lsusb
...
Bus 006 Device 002: ID 10c4:ea60 Silicon Labs CP210x UART Bridge
...

10c4:ea60 即是我们需要的。10c4 是制造商 ID,ea60 是设备 ID。

/etc/udev/rules.d/ 下建立一个 udev 规则,使得插入时,执行脚本 /etc/usbip/usb-serial-cp2102.sh

$ sudo vi /etc/udev/rules.d/10-usb-serial-cp2102.rules

输入以下内容:

SUBSYSTEM=="usb", ATTR{idVendor}=="10c4", ATTR{idProduct}=="ea60", RUN+="/etc/usbip/usb-serial-cp2102.sh"

接下来,创建 /etc/usbip/usb-serial-cp2102.sh

$ sudo mkdir /etc/usbip
$ sudo touch /etc/usbip/usb-serial-cp2102.sh
$ sudo chmod +x /etc/usbip/usb-serial-cp2102.sh
$ sudo vi /etc/usbip/usb-serial-cp2102.sh

输入以下内容:

#!/usr/bin/env bash

/usr/bin/usbip bind --$(/usr/bin/usbip list -p -l | grep '#usbid=10c4:ea60#' | cut '-d#' -f1)

最后,刷新 udev 即可:

$ sudo udevadm control --reload-rules && sudo udevadm trigger

现在插入这个 USB 设备,它就会被通过网络共享。有关如何在客户端附加 usbip 共享的 USB 设备,请参阅 usbipman page

发表评论

邮箱地址不会被公开。 必填项已用*标注