Boosted by brib@bribstodon.xyz ("brib :neofox_floof: :Nonbinary:"):
stuartl@longlandclan.id.au ("Stuart Longland (VK4MSL)") wrote:
Playing around with #NetBSD again… so I have a Intel NUC running it. One of the thing I frequently have to deal with, being an embedded software developer *and* an amateur radio operator, is #SerialPorts.
More often than not, USB serial ports. Now, I'm used to the Linux way of doing things, where everything is accessed through a /dev/tty* device.
We used to do it the BSD way with a device like /dev/cua0 (16550 UART on ISA 0x3f8 IRQ 4; COM1 for you DOS people) being your serial port ignoring carrier detect, and /dev/ttyS0 was the same serial port but required CD to be up. This got deprecated years ago, so /dev/cua0 disappeared, and we were left with /dev/ttyS0.
I grabbed a test rig I made for work, this is Zephyr RTOS on a Raspberry Pi Pico. It enumerates two CDC-ACM serial ports, one with the Zephyr shell, and the other is a USB serial port. You use the shell port to tell it how to route the RXD/TXD lines on the other serial port, with the board supporting RS-485, RS-422 and TTL serial. On Linux, it shows up as `/dev/ttyACM${n}` and `/dev/ttyACM$(( ${n} + 1 )`. `udev` also creates these symbolic links:
```
stuartl@rikishi ~ $ ls -l /dev/serial/by-id
total 0
lrwxrwxrwx 1 root root 13 Jul 26 10:58 usb-WideSky.Cloud_Pty_Ltd_WideSky_Hub_Test_Rig_E663AC91D3665F30-if00 -> ../../ttyACM0
lrwxrwxrwx 1 root root 13 Jul 26 10:58 usb-WideSky.Cloud_Pty_Ltd_WideSky_Hub_Test_Rig_E663AC91D3665F30-if02 -> ../../ttyACM1
stuartl@rikishi ~ $ ls -l /dev/serial/by-path/
total 0
lrwxrwxrwx 1 root root 13 Jul 26 10:58 pci-0000:00:14.0-usb-0:2:1.0 -> ../../ttyACM0
lrwxrwxrwx 1 root root 13 Jul 26 10:58 pci-0000:00:14.0-usb-0:2:1.2 -> ../../ttyACM1
lrwxrwxrwx 1 root root 13 Jul 26 10:58 pci-0000:00:14.0-usbv2-0:2:1.0 -> ../../ttyACM0
lrwxrwxrwx 1 root root 13 Jul 26 10:58 pci-0000:00:14.0-usbv2-0:2:1.2 -> ../../ttyACM1
```This is handy because if I have two of these, it doesn't matter which gets detected first, I know which device is which. The links ending in `-if02` or `.2` will be the data port, and the `-if00` / `.0` ones will be the shell control port.
In NetBSD, I plug this same MCU in and I get 4 devices:
- `/dev/dtyU0`
- `/dev/dtyU1`
- `/dev/ttyU0`
- `/dev/ttyU1`The files actually always exist, but they get mapped to this physical device when the driver detects it and enumerates it on USB.
If I plug in another dongle, I get another pair, a `/dev/dtyU2` and a `/dev/ttyU2`. The choice of `/dev/dtyU[012]` is dependent on which order the devices is detected… which on USB is indeterminate as they can be hotplugged.
The only clue I get is the `usbdevs -v`; it shows a device number and serial number information.
```
vk4msl-nbsd# usbdevs -v
Controller /dev/usb0:
addr 0: super speed, self powered, config 1, xHCI root hub(0x0000), NetBSD(0x0000), rev 1.00(0x0100)
port 1 disabled
port 2 disabled
port 3 disabled
port 4 disabled
Controller /dev/usb1:
addr 0: high speed, self powered, config 1, xHCI root hub(0x0000), NetBSD(0x0000), rev 1.00(0x0100)
port 1 powered
port 2 addr 17: full speed, power 100 mA, config 1, USB-Serial Controller D(0x2303), Prolific Technology Inc.(0x067b), rev 4.00(0x0400)
port 3 addr 1: low speed, power 100 mA, config 1, CASUE USB KB(0x6a21), vendor 2a7a(0x2a7a), rev 0.01(0x0001)
port 4 addr 18: full speed, self powered, config 1, WideSky Hub Test Rig(0x5678), WideSky.Cloud Pty Ltd(0x1234), rev 4.03(0x0403), serial E663AC91D3665F30
port 5 powered
port 6 powered
port 7 addr 3: full speed, self powered, config 1, product 0a2a(0x0a2a), Intel(0x8087), rev 0.01(0x0001)
port 8 powered
port 9 powered
port 10 powered
port 11 powered
…
```lacking is the knowledge that there are *two* devices allocated to device 18 (the test rig).
Given a `/dev/ttyU${n}` or `/dev/dtyU${n}` device node, how do I find out about the device attached to it? Seems assuming a device node is fraught with danger.