Skip to content

Provide means for reliably relating serial port and filesystem mount path #6621

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

Closed
aivarannamaa opened this issue Jul 20, 2022 · 11 comments
Closed
Assignees
Milestone

Comments

@aivarannamaa
Copy link

aivarannamaa commented Jul 20, 2022

It would be nice if one (a person or a tool) could reliably locate device's host mount path when given a serial port and vice versa.

Example situations:

  • Thonny users need to select their device by serial port but as serial REPL can't be used for saving files, Thonny needs to locate device's filesystem mount as well. It currently uses storage.getmount('/') to retrieve volume label and hopes to find single volume with given name. This doesn't work out when there are several CP boards plugged in.
  • Pipkin allows users to select their device by mount path. I'd like pipkin to consult device's list of frozen modules (help("modules")) before performing an install, so that it can see whether adafruit_bus_device is built-in for this device or not (here's a related discussion: build_bundles: Ignore more packages that exist only on pypi circuitpython-build-tools#90 (comment)). For this it is necessary to find the serial port corresponding to given mount path.

I assume it is not possible for CircuitPython to directly report its mount path or serial port, but would it be possible to append another line to boot_out.txt, which reports device's USB serial number? If I'm not mistaken, this is a unique identifier, which means tools could use it for reliably finding the right port given the mount path and vice versa.

@Neradoc
Copy link

Neradoc commented Jul 20, 2022

How about discotool ?

@dhalbert
Copy link
Collaborator

Or https://github.com/adafruit/Adafruit_Board_Toolkit, which uses most of the same insides as discotool?

@Neradoc
Copy link

Neradoc commented Jul 20, 2022

The Adafruit_Board_Toolkit is for serial ports, they only share the fixed pyserial list_ports.
Discotool goes through the USB hierarchy to associate the USB Mass Storage Device and the serial ports for each board, then find the actual mount point(s) for the USB drive. In my research at the time, I found no simple way to do that in a multi-platform way (I also rejected using pyusb due to the dependency to libusb which is outside of pip).
It was rather straightforward with pyudev on linux, but the mac and windows ports are a little more "hacky", using the serial number to match devices, which is not guaranteed to be unique (per board) or even existing outside of Circuitpython devices. I hope to make that better some day, but that is a discussion for the discotool repo.

@dhalbert
Copy link
Collaborator

@Neradoc thanks for the clarification.

@aivarannamaa: microcontroller.cpu.uid returns the serial number, so you could access it from the REPL via the Thonny back end. But maybe that doesn't help to distinguish it via volume?

We have had some issues about the nibble and byte order of cpu.uid, and we may need to flip some things around to make them match.

@aivarannamaa
Copy link
Author

@Neradoc, thanks for the library and explanations! Somehow it never occurred to me that I could turn to OS for getting the match between serial port and mount point. Your library's deps are rather heavy, though... I'll need to give it some thought.

@dhalbert, I tried your advice on Cytron Maker Pi RP2040, but microcontroller.cpu.uid (bytearray(b'\xe6'\xc0b\x13B\x155')) seems to be very different from its USB serial id ( "E660C06213421535").

@dhalbert
Copy link
Collaborator

@dhalbert, I tried your advice on Cytron Maker Pi RP2040, but microcontroller.cpu.uid (bytearray(b'\xe6'\xc0b\x13B\x155')) seems to be very different from its USB serial id ( "E660C06213421535").

The bytearray is mixed printing characters and hex-escaped characters. I think you substituted a single quote for a backtick in there. Assuming that, I get:

>>> [hex(b) for b in b'\xe6`\xc0b\x13B\x155']
['0xe6', '0x60', '0xc0', '0x62', '0x13', '0x42', '0x15', '0x35']

whose digits match the concatenated digits in "E660C06213421535".

@aivarannamaa
Copy link
Author

@dhalbert, thank you!

I thought E660C06213421535 is just a string of characters, not a hexlified representation of some bytes.

It looks like with this I can really implement the mount point lookup in Thonny. It's not good solution for going from mount point to serial port, though, so I'll think about alternative solutions for pipkin.

Please decide whether to close this issue or leave it open. For pipkin I would still like this extra line in boot_out.txt, but I understand that you have limited time and that making the file larger/more complex has its own downsides.

@aivarannamaa
Copy link
Author

It looks like with this I can really implement the mount point lookup in Thonny.

Oops, I just realized I got my thinking messed up. By learning the USB serial ID via MicroPython code I can easily find only the right serial port, which I already know. If I understood @Neradoc correctly, then the hard part is finding the mount point by serial port information. Having the serial ID explicitly written out at the mount point should make it easy.

@tannewt tannewt added this to the 8.0.0 milestone Jul 25, 2022
@tannewt
Copy link
Member

tannewt commented Jul 25, 2022

I'd be ok with adding serial to boot_out.txt. Maybe it'd be better to write a json file with info we get from boot_out.txt. That'd make version agnostic parsing much easier. (It'd be bad for tiny filesystems though.)

@aivarannamaa
Copy link
Author

A line in boot_out.txt would be good enough for my projects. If I simply had to find a line with specific prefix (eg. Serial: ), then parsing wouldn't be too much harder compared to json format.

@tannewt tannewt self-assigned this Aug 3, 2022
@tannewt
Copy link
Member

tannewt commented Aug 3, 2022

I'm adding a UID: like with the uid printed as %02X per byte.

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

No branches or pull requests

4 participants