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

The open() method is not well suited to hot-plugged SPI device controllers (e.g. USB, Thunderbolt, PCIe and similar situations). #129

Open
tim-seoss opened this issue Mar 15, 2023 · 2 comments · May be fixed by #130

Comments

@tim-seoss
Copy link

The Linux kernel usually doesn't guarantee that SPI bus numbers are predictable and persistent across reboots, and kernel upgrades etc.

As with other device special files (e.g. storage devices, network devices, serial ports), the Linux udev subsystem is the generic mechanism for creating persistent/predictable names for devices (including SPI bus numbers).

Whilst in many cases the SPI bus number is predicable (e.g. Raspberry Pi OS maintainers take steps to ensure the spi bus number remains stable), in general this is not the case (e.g. Beaglebone Black has swapped SPI bus numbers 0 and 1 more than once between major Linux kernel version upgrades).

Unfortunately the current open() method requires that the user of the extension knows the bus number because it hard-codes the use of /dev/spidevX.Y.

A solution would be to add a second alternative call e.g. open_path() which would allow the user to supply a persistent device name such as /dev/spi/by-path/ftdi232h_7821067-cs0. Such a filesystem path would typically be created automatically by the udev daemon when, and would take the form of a symbolic link to a (non-predictable) spidev character device file e.g. /dev/spidev/14.0.

Having studied the codebase, it would be possible to keep the existing open() call (for backward compatibility), whilst adding a more generic open_path() alternative.

I'll prepare a PR with a draft implementation, along with some sample udev rules, and documentation updates.

tim-seoss added a commit to tim-seoss/py-spidev that referenced this issue Apr 24, 2023
Prep for adding open_path Python method in doceme#129
tim-seoss added a commit to tim-seoss/py-spidev that referenced this issue Apr 24, 2023
Prep for adding open_path Python method in doceme#129
tim-seoss added a commit to tim-seoss/py-spidev that referenced this issue Apr 24, 2023
Adds to the functionality provided by the open() call (which hard-codes
the opening of /dev/spidev<bus>.<chipselect> device file paths).
Because the bus number allocation may not be knowable in advance (bus
numbers are dynamically allocated by the Linux kernel), open_path()
allows the user to employ udev rules to deterministically create a
symlink to the correct hardware device at boot and/or hot-plug time.

Resolves doceme#129
tim-seoss added a commit to tim-seoss/py-spidev that referenced this issue Apr 24, 2023
Adds to the functionality provided by the open() call (which hard-codes
the opening of /dev/spidev<bus>.<chipselect> device file paths).
Because the bus number allocation may not be knowable in advance (bus
numbers are dynamically allocated by the Linux kernel), open_path()
allows the user to employ udev rules to deterministically create a
symlink to the correct hardware device at boot and/or hot-plug time.

Part of doceme#129
tim-seoss added a commit to tim-seoss/py-spidev that referenced this issue Apr 24, 2023
tim-seoss added a commit to tim-seoss/py-spidev that referenced this issue Apr 24, 2023
tim-seoss added a commit to tim-seoss/py-spidev that referenced this issue Apr 24, 2023
Prep for adding open_path Python method in doceme#129
tim-seoss added a commit to tim-seoss/py-spidev that referenced this issue Apr 24, 2023
Adds to the functionality provided by the open() call (which hard-codes
the opening of /dev/spidev<bus>.<chipselect> device file paths).
Because the bus number allocation may not be knowable in advance (bus
numbers are dynamically allocated by the Linux kernel), open_path()
allows the user to employ udev rules to deterministically create a
symlink to the correct hardware device at boot and/or hot-plug time.

Part of doceme#129
tim-seoss added a commit to tim-seoss/py-spidev that referenced this issue Apr 24, 2023
@Gadgetoid
Copy link
Contributor

This is a good point, and thank you for your PR.

I need to find the time to test this, since I am able to accept PRs on my fork and release a new version of the spidev Python library if it makes sense.

I'm currently fighting bugs on Pi 5, however, but after that I'll be updating some libraries that use spidev and it would make sense for me to test changes like this then.

@tim-seoss tim-seoss changed the title The open() method awkward for hot-plugged SPI device controllers (e.g. USB, Thunderbolt, PCIe and similar situations). The open() method is not well suited to hot-plugged SPI device controllers (e.g. USB, Thunderbolt, PCIe and similar situations). Nov 3, 2023
@tim-seoss
Copy link
Author

Thanks, any feedback is welcome. An organisation I work with has put this code into production, so it's received a reasonably amount of testing on a couple of different 32 bit ARM systems. I've also used it with USB to SPI adapters on x86-64.

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

Successfully merging a pull request may close this issue.

2 participants