Connect USB devices via USB/IP
The USB/IP protocol allows you to share USB devices between your virtual machine and another device.
USB/IP is an open-source tool for encapsulating USB I/O messages into TCP/IP messages. The host device shares a USB peripheral that the client device can use as if it were directly attached to the client. Read more about the protocol on the USB/IP SourceForge page.
In this article, we will show an example of how to Use Your Local Linux Computer as the USB/IP Host to directly control the cursor on a virtual Raspberry Pi Desktop device over a VPN connection.
We will also show examples of how to Use a Virtual STM32U5 Board as the USB/IP Host to share both input and output USB peripherals.
Use Your Local Linux Computer as the USB/IP Host
We will be using a physical computer with a fresh install of Ubuntu Desktop 22.04 LTS and a Raspberry Pi 4 running the Desktop version of firmware 11.2.0.
Start with the USB peripheral disconnected from your device.
:::Note The USB device we use will stop working on your host, so make sure to have a second mouse (or laptop trackpad) to control your computer. :::
Set Up the USB/IP Daemon on Your Computer
Start with a fresh install of the most recent LTS version of Ubuntu Desktop as the host and a virtual Raspberry Pi 4 Desktop board as the client.
Install the required packages.
sudo apt update && sudo apt install -y linux-tools-$(uname -r) hwdata ubuntu-restricted-extras
Download the
.ovpn
file from the Raspberry Pi 4's Connect tab and connect to your AVH project using openvpn. Make note of the VPN's IP address, which in our example is10.11.3.5
.sudo openvpn --config ~/Downloads/AVH_config.ovpn
Open a new Terminal window and load the USB/IP Host kernel module.
sudo modprobe usbip_host
Start the USB/IP daemon in the background.
sudo usbipd &
With the USB mouse dongle still disconnected, list the available peripherals.
usbip list -l
Connect the physical USB mouse dongle to your computer and run the
list
command again. You should see a new device on a new bus number. In our example, we have a new device on bus1-1
.Bind the appropriate USB bus,
1-1
in our case. (This will cause the device to stop functioning on your host computer, so make sure to have a backup in the case of a mouse.)sudo usbip bind -b 1-1
Attach a Physical Device to the Virtual Board Client
To attach a physical device to the virtual board client:
On your newly created Raspberry Pi 4 virtual board, log in with the credentials
pi
andraspberry
.Install the USB/IP package.
sudo apt update && sudo install usbip
Load the Virtual Host Controller Interface kernel module.
sudo modprobe vhci-hcd
Using the VPN IP address from openvpn, list the exportable USB devices on the host. Look for the same bus number from the previous section.
usbip list -r 10.11.3.5
Attach to USB bus
1-1
, which corresponds to our mouse.sudo usbip attach -r 10.11.3.5 -b 1-1
You should now be able to control the cursor on the Raspberry Pi 4 Desktop.
(Optionally) Close the Connection When Finished
When you are finished, you can optionally close the connection by detaching on the client and unbinding the host's USB bus.
This process is necessary if you want to access the USB resource again on your host device.
On the USB/IP client, which in our case is the virtual Raspberry Pi 4 Desktop board, list the imported USB devices. Look for the appropriate port number.
usbip port
Detach port
00
, which corresponds to our mouse. Look for a response showingdetached
.sudo usbip detach -p 00
Switch over to your USB/IP host, which in our case is the Ubuntu machine, and unbind the appropriate USB bus. Look for a response showing
complete.
usbip unbind -b 1-1
Use a Virtual STM32U5 Board as the USB/IP Host
We will be using firmware files that are offered as examples in STMicroelectronics's STM32CubeIDE tool.
You will need to build the Ux_Device_HID.elf
and Ux_Device_HID_CDC_ACM.elf
firmware files.
Build USB Firmware Files with the STM32CubeIDE Tool
Follow this process to build the required .elf
custom firmware files using free tools from STMicroelectronics.
Install the STM32CubeIDE tool. In our example, we will use the MacOS version.
Create a new project by clicking New -> STM32 Project from the File menu.
When the STM32 Project window appears, click on Example Selector.
Choose the example name
Ux_Device_HID
and the board nameB-U585I-IOT02A
, click on the example you want to build, then click Next.Make note of your project name and path to your workspace then click Finish.
When the Project Explorer opens, right-click on your project name and select Build Project.
While the project is building, you should see a progress message towards the bottom right. Open the Console if you prefer to follow the progress.
The
.elf
firmware file will be created inside your project directory, which is inside/<path_to_workspace>/<project_name>/STM32CubeIDE/Debug
.ls ~/STM32CubeIDE/workspace_1.10.0/Ux_Device_DFU/STM32CubeIDE/Debug/*.elf
The firmware file is ready to be uploaded to your AVH virtual STM32U5 board.
Attach a Virtual USB Peripheral to a Virtual Raspberry Pi 4 Board
To attach a virtual joystick to the Raspberry Pi 4:
Create a new virtual STM32U5 board and manually upload the
Ux_Device_HID.elf
custom firmware you created.Make note of the Services IP address on the Connect tab. In our example, we will use the Services IP
10.11.1.5
.Create a new Raspberry Pi 4 virtual device using any version of the firmware. In our example, we will use the lite version of firmware
11.2.0
.Log in as the root user with the username
pi
and passwordraspberry
.Install the USB/IP package.
sudo apt update && sudo apt install -y usbip
Load the Virtual Host Controller Interface kernel module.
sudo modprobe vhci-hcd
List the STM32U5's exportable USB devices using the Services IP and port 6000.
usbip --tcp-port 6000 list -r 10.11.1.5
Attach to USB bus 0-1, which corresponds to the joystick peripheral. (Don't forget to
sudo
or the command will fail.)sudo usbip --tcp-port 6000 attach -r 10.11.3.3 -b 1-2
The STM32U5's virtual joystick is now attached to your Raspberry Pi 4 virtual board. Confirm the device is attached using
usbip port
. Make note that the device is using port00
.When you are finished, detach the peripheral from port
00
.sudo usbip detach -p 00
Attach a Virtual USB Peripheral to a Physical Computer Using a VPN Connection
In this example, we will use a laptop running Ubuntu 20.04. We will also use Ux_Device_HID_CDC_ACM.elf, the "Mini LED Display" firmware file we created in the Build USB Firmware Files with the STM32CubeIDE Tool step.
Create a new STM32U5 virtual device and manually upload the
Ux_Device_HID_CDC_ACM.elf
firmware you created in the STM32CubeIDE tool.Download the
.ovpn
file and make note of the Services IP address on the Connect tab. In our example, the Services IP is10.11.1.1
.On your Linux client machine, install the required packages.
sudo apt update && sudo apt install -y linux-tools-$(uname -r) hwdata
Connect to the AVH VPN using the
.ovpn
file you downloaded.sudo openvpn --config /Downloads/app.avh.corellium.com\ VPN\ -\ Default\ Project.ovpn
Open a second Terminal window. Double-check your VPN connection by pinging the Services IP for your USB/IP host.
Load the Virtual Host Controller Interface kernel module.
sudo modprobe vhci-hcd
List the exportable STM32U5 USB devices.
usbip --tcp-port 6000 list -r 10.11.1.1
Attach to USB bus 0-1, which corresponds to the LED display.
sudo usbip --tcp-port 6000 attach -r 10.11.1.1 -b 0-1
List the Imported USB devices to confirm the attach command was successful.
usbip port
When you are finished, detach from port
00
.sudo usbip detach -p 00
Attach a Virtual USB Peripheral to a Physical Computer Using SSH Port Forwarding
In this example, we will use a laptop running Ubuntu 22.04. We will also use Ux_Device_HID_CDC.elf
, the "Joystick in FS Mode" firmware file we created in the Build USB Firmware Files with the STM32CubeIDE Tool step.
Upload the
Ux_Device_HID_CDC.elf
firmware file and start the STM device. Make note of the device's "Services IP".Next, we will find your project's unique identifier. The first option is to use the Get Projects API command. Alternatively, you can do the following.
Boot up a virtual Raspberry Pi 4 board.
Under the Connect tab, find to the Quick Connect SSH command
Copy the part of the command showing your project's unique identifier
<project identifier>@proxy.app.avh.corellium.com
.
On your Ubuntu computer, generate a public/private key pair using the Ed25519 signature scheme. In our example, we will use the default file path with no passphrase.
ssh-keygen -t ed25519
Add the public key (
cat ~/.ssh/id_ed25519.pub
) to your AVH project's authorized project keys under https://app.avh.corellium.com/admin/projects.Install USB/IP and the hardware identification tool.
sudo apt update && sudo apt install -y linux-tools-$(uname -r) hwdata
Load the USB Virtual Host Controller Interface kernel module.
sudo modprobe vhci-hcd
Use ssh to forward local port 6000 to port 6000 of your device's services IP.
ssh -M -Ssock -N -f -L 6000:<STM_device_services_IP>:6000 <your_project_id>@proxy.app.avh.corellium.com
List USBIP devices on localhost port 6000.
usbip --tcp-port 6000 list -r localhost
You should see the virtual STMicroelectronics USB peripheral appear.
When you are finished, close the socket.
ssh -Ssock -O exit proxy.corellium.com