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

Cannot init USB devices in boot.py #882

Open
mischif opened this issue Jun 13, 2024 · 6 comments
Open

Cannot init USB devices in boot.py #882

mischif opened this issue Jun 13, 2024 · 6 comments

Comments

@mischif
Copy link

mischif commented Jun 13, 2024

I tested this on a pico running MP 1.23 and the latest release of usb-device-cdc.

boot.py:

import usb.device
from usb.device.cdc import CDCInterface

IFACE_TWO = CDCInterface()
IFACE_TWO.init(timeout=0)
#usb.device.get().init(IFACE_TWO, builtin_driver=True)

main.py:

from time import sleep_ms

def main():
	while True:
		print(IFACE_TWO)
		sleep_ms(1000)

if __name__ == "__main__": main()

Running this as-is, IFACE_TWO does show up in main.py, but uncommenting the init function causes the process to error out. This discord post suggests you can call usb.device.get.init() in boot.py, is this no longer true?

@projectgus
Copy link
Contributor

projectgus commented Jun 19, 2024

causes the process to error out

Please give some more details about this means: what exactly do you do, and what error output do you see?

A soft reset (i.e. Ctrl-D in the REPL) will still disconnect the USB port each time, because the runtime USB interface objects have to all be freed and recreated.

A hard reset (i.e. plugging the rp2 in, or calling machine.reset()) should come up immediately with the two CDC ports.

The only difference between boot.py and main.py is that the first time the device boots from a hard reset, it runs boot.py before it initialises USB. If you put the code in main.py instead of boot.py then the rp2 would first try create a device using the default USB interface, then immediately switch to the custom USB interface. This can show up on the host as connect/disconnect/connect cycle, or as an error depending on the timing.

@mischif
Copy link
Author

mischif commented Jun 19, 2024

With the init line commented out in boot.py:

  • plug in pico
  • mpremote fs cp boot.py :
  • unplug/replug
  • mpremote run main.py

I see the print statements I expect:

9600/8N1 rts=False dtr=False
9600/8N1 rts=False dtr=False
[...]

With the init line uncommented in boot.py:

  • plug in pico
  • mpremote fs cp boot.py :
  • unplug/replug
  • mpremote run main.py

I do not see the print statements I expect:

Traceback (most recent call last):
  [...]
  File "/home/mischif/.local/lib/python3.10/site-packages/serial/serialposix.py", line 549, in in_waiting
    s = fcntl.ioctl(self.fd, TIOCINQ, TIOCM_zero_str)
OSError: [Errno 5] Input/output error

I get dropped back to the terminal, and connecting with mpremote a0 yields no output. Attempting to replace boot.py even after unplugging/replugging the pico also yields the above OSError; I have to drop to a shell and use os.unlink().

@projectgus
Copy link
Contributor

projectgus commented Jun 19, 2024

Ah snap, mpremote run does a soft reset before it runs the provided file. Because boot.py has loaded the custom USB interface, it disconnects the USB port every time (then boot.py runs and adds it back, so you end up where you started.)

If you copy both boot.py and main.py to the filesystem then main.py works and you can use mpremote a0 to view the output, but you still can't use mpremote run any more.

I think the fix for this will be the planned work to have mpremote detect when the USB port is in a disconnect/reconnect cycle, and recover from it instead of erroring out.

@mischif
Copy link
Author

mischif commented Jul 10, 2024

Is there a timeline for when the planned work might be finished?

@projectgus
Copy link
Contributor

Not at the moment, I'm afraid.

@ziesemer
Copy link

I assume this is impacting mpremote connect as well (also including a soft reset)? Running similar as the OP above, I'm finding that I can connect directly to REPL by connecting to its COM port - but not using mpremote connect.

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

No branches or pull requests

3 participants