esp-rs / espflash

Serial flasher utility for Espressif SoCs and modules based on esptool.py
Apache License 2.0
471 stars 115 forks source link

espflash gets stuck at Connecting... in WSL Dev Container using USBIPD #411

Closed marco12en3 closed 6 months ago

marco12en3 commented 1 year ago

This happens when working in a VS Code dev container and using the following link: https://learn.microsoft.com/en-us/windows/wsl/connect-usb.

esp@1dff5bb6222f:~/espflash$ espflash monitor -p /dev/ttyACM0
[2023-05-25T20:06:26Z INFO ] Serial port: '/dev/ttyACM0'
[2023-05-25T20:06:26Z INFO ] Connecting...

And nothing happens.

When debugging, I found that the serial communication gets stuck in a flush(). The cause appears to be inside /espflash/src/connection.rs:123 reset_to_flash().

if self.port_info.pid == USB_SERIAL_JTAG_PID {

the port_info.pid is 0 when I run this inside WSL with USBIPD. After replacing this if statement with if true, everything works, including flashing.

This problem might originate from a dependency somewhere else, but maybe providing a workaround with a command-line argument forcing Serial/JTAG would be appreciated by people running into this issue.

marco12en3 commented 1 year ago

With this command you can install the workaround

cargo install espflash cargo-espflash --git https://github.com/marco12en3/espflash

This works for my Espressif USB JTAG/serial debug unit on WSL2 using USBIPD It is a fork from this repo with a small change in connection.rs

jessebraham commented 1 year ago

If WSL is not setting the PID then this is an issue with WSL. Your branch obviously isn't a viable solution, is there any way to get WSL to handle USB correctly? I'm not a Windows user, but based on some quick searching it should be possible.

marco12en3 commented 1 year ago

If WSL is not setting the PID then this is an issue with WSL. Your branch obviously isn't a viable solution, is there any way to get WSL to handle USB correctly?

I think WSL is setting the PID correctly. My branch is only a quick workaround for this specific issue. Everything USB-related is working fine, including openocd/gdb and all the Python-based ESP tools. The first issue I ran into is this Rust project.

With the command 'lsusb', the device is listed as 'Bus 001 Device 009: ID 303a:1001 Espressif USB JTAG/serial debug unit'. In 'espflash/src/cli/mod.rs', this line is reached: debug!("Matched SerialPortType::PciPort or ::Unknown"). serialport-4.2.0 determines the port_type to be SerialPortType::Unknown.

I think the problem is the interaction between serialport-4.2.0 and usbip, but I'm not sure which one has the bug.

marco12en3 commented 1 year ago

It's not a bug; WSL is not running udev. On https://github.com/serialport/serialport-rs, it reads:

Serial enumeration is provided on most platforms. The implementation on Linux using glibc relies on libudev, an external dynamic library that will need to be available on the system the final binary is running on. Enumeration will still be available if this feature is disabled, but won't expose as much information and may return ports that don't exist physically. However this dependency can be removed by disabling the default libudev feature

The key part is:

but won't expose as much information

espflash uses that missing PID information from libudev to determine if the device is USB_SERIAL_JTAG_PID. The only reason espflash needs to know this is for the reset_to_flash() function.

marco12en3 commented 1 year ago

There are ways to obtain the PID without relying on serialport to provide it. For example

~$ cat /sys/dev/char/$(stat -c "%Hr:%Lr" /dev/ttyACM0)/device/uevent | grep PRODUCT
PRODUCT=303a/1001/101
nagisa commented 1 year ago

I hit a similar issue when attempting to use USB/IP on Linux as well (the ESP I’m trying to flash is in a different place from my development machine). esptool.py appears to work, but espflash gets stuck in a similar place, printing “Unable to connect” repeatedly.

If you're looking for some reproduction steps, https://developer.ridgerun.com/wiki/index.php/How_to_setup_and_use_USB/IP contains description how to use usbip(d).

SergioGasquez commented 6 months ago

I think the problem is the interaction between serialport-4.2.0 and usbip, but I'm not sure which one has the bug.

@nagisa @marco12en3. Since there were new releases of both serialport and espflash, could you try with latest espflash (v3.0.0-rc.1) to see if the issue persists?

nagisa commented 6 months ago

I do not have any spare ESPs around right now to test this out unfortunately.

SergioGasquez commented 6 months ago

I'll be closing the issue as inactive since it can't be tested with latest releases. Feel free to reopen if needed.

soiamsoNG commented 5 months ago

esp-idf-template create tempalte

test espflash v3.0.0 inside devcontainer (podman) on top Fedora39 (host) stuck at Connecting..., no usbip on the host

lsusb (inside podman) can show infomation with PID

below method (inside podman) can obtain the PID

There are ways to obtain the PID without relying on serialport to provide it. For example

~$ cat /sys/dev/char/$(stat -c "%Hr:%Lr" /dev/ttyACM0)/device/uevent | grep PRODUCT
PRODUCT=303a/1001/101

this workaround is still workable, can get correct information.

With this command you can install the workaround

cargo install espflash cargo-espflash --git https://github.com/marco12en3/espflash

This works for my Espressif USB JTAG/serial debug unit on WSL2 using USBIPD It is a fork from this repo with a small change in connection.rs