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:
- usbipd-win to install usbipd on windows.
- 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.
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 thePATH
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.
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.
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
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.
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.
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.
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
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
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
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
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%"
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.
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.
Lower resolution GIF in wiki, for high resolution video click here
Lower resolution GIF in wiki, for high resolution video click here
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.