Reputation: 161
I am using Win10 and Linux Ubuntu on WSL 2.0.
For testing purposes of some programs, I would like to use the serial port of my PC in "loopback" with Linux running through WSL.
Basically I would like a process on Linux/WSL to be able to send/receive data from a Windows process or vice versa, through serial port, but without any hardware hack.
Of course I have already tried to set the Windows process serial as "COM1" (as indicated by the Windows resource manager) and the Linux port on WSL as "/dev/ttyS1", but apparently it doesn't work.
Is there any way to do this?
Upvotes: 11
Views: 37752
Reputation: 500
I run recently into the same problem with WSL2, and I discovered that it is possible, but with some tinkering.
# install build dependencies
sudo apt install build-essential flex bison libssl-dev libelf-dev libncurses-dev autoconf libudev-dev libtool
# check your current kernel version
uname -r
# clone the Microsoft's Linux kernel repo
git clone https://github.com/microsoft/WSL2-Linux-Kernel.git
cd WSL2-Linux-Kernel
# chechout YOUR closest version
git checkout linux-msft-wsl-5.15.153.1 # or the right one
# extract your current kernel configuration (different distros may have this in different locations)
cp /proc/config.gz config.gz
gunzip config.gz
mv config .config
Here in .config
you can then tweak some config file configurations, such as setting CONFIG_USB=y
. Then do
sudo make menuconfig
and turn the other things you need. For instance, in my case I needed to use a PL2303-based device, so I made sure to enable
# Device Drivers -> USB Support
# Device Drivers -> USB Support -> USB announce new devices
# Device Drivers -> USB Support -> USB Modem (CDC ACM) support
# Device Drivers -> USB Support -> USB/IP
# Device Drivers -> USB Support -> USB/IP -> VHCI HCD
# NO MORE Device Drivers -> USB Support -> USB/IP -> Debug messages for USB/IP
# Device Drivers -> USB Serial Converter Support
# Device Drivers -> USB Serial Converter Support -> USB FTDI Single port Serial Driver
(note Debug messages
is no longer required, so I disabled it). Now you're ready to compile:
sudo make -j 8
# copy the new kernel in a location you like on the Windows disk
cp arch/x86/boot/bzImage /mnt/c/Users/<user>/usb-bzImage
You then need to tell Windows to use the new kernel instead of the normal one. Open the file C:\Users\<your-user>\.wslconfig
(create it if it doesn't exist), and write in there
[wsl2]
kernel=C:\\Users\\<your-user>\\usb-bzImage
Yes, the double backslashes are required, and yes, lines need to start at the first char of the line. Now, from the Windows terminal, turn down all the WSL2 distros active (save your work first), then reopen them:
wsl --shutdown
wsl
If everything is correct, your distro should fire up as usual, but this time you can connect serial USB devices with usbipd-win. In a Windows terminal
usbipd list # see which USB bus the device is attached to
usbipd bind --busid <n1>-<n2> # for this you'll need admin privileges
usbipd attach --wsl --busid <n1>-<n2>
The second step requires an admin terminal, but you'll need to do that only once for every device. Now, in the WSL2 dmesg
, you should see the USB device correctly recognized and directed, generally to /dev/ttyUSB0
or similar
Upvotes: 1
Reputation: 2647
Following these steps (reproduced below), I was able to get access to the COM ports from WSL 2 on Windows 11. I plugged in 2 USB-Serial cables as shown, and I was able to use one COM port from Linux (with the code I was writing) and the other from Windows (with Termite).
usbipd list
.4-4
) and use usbipd bind --busid <id>
to share it with WSL.usbipd attach --wsl --busid <id>
to attach the USB port to WSL.lsusb
to see the device.Upvotes: 13
Reputation: 4360
Status update
According to other answers, it seems that the addition of product functions has made it possible to use USB devices with WSL2.
Especially in v5.10.93.2, it seems that drivers for two types of USB serial interface chips are built in.
- Enable CH341 and CP210X USB Serial drivers
- Enable USB over IP support
- Enable USB kernel configuration options for interacting with an Arduino over USB
The following is outdated information.
WSL 2.0 does not support serial ports.
Exceptions for using WSL 1 rather than WSL 2
- WSL 2 does not include support for accessing serial ports. Learn more in the FAQs or in WSL GitHub repo issue on serial support.
The following options are possible.
Revert to WSL 1.0 and use
Use third-party products
Also, if you want to communicate between serial ports even if WSL2 cannot recognize USB serial, this method is also available.
Connecting to serial port (com port) over network
And as you can see from the above explanation, if you want to communicate between the processes of each OS, you can simply use a TCP/IP socket instead of the above mechanism.
Upvotes: 6
Reputation:
Run this in PowerShell or CMD to see if you use Version 1:
C:\>wsl -l -v
NAME STATE VERSION
* Ubuntu Running 1
If yes, here's some tested working code to read COM14 from linux command prompt:
#!perl -w
use strict;
$|=1; # autoflush
use Device::SerialPort;
my $port = Device::SerialPort->new("/dev/ttyS14");
$port->baudrate(115200); # Configure below to match your device
$port->databits(8);
$port->parity("none");
$port->stopbits(0);
$port->debug(1);
$port->read_char_time(0); # don't wait for each character
$port->read_const_time(1); # 0.001 second per unfulfilled "read" call
while (1) {
my ($count_in, $str_in) = $port->read(255); # Supposedly must be 255 always
if($count_in) {
print $str_in;
}
}
If you are running WSL2, you can backup, convert or copy your distribution to WSL1 via wsl --export
, wsl --import
, and wsl --set-version
. See this question among others for details.
Upvotes: 0