From a94c858b014da0d63e12764b636a281e740aad90 Mon Sep 17 00:00:00 2001 From: Tim Small Date: Mon, 24 Apr 2023 14:56:16 +0100 Subject: [PATCH] Add open_path() Python method to permit persistent device symlinks. Adds to the functionality provided by the open() call (which hard-codes the opening of /dev/spidev. 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 #129 --- README.md | 13 ++++++++++--- spidev_module.c | 24 ++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 5f272d6..9d06436 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ Usage ```python import spidev spi = spidev.SpiDev() -spi.open(bus, device) +spi.open_path(spidev_devicefile_path) to_send = [0x01, 0x02, 0x03] spi.xfer(to_send) ``` @@ -21,7 +21,7 @@ Settings ```python import spidev spi = spidev.SpiDev() -spi.open(bus, device) +spi.open_path("/dev/spidev0.0") # Settings (for example) spi.max_speed_hz = 5000 @@ -43,9 +43,16 @@ spi.mode = 0b01 Methods ------- + open_path(filesystem_path) + +Connects to the specified SPI device special file, following symbolic links if +appropriate (see note on deterministic SPI bus numbering in the Linux kernel +below for why this can be advantageous in some configurations). + open(bus, device) -Connects to the specified SPI device, opening `/dev/spidev.` +Equivalent to calling `open_path("/dev/spidev.")`. n.b. **Either** +`open_path` or `open` should be used. readbytes(n) diff --git a/spidev_module.c b/spidev_module.c index cf12a1d..a7eddc3 100644 --- a/spidev_module.c +++ b/spidev_module.c @@ -1365,6 +1365,28 @@ SpiDev_open_dev(SpiDevObject *self, char *dev_path) } +PyDoc_STRVAR(SpiDev_open_path_doc, + "open_path(spidev_path)\n\n" + "Connects the object to the specified SPI device.\n" + "open_path(X) will open the spidev character device (following symbolic links if necessary).\n"); + +static PyObject * +SpiDev_open_path(SpiDevObject *self, PyObject *args, PyObject *kwds) +{ + static char *kwlist[] = {"path", NULL}; + PyObject *py_dev_path; + char *dev_path; + if (!PyArg_ParseTupleAndKeywords(args, kwds, "O&:open", kwlist, PyUnicode_FSConverter, &py_dev_path)) + return NULL; + if (py_dev_path == NULL) + return NULL; + dev_path = PyBytes_AsString(py_dev_path); + if (dev_path == NULL) + return NULL; + return SpiDev_open_dev(self, dev_path); +} + + PyDoc_STRVAR(SpiDev_open_doc, "open(bus, device)\n\n" "Connects the object to the specified SPI device.\n" @@ -1441,6 +1463,8 @@ PyObject *SpiDev_exit(SpiDevObject *self, PyObject *args) static PyMethodDef SpiDev_methods[] = { {"open", (PyCFunction)SpiDev_open, METH_VARARGS | METH_KEYWORDS, SpiDev_open_doc}, + {"open_path", (PyCFunction)SpiDev_open_path, METH_VARARGS | METH_KEYWORDS, + SpiDev_open_path_doc}, {"close", (PyCFunction)SpiDev_close, METH_NOARGS, SpiDev_close_doc}, {"fileno", (PyCFunction)SpiDev_fileno, METH_NOARGS,