adafruit / circuitpython

CircuitPython - a Python implementation for teaching coding with microcontrollers
https://circuitpython.org
Other
4.11k stars 1.22k forks source link

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

Closed aivarannamaa closed 2 years ago

aivarannamaa commented 2 years ago

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:

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 commented 2 years ago

How about discotool ?

dhalbert commented 2 years ago

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

Neradoc commented 2 years ago

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 commented 2 years ago

@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 commented 2 years ago

@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 commented 2 years ago

@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 commented 2 years ago

@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 commented 2 years ago

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 commented 2 years ago

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 commented 2 years ago

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 commented 2 years ago

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