How to configure a USB remote server with an STM32 MPU board

1 Article purpose[edit]

The purpose of this article is to explain how to configure a USB remote server with an STM32MP157x-DKx More info green.png board used as an example, managed by Linux® on the Arm® Cortex®-A7 processor.


The goal is to transform an STM32MP157x-DKx More info green.png board into a USB remote server, and then manage a USB device from a PC while the USB device is connected to a remote server on the network.

USB remote verser
USB remote server

USBIP kernel modules are used to configure an STM32MP157x-DKx More info green.png board as a USB remote server.

This article provides step-by-step instructions to:

  • explain how to transform a Linux® board into a USB remote server with USBIP kernel modules and server
  • configure Linux® software to enable the USBIP server (aka USB remote server)
  • configure a PC client to connect to the USBIP server.
  • further manage power for the USB device on the server using the uhubctl tool
Info.png This configuration can be replicated with other STM32 MPU boards provided the USBIP kernel modules are activated on their Linux® kernel.

2 Configure an STM32 MPU board with USBIP[edit]

2.1 Overview[edit]

As explained on the USB/IP Project webpage, the USB/IP Project aims to develop a general USB device sharing system over IP network. To share USB devices between computers with their full functionality, USB/IP encapsulates "USB I/O messages" into TCP/IP payloads and transmits them between computers. [1]

2.2 Step by step on server[edit]

The installation of a USBIP server is made on boards with embedded Linux®.
The following chapter shows how to configure manually the USBIP service on board and how to enable it on an STM32 MPU board on which all the configurations, files, and services are present.

2.2.1 Manual setup[edit]

Before using the usbip command, it is necessary to load the kernel modules associated to USBIP:

 Board $> modprobe usbip-core
 Board $> modprobe usbip-host

Start the USBIP server:

 Board $> usbipd -D

To make available a USB device connected to a board with embedded Linux®, it is necessary to bind the device.

List the available USB devices:

 Board $> usbip list -l
- busid 2-1.1 (03f0:e207)
  HP, Inc : unknown product (03f0:e207)

Bind this specific device to be visible by the PC client (here device 2-1.1):

 Board $> usbip bind -b 2-1.1

(To automate the binding of new USB devices, see the next section Automated setup.)

2.2.2 Automated setup (available by default on STM32 MPU boards)[edit]

All the configurations, files, services are present on STM32 MPU boards by default.

  • Automate server startup via systemd:

Create on board a service dedicated to start the USBIP server.
Content of /lib/systemd/system/usbip.service:

[Unit]
Description=USB-IP Bindind
After=network.target
Wants=network.target
 
[Service]
Type=forking
ExecStartPre=-/sbin/modprobe usbip-core
ExecStartPre=-/sbin/modprobe usbip-host
ExecStart=/usr/sbin/usbipd -D
ExecStop=/usr/sbin/stm32mp-usbip-bind-unbind.sh unload

[Install]
WantedBy=multi-user.target

Start systemd USBIP service:

 Board $> systemctl daemon-reload 
 Board $> systemctl start usbip
  • Automate the binding of new USB devices:

The binding of new USB devices can be made by a script, which binds or unbinds the usb devices depending if they are plugged or unplugged.
This script must be called by an udev rules for the case of device plug/unplug.

Content of script: /usr/sbin/stm32mp-usbip-bind-unbind.sh:

#!/bin/sh -
#echo "Parameter number $#" >> /tmp/usbip.log
action=$1
devpath=$2
#echo "Parameter: $1" >> /tmp/usbip.log
#echo "Parameter: $2" >> /tmp/usbip.log

case $1 in
unload)
    modprobe -r usbip-core
    modprobe -r usbip-host
    kill -9 `pgrep usbipd`
    exit 0
    ;;
esac

subpath=$(echo $2 | sed "s|.*/\([^/]*\)|\1|")
#echo "subpath  >$subpath<" >> /tmp/usbip.log
if $(echo $subpath | grep -q ":");
then
    #echo "No valid path" >> /tmp/usbip.log
    exit 0
fi

# if usbip-core are not loaded, do nothing
if [ -z "$(cat /proc/modules | grep usbip_core)"  ]; then
   #echo "no module usbip_core loaded" >> /tmp/usbip.log
   exit 0
fi

case $1 in
add)
    #echo ">>> bind $subpath" >> /tmp/usbip.log
    usbip bind -b $subpath
    ;;
remove)
    #echo "<<< unbind $subpath" >> /tmp/usbip.log
    usbip unbind -b $subpath
    ;;
esac

Content of udev rules: /etc/udev/rules.d/99-usb-usbip.rules:

ACTION=="remove", SUBSYSTEM=="usb", RUN+="/usr/sbin/stm32mp-usbip-bind-unbind.sh remove %p"

ACTION=="add", SUBSYSTEM=="usb", DRIVER=="usb", RUN+="/usr/sbin/stm32mp-usbip-bind-unbind.sh add %p"

2.3 Step by step on PC client[edit]

2.3.1 On Windows®[edit]

A USBIP client exists for Windows®. It is available via GitHub usbip-win.

2.3.1.1 Installation[edit]

Follow the instructions specified on README.md.

2.3.1.2 Usage[edit]

User action:

  • List the USB devices available on the specific server:
PC $> usbip.exe list -l -r <usbip server ip>
  • Attach a USB device available on the specific server (here 2-1):
PC $> usbip.exe list -r <usbip server ip> -b 2-1
  • List USB devices attached on the host PC:
PC $> usbip.exe port
  • Detach a specific attached USB device from the host PC:
List attached device on the host PC and detach it (here 00):
PC $> usbip detach -p 00

2.3.2 On Linux®[edit]

2.3.2.1 Installation[edit]

On Ubuntu®, it is necessary to install some pre-requisite package:

PC $> sudo apt-get install sysfsutils linux-tools-generic

For having a translation of USB device name and ID, install a specific hardware data base:

 PC $> wget http://www.linux-usb.org/usb.ids
 PC $> sudo mkdir -p /usr/share/hwdata/
 PC $> sudo cp usb.ids /usr/share/hwdata/
2.3.2.2 Usage[edit]

Before using the usbip command, load the kernel modules associated to USBIP:

PC $> sudo modprobe usbip-core
PC $> modprobe vhci-hcd
  • List USB remote devices available on the specific server:
PC $> sudo usbip list -r <server IP>
  • Attach a USB remote device available on the specific server:
PC $> sudo usbip attach -r <server IP> -b <USB ID>
  • Detach a specific attached USB device from the host PC:

List the attached USB devices:

PC $> sudo usbip port

Detach the specific USB device attached as 00:

PC $> sudo usbip detach -p 00

3 Configure the STM32 MPU board to add USB power management with uhubctl[edit]

3.1 Overview[edit]

uhubctl is the utility to control per-port USB power on smart USB hubs. A smart hub is defined as a hub that implements per-port power switching[2].

3.2 Usage[edit]

Board $> uhubctl 
Current status for hub 2-1 [0424:2514]
 Port 1: 0507 power highspeed suspend enable connect [03f0:e207 Hewlett Packard HP Webcam HD 2300]
 Port 2: 0100 power
 Port 3: 0100 power
 Port 4: 0100 power
Current status for hub 2 [1d6b:0002 Linux 5.9.0-rc4 ehci_hcd EHCI Host Controller 5800d000.usbh-ehci]
 Port 1: 0503 power highspeed enable connect [0424:2514]
 Port 2: 0100 power
Current status for hub 1 [1d6b:0002 Linux 5.9.0-rc4 dwc2_hsotg DWC OTG Controller 49000000.usb-otg]
 Port 1: 0000 off

On hub 2-1 Port 1, a USB webcam is plugged:

Board $> cat /sys/class/video4linux/video1/name 
HP Webcam HD 2300: HP Webcam HD

To power off the USB webcam connected on this port:

Board $> uhubctl -a off -p 1 -l 2-1
Current status for hub 2-1 [0424:2514]
 Port 1: 0507 power highspeed suspend enable connect [03f0:e207 Hewlett Packard HP Webcam HD 2300]
Sent power off request
New status for hub 2-1 [0424:2514]
 Port 1: 0000 off
Board $> uhubctl 
Current status for hub 2-1 [0424:2514]
 Port 1: 0503 power highspeed enable connect [03f0:e207]
 Port 2: 0100 power
 Port 3: 0100 power
 Port 4: 0100 power
Current status for hub 2 [1d6b:0002 Linux 5.9.0-rc4 ehci_hcd EHCI Host Controller 5800d000.usbh-ehci]
 Port 1: 0503 power highspeed enable connect [0424:2514]
 Port 2: 0100 power
Current status for hub 1 [1d6b:0002 Linux 5.9.0-rc4 dwc2_hsotg DWC OTG Controller 49000000.usb-otg]
 Port 1: 0000 off

To power on the USB webcam connected on this port:

Board $> uhubctl -a on -p 1 -l 2-1
Current status for hub 2-1 [0424:2514]
 Port 1: 0507 power highspeed suspend enable connect [03f0:e207 Hewlett Packard HP Webcam HD 2300]
Sent power on request
New status for hub 2-1 [0424:2514]
 Port 1: 0503 power highspeed enable connect [03f0:e207 Hewlett Packard HP Webcam HD 2300]
Board $> uhubctl
Current status for hub 2-1 [0424:2514]
 Port 1: 0507 power highspeed suspend enable connect [03f0:e207 Hewlett Packard HP Webcam HD 2300]
 Port 2: 0100 power
 Port 3: 0100 power
 Port 4: 0100 power
Current status for hub 2 [1d6b:0002 Linux 5.9.0-rc4 ehci_hcd EHCI Host Controller 5800d000.usbh-ehci]
 Port 1: 0503 power highspeed enable connect [0424:2514]
 Port 2: 0100 power
Current status for hub 1 [1d6b:0002 Linux 5.9.0-rc4 dwc2_hsotg DWC OTG Controller 49000000.usb-otg]
 Port 1: 0000 off

4 References[edit]

  1. USB/IP Project web page [1]
  2. uhubctl web page [2]