WSL Setup - tomyummmm/Gen2-UHF-RFID-Reader GitHub Wiki

The following has been tested on Windows 10 Version 21H1, WSl 2 Ubuntu 20.04 LTS, and updated to usbipd-win 2.3.0. Previous wiki guide was based on usbipd-win 1.3.0.

Following installation instructions on Windows and Linux copied and modified from:

  1. usbipd-win to install usbipd on windows.
  2. usbipd-win WSL wiki to install in WSL under WSL setup. Building kernel is not required, and we will deal with udev rules in next section, skip over.

How to install usbipd on Windows

This software requires Microsoft Windows 8.1 x64 / Microsoft Windows Server 2012 or newer; it does not depend on any other software.

Run the installer (.msi) from the latest release on the Windows machine where your USB device is connected.

Alternatively, use the Windows Package Manager:

winget install --interactive --exact dorssel.usbipd-win

If you leave out --interactive, winget may immediately restart your computer if that is required to install the drivers.

This will install:

  • A service called usbipd (display name: USBIP Device Host).
    You can check the status of this service using the Services app from Windows.
  • A command line tool usbipd.
    The location of this tool will be added to the PATH environment variable.
  • A firewall rule called usbipd to allow all local subnets to connect to the service.
    You can modify this firewall rule to fine tune access control.
    ℹ️
    If you are using a third-party firewall, you may have to reconfigure it to allow incoming connections on TCP port 3240.

How to install usbipd on Linux

WSL version

Running uname -a from within WSL should report a kernel version of 5.10.60.1 or later. You’ll need to be running a WSL 2 distro.

USB/IP client tools

From within WSL, install the user space tools for USB/IP and a database of USB hardware identifiers. On Ubuntu 20.04 LTS, run these commands:

sudo apt install linux-tools-virtual hwdata
sudo update-alternatives --install /usr/local/bin/usbip usbip /usr/lib/linux-tools/*/usbip 20

⚠️ These instructions have changed.
Updating to usbipd-win version 2.0.0 or higher will require these new instructions, even if the old instructions were followed before.

ℹ️ Other distributions.
For other distributions a different usbip client package may be required. In any case, make sure that the resulting usbip command is in the PATH for user root; for example by adjusting the above update-alternatives. Please search the (possibly closed) issues to see if instructions for your distribution are already known.

Read WSL Convenience Commands for information on how to use usbipd.

Important Note

WSL 2 does not include systemd, hence it is unable to execute udev rules on startup and provide permissions that persist across sessions. Read next section for workaround.

Note that depending on your application, you may need to configure udev rules to allow non-root users to access the device. Rules to enable a device must be in place before connecting the device. As a common example for using embedded devices with openocd copy share/openocd/contrib60-openocd.rules to the /etc/udev/rules.d folder.

Udev rules

Depending on the packages installed, it might already include udev rules within the /etc/udev/rules.d folder.

/etc/udev/rules.d                                                                                       01:34:58 PM❯ ls
10-usrp.rules     52-airspy.rules  64-limesuite.rules   88-nuand-bladerf1.rules  88-nuand-bootloader.rules
15-rtl-sdr.rules  53-hackrf.rules  70-snap.snapd.rules  88-nuand-bladerf2.rules  rtl-sdr.rules

LimeSDR is used in our project, hence we can look at 64-limesuite.rules

❯ cat 64-limesuite.rules
SUBSYSTEM=="usb", ATTR{idVendor}=="04b4", ATTR{idProduct}=="8613", SYMLINK+="stream-%k", MODE="666"
SUBSYSTEM=="usb", ATTR{idVendor}=="04b4", ATTR{idProduct}=="00f1", SYMLINK+="stream-%k", MODE="666"
SUBSYSTEM=="usb", ATTR{idVendor}=="0403", ATTR{idProduct}=="601f", SYMLINK+="stream-%k", MODE="666"
SUBSYSTEM=="usb", ATTR{idVendor}=="1d50", ATTR{idProduct}=="6108", SYMLINK+="stream-%k", MODE="666"
SUBSYSTEM=="xillybus", MODE="666", OPTIONS="last_rule"

SUBSYSTEM=="tty", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6001", MODE="0666", SYMLINK+="serial"

From the above, LimeSDR is identified by its Vendor and Product id of 1d50:6108, where we are granting read and write access "666".

You can create your own Udev rule file with reference to the above for your own device.

Launching on every startup

Add the following instructions to ~/.bashrc or relevant shell equivalent like ~/.zshrc. This will cause the Udev rules to be reloaded every time the WSL terminal is started.

# Auto reload udev for USB passthrough to work
wsl.exe -u root service udev restart || wsl.exe -u root udevadm control --reload

Reload .bashrc

source ~/.bashrc

The above replaces the need to type the following every time you login to WSL:

sudo service udev restart
sudo udevadm control --reload

Checking connection in Linux

You can check if the device successfully pass through with lsusb

~$ lsusb
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 002: ID 1d50:6108 OpenMoko, Inc. Myriad-RF LimeSDR
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

If udev rules were not correctly applied, the permissions would show up as non read and writable, replace 001/002 with the respective bus and device id from lsusb:

~$ ls -l /dev/bus/usb/001/002
crw------- 1 root root 189, 1 Dec 13 14:21 /dev/bus/usb/001/002

Correctly applied according to the udev rules of mode 666:

~$ ls -l /dev/bus/usb/001/002
crw-rw-rw- 1 root root 189, 1 Dec 13 14:14 /dev/bus/usb/001/002

Checking UHD

Incorrectly applied udev:

~$ uhd_find_devices
[INFO] [UHD] linux; GNU C++ version 9.3.0; Boost_107100; UHD_3.15.0.0-74-ge35f66e8
libusb: error [_get_usbfs_fd] libusb couldn't open USB device /dev/bus/usb/001/002: Permission denied
libusb: error [_get_usbfs_fd] libusb requires write access to USB device nodes.
No UHD Devices Found

Correctly applied udev:

~$ uhd_find_devices
[INFO] [UHD] linux; GNU C++ version 9.3.0; Boost_107100; UHD_3.15.0.0-74-ge35f66e8
--------------------------------------------------
-- UHD Device 0
--------------------------------------------------
Device Address:
    serial: 0009072Cxxxxxxxx
    addr: 1d50:6108
    driver: lime
    label: LimeSDR-USB [USB 2.0] 9072Cxxxxxxxx
    media: USB 2.0
    module: FX3
    name: LimeSDR-USB
    type: soapy

Checking SoapySDRUtil

Incorrectly applied udev:

~$ SoapySDRUtil --probe
######################################################
##     Soapy SDR -- the SDR abstraction library     ##
######################################################

Probe device
[INFO] [UHD] linux; GNU C++ version 9.3.0; Boost_107100; UHD_3.15.0.0-74-ge35f66e8
libusb: error [_get_usbfs_fd] libusb couldn't open USB device /dev/bus/usb/001/002: Permission denied
libusb: error [_get_usbfs_fd] libusb requires write access to USB device nodes.
Error probing device: SoapySDR::Device::make() no driver specified and no enumeration results

Correctly applied udev:

~$ SoapySDRUtil --probe
######################################################
##     Soapy SDR -- the SDR abstraction library     ##
######################################################

Probe device
[INFO] Make connection: 'LimeSDR-USB [USB3.0] 9072Cxxxxxxxx'
[INFO] Reference clock 30.72 MHz
[INFO] Device name: LimeSDR-USB
[INFO] Reference: 30.72 MHz
[INFO] LMS70002M register cache: Disabled

---------------------------------------------------
-- Device identification
---------------------------------------------------
  driver=FX3
  hardware=LimeSDR-USB
  boardSerialNumber=0x9072Cxxxxxxxx
  firmwareVersion=4
  gatewareVersion=2.23
  hardwareVersion=4
  protocolVersion=1

Automating usbipd attachment and launching windows terminal

Instead of having to open Windows Terminal, ensuring WSL is open and running, then typing in usbipd wsl list and usbipd wsl attach --busid 1-X everytime, we can automate this using a batch script in command prompt.

usbipd version >2.0.0 attach and detach commands requires administrator rights on the first run.

usbipd: error: Access denied; this operation requires administrator privileges.
usbipd: info: The first time attaching a device to WSL requires elevated privileges; 
subsequent attaches will succeed with standard user privileges.

The following code is in WSL_Launcher.bat. Right click and Run as administrator for the first time attaching a device, following that just double click will work.

FOR /F "tokens=1" %%i IN ('usbipd wsl list ^| findstr /c:"LimeSDR-USB"') DO SET VARIABLE=%%i

wt -p "Ubuntu-20.04" ; new-tab -p "Command Prompt" cmd /k "usbipd wsl list & usbipd wsl attach --busid %VARIABLE%"

Why is it in batch script and command prompt?

Because that is what I (Mervin) am familiar with, and batch script can be run without dealing with permission issues. Feel free to write this in Powershell scripting and figure out how to deal with Powershell script execution permissions on every Windows version, create a Pull Request and tell me.

How do I modify this script?

You can change the name of the device from LimeSDR-USB to your device as listed within usbipd wsl list.

The first line executes the commands within the parenthesis ( ), where usbipd wsl list is piped into findstr function (cmd equivalent of GREP in Linux). The findstr matches for the "STRING", and outputs only the line containing the STRING.

1-10   LimeSDR-USB                                                    Not attached

It then executes a FOR loop, taking the first TOKEN (substring before a space/tab) from the output of findstr, and sets VARIABLE=1-10.

The second line opens Windows Terminal as administrator since this batch script is run as administrator, first opening the WSL Linux profile with -p flag, followed by the name of the distro. It then opens a new tab with profile of command prompt, keeping the command prompt open with /k, and passes in 2 commands, listing all usbipd devices for wsl and their status (all should be not attached), and attaching the busid stored in VARIABLE.

See Windows Terminal Command Line Arguments for more info on flags and arguments.

Demo from usbipd 2.3.0

Lower resolution GIF in wiki, for high resolution video click here

WSL_USB_passthrough_demo_new

Demo from usbipd 1.3.0

Lower resolution GIF in wiki, for high resolution video click here

WSL_USB_passthrough_demo

WSL Port Forwarding for Remote PC to GUI

If running reader_2.py and GUI on same machine, WSL automatically passes through localhost (127.0.0.1). No action required.

If running reader_2.py on a remote PC and GUI on another PC on the same LAN, WSL requires port forwarding in order to receive data from remote PC. Run WSL_Port_Forwarding.ps1 by right clicking, Run with PowerShell. The script may need to be run twice if it doesnt successfully set up on first run. The script can be modified to add ports that you use. The script adds Firewall rules and forwards the ports required by GUI (port 5556).

#[Ports]

#All the ports you want to forward separated by coma
$ports=@(5556);

This can be checked by running the following in powershell, where the port should show up as forwarded.

netsh interface portproxy show all
Listen on ipv4:             Connect to ipv4:

Address         Port        Address         Port
--------------- ----------  --------------- ----------
0.0.0.0         5556        172.20.103.90   5556

However, this results in the port being binded and unusable for any other program on Windows until the port forwarding is removed. Hence, run WSL_Port_Forwarding - Remove.ps1 by right clicking, Run with PowerShell. Check with the command above and it should show no ports being forwarded. Firewall rules are also removed.

⚠️ **GitHub.com Fallback** ⚠️