All Collections
Advanced Features
Use USB/IP to Attach Peripherals over the Internet
Use USB/IP to Attach Peripherals over the Internet

The USB/IP protocol allows you to share USB devices between your virtual machine and another device.

avhsupport avatar
Written by avhsupport
Updated over a week ago

Table of Contents

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 using your local Linux computer as the host to directly control the cursor on a virtual Raspberry Pi Desktop device over a VPN connection.

We will also show examples of using a virtual STM32U5 board as the 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.

  1. Install the required packages.

    sudo apt update && sudo apt install -y linux-tools-$(uname -r) hwdata ubuntu-restricted-extras

  2. 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 is 10.11.3.5.

    sudo openvpn --config ~/Downloads/AVH_config.ovpn

  3. Open a new Terminal window and load the USB/IP Host kernel module.

    sudo modprobe usbip_host

  4. Start the USB/IP daemon in the background.

    sudo usbipd &

  5. With the USB mouse dongle still disconnected, list the available peripherals.

    usbip list -l

  6. 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 bus 1-1.

  7. 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

  1. On your newly created Raspberry Pi 4 virtual board, log in with the credentials pi and raspberry.

  2. Install the USB/IP package.

    sudo apt update && sudo install usbip

  3. Load the Virtual Host Controller Interface kernel module.

    sudo modprobe vhci-hcd

  4. 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

  5. Attach to USB bus 1-1, which corresponds to our mouse.

    sudo usbip attach -r 10.11.3.5 -b 1-1

  6. 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.

  1. 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

  2. Detach port 00, which corresponds to our mouse. Look for a response showing detached.

    sudo usbip detach -p 00

  3. 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.

  1. Install the STM32CubeIDE tool. In our example, we will use the MacOS version.

  2. Create a new project by clicking New -> STM32 Project from the File menu.

  3. When the STM32 Project window appears, click on Example Selector.

  4. Choose the example name Ux_Device_HID and the board name B-U585I-IOT02A, click on the example you want to build, then click Next.

  5. Make note of your project name and path to your workspace then click Finish.

  6. When the Project Explorer opens, right-click on your project name and select Build Project.

  7. 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.

  8. 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 

  9. 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

  1. Create a new virtual STM32U5 board and manually upload the Ux_Device_HID.elf custom firmware you created.

  2. Make note of the Services IP address on the Connect tab. In our example, we will use the Services IP 10.11.1.5.

  3. 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.

  4. Log in as the root user with the username pi and password raspberry.

  5. Install the USB/IP package.

    sudo apt update && sudo apt install -y usbip

  6. Load the Virtual Host Controller Interface kernel module.

    sudo modprobe vhci-hcd

  7. List the STM32U5's exportable USB devices using the Services IP and port 6000.

    usbip --tcp-port 6000 list -r 10.11.1.5

  8. 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

  9. 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 port 00.

  10. 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 22.04. We will also use Ux_Device_HID_CDC_ACM.elf, the "Mini LED Display" firmware file we created in the earlier step.

  1. Create a new STM32U5 virtual device and manually upload the Ux_Device_HID_CDC_ACM.elf firmware you created in the STM32CubeIDE tool.

  2. Download the .ovpn file and make note of the Services IP address on the Connect tab. In our example, the Services IP is 10.11.1.1.

  3. On your Linux client machine, install the required packages.

    sudo apt update && sudo apt install -y linux-tools-$(uname -r) hwdata

  4. Connect to the AVH VPN using the .ovpn file you downloaded.

    sudo openvpn --config /Downloads/app.avh.arm.com\ VPN\ -\ Default\ Project.ovpn

  5. Open a second Terminal window. Double-check your VPN connection by pinging the Services IP for your USB/IP host.

  6. Load the Virtual Host Controller Interface kernel module.

    sudo modprobe vhci-hcd

  7. List the exportable STM32U5 USB devices.

    usbip --tcp-port 6000 list -r 10.11.1.1

  8. 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

  9. List the Imported USB devices to confirm the attach command was successful.

    usbip port

  10. 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 earlier step.

  1. Upload the Ux_Device_HID_CDC.elf firmware file and start the STM device. Make note of the device’s “Services IP”.

  2. 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.

    1. Boot up a virtual Raspberry Pi 4 board.

    2. Under the CONNECT tab, find to the Quick Connect SSH command

    3. Copy the part of the command showing your project's unique identifier <project identifier>@proxy.app.avh.arm.com.

  3. 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.

  4. ssh-keygen -t ed25519

  5. Add the public key (cat ~/.ssh/id_ed25519.pub) to your AVH project's authorized project keys under https://app.avh.arm.com/admin/projects.

  6. Install USB/IP and the hardware identification tool.

    sudo apt update && sudo apt install -y linux-tools-$(uname -r) hwdata

  7. Load the USB Virtual Host Controller Interface kernel module.

    sudo modprobe vhci-hcd

  8. 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.arm.com

  9. List USBIP devices on localhost port 6000.

    usbip --tcp-port 6000 list -r localhost

  10. You should see the virtual STMicroelectronics USB peripheral appear.

  11. When you are finished, close the socket.

    ssh -Ssock -O exit proxy.corellium.com


Did this answer your question?