Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

COM port hang in WSL #3099

Closed
ChuckM opened this issue Apr 13, 2018 · 7 comments
Closed

COM port hang in WSL #3099

ChuckM opened this issue Apr 13, 2018 · 7 comments
Labels

Comments

@ChuckM
Copy link

ChuckM commented Apr 13, 2018

I have as system debugging module called a Black Magic Probe (info is here: https://github.com/blacksphere/blackmagic) This system runs a GDB server on the embedded processor and presents itself to the host computer as two serial ports over USB. One is the GDB server, and one is a local UART that you can connect to the system under test.

Typically in gdb you would connect to the target using the command
target extended-remote /dev/ttyACM0
That is how it would work on say Ubuntu. On WSL I use target extended-remote /dev/ttySx where x is replaced with the COM port number for the gdb server port.

After freshly plugging in the BMP, this gdb command hangs, hard. The only way to recover is to unplug the BMP so that the serial device errors out.

It also fails if I am using the Windows native version of the arm embedded tools from ARM. With a freshly plugged in device.

However, if I run Putty and open the serial device, it show the $OK that indicates the GDB server is waiting. And now if I go back to WSL and try it, it works fine. And will continue to work until the next time I unplug and re-plug in the USB device.

You can read the ACM implementation in the BMP code repo above. It is pretty vanilla. I'm trying to figure out what is different after Putty has talked with it. The only difference in the stty -a -F /dev/ttySx output is that before Putty the speed is 0 and after Putty the speed is 9600. I tried manually setting the speed using stty on a freshly plugged in device and it still didn't work. Needed to open it up with Putty first.

Any thoughts on how I might go about debugging this further?

@therealkenc
Copy link
Collaborator

And will continue to work until the next time I unplug and re-plug in the USB device.

Fair enough post if the port is still alive on the "Windows side" but dies on WSL. Might be a good catch.

Any thoughts

don't unplug it 😉

@mkarpoff
Copy link

I've noticed a similar problem when I was working with an Arduino. I could only upload to the device if I had uploaded from the IDE first. I thought it was a bug with Arduino but The symptoms were the exact same.

@Brian-Perkins
Copy link

We have seen some devices that only work after specific initialization steps -- even if those steps are just setting the device to a state it already claims to be in. I would check the device state via the TIOCMGET ioctl after it is working, and try setting those values via TIOCMSET to see if the device can be put back into a working state when it is first plugged in. Unfortunately if it requires a specific sequence of actions then obviously this is not going to be as simple. If a Windows client can get the device into a good state, then either source for that client or the use of a debugger (see APIs like SetCommState) will be required.

@Gussy
Copy link

Gussy commented Mar 15, 2019

I'm running into this same issue. The putty workaround is much appreciated but it would be great to see this get sorted out.

@Gussy
Copy link

Gussy commented Apr 7, 2020

Any updates on this one? I've been opening putty to "initialize" the port every time I connect the USB device, for at least a year now.

The BMP COM port works without extra configuration in Windows/Ubuntu/Mac but not WSL, so it seems like this is an issue specific to WSL?

@Gussy
Copy link

Gussy commented Apr 11, 2020

For anyone following along with this issue; I took the advice from @Brian-Perkins above and wrote a small program to check the device state with the TIOCMGET ioctl.

Here's the code:

#include <termios.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <stdio.h>
#include <unistd.h>

#define DEVICE "/dev/ttyS4"

#define BIT_SET(a, b) ((a & b) == b)

int main(void)
{
    int fd, serial;

    fd = open(DEVICE, O_RDONLY);
    ioctl(fd, TIOCMGET, &serial);
    printf("%s TIOCMGET 0x%02x\n", DEVICE, serial);

    printf("TIOCM_LE \t%i\n", BIT_SET(serial, TIOCM_LE));
    printf("TIOCM_DTR \t%i\n", BIT_SET(serial, TIOCM_DTR));
    printf("TIOCM_RTS \t%i\n", BIT_SET(serial, TIOCM_RTS));
    printf("TIOCM_ST \t%i\n", BIT_SET(serial, TIOCM_ST));
    printf("TIOCM_SR \t%i\n", BIT_SET(serial, TIOCM_SR));
    printf("TIOCM_CTS \t%i\n", BIT_SET(serial, TIOCM_CTS));
    printf("TIOCM_CAR \t%i\n", BIT_SET(serial, TIOCM_CAR));
    printf("TIOCM_CD \t%i\n", BIT_SET(serial, TIOCM_CD));
    printf("TIOCM_RNG \t%i\n", BIT_SET(serial, TIOCM_RNG));
    printf("TIOCM_RI \t%i\n", BIT_SET(serial, TIOCM_RI));
    printf("TIOCM_DSR \t%i\n", BIT_SET(serial, TIOCM_DSR));

    close(fd);
}

Withe the device freshly plugged in, within WSL I get:

$ gcc serial.c -o serial && ./serial
/dev/ttyS4 TIOCMGET 0x04
TIOCM_LE        0
TIOCM_DTR       0
TIOCM_RTS       1
TIOCM_ST        0
TIOCM_SR        0
TIOCM_CTS       0
TIOCM_CAR       0
TIOCM_CD        0
TIOCM_RNG       0
TIOCM_RI        0
TIOCM_DSR       0

and after running Putty to "activate" the port for WSL I get

$ gcc serial.c -o serial && ./serial
/dev/ttyS4 TIOCMGET 0x06
TIOCM_LE        0
TIOCM_DTR       1
TIOCM_RTS       1
TIOCM_ST        0
TIOCM_SR        0
TIOCM_CTS       0
TIOCM_CAR       0
TIOCM_CD        0
TIOCM_RNG       0
TIOCM_RI        0
TIOCM_DSR       0

I then altered the code above to set the "correct"(?) state using TIOCMSET before closing the device in the original code above:

    serial = 0x06;
    ioctl(fd, TIOCMSET, &serial);

After TIOCM_DTR was set to 1 I was able to connect to a freshly connected BMP debugger without having to open the device in Putty.

From here I'm able to have my flash.sh script call the small program above before starting arm-none-eabi-gdb, which solves my problem of having to "initialize" the port with Putty each time I plug it in. This solution is good enough for me, though I'm sure many others have run into this issue and given up.

I'd appreciate any input on if this is something which should be fixed in WSL or on the devices side? To me it still appears to be WSL bug since I don't see this behavior on MacOS, Windows, Ubuntu (native), although it's possible all of those OSes could be masking bad device behavior.

Copy link
Contributor

This issue has been automatically closed since it has not had any activity for the past year. If you're still experiencing this issue please re-file this as a new issue or feature request.

Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

6 participants