From 7973ba6b6a2357bcad6e2da70da728b783e64124 Mon Sep 17 00:00:00 2001 From: Brendan <2bndy5@gmail.com> Date: Mon, 18 Mar 2024 11:35:53 -0700 Subject: [PATCH] move gpiochipX init out of cache c'tors this should fix the issue with loading pyRF24 modules( downstream) when building docs. There should be negligible performance hit as most of this init stuff (`pinMode()` and `attachInterrupt()`) only takes place at user space startup. Although, devs that dynamically allocate pins (with `RF24::begin(CE, CSN)`) will see a performance cost. --- utility/RPi/interrupt.cpp | 42 ++++++++++++++++++------------------ utility/RPi/interrupt.h | 5 ++--- utility/SPIDEV/gpio.cpp | 41 +++++++++++++++++------------------ utility/SPIDEV/gpio.h | 1 - utility/SPIDEV/interrupt.cpp | 26 ++++++++++++++++++---- 5 files changed, 65 insertions(+), 50 deletions(-) diff --git a/utility/RPi/interrupt.cpp b/utility/RPi/interrupt.cpp index bb5c95241..9d6125f2b 100644 --- a/utility/RPi/interrupt.cpp +++ b/utility/RPi/interrupt.cpp @@ -42,24 +42,6 @@ void IrqChipCache::closeDevice() IrqChipCache::IrqChipCache() { - try { - openDevice(); - } - catch (IRQException& exc) { - chip = "/dev/gpiochip0"; - openDevice(); - } - - // cache chip info - memset(&info, 0, sizeof(info)); - int ret = ioctl(fd, GPIO_GET_CHIPINFO_IOCTL, &info); - if (ret < 0) { - std::string msg = "Could not gather info about "; - msg += chip; - throw IRQException(msg); - return; - } - closeDevice(); // in case other apps want to access it } IrqChipCache::~IrqChipCache() @@ -102,7 +84,26 @@ int attachInterrupt(rf24_gpio_pin_t pin, int mode, void (*function)(void)) // ensure pin is not already being used in a separate thread detachInterrupt(pin); - if (pin > irqChipCache.info.lines) { + try { + irqChipCache.openDevice(); + } + catch (IRQException& exc) { + irqChipCache.chip = "/dev/gpiochip0"; + irqChipCache.openDevice(); + } + + // get chip info + gpiochip_info info; + memset(&info, 0, sizeof(info)); + int ret = ioctl(irqChipCache.fd, GPIO_GET_CHIPINFO_IOCTL, &info); + if (ret < 0) { + std::string msg = "[attachInterrupt] Could not gather info about "; + msg += irqChipCache.chip; + throw IRQException(msg); + return 0; + } + + if (pin > info.lines) { std::string msg = "[attachInterrupt] pin " + std::to_string(pin) + " is not available on " + irqChipCache.chip; throw IRQException(msg); return 0; @@ -136,8 +137,7 @@ int attachInterrupt(rf24_gpio_pin_t pin, int mode, void (*function)(void)) } // write pin request's config - irqChipCache.openDevice(); - int ret = ioctl(irqChipCache.fd, GPIO_V2_GET_LINE_IOCTL, &request); + ret = ioctl(irqChipCache.fd, GPIO_V2_GET_LINE_IOCTL, &request); if (ret < 0 || request.fd <= 0) { std::string msg = "[attachInterrupt] Could not get line handle from ioctl; "; msg += strerror(errno); diff --git a/utility/RPi/interrupt.h b/utility/RPi/interrupt.h index 1f222ff7a..7fe7dcf04 100644 --- a/utility/RPi/interrupt.h +++ b/utility/RPi/interrupt.h @@ -4,9 +4,9 @@ #ifndef RF24_UTILITY_RPI_INTERRUPT_H_ #define RF24_UTILITY_RPI_INTERRUPT_H_ -#include // pthread_t -#include // gpiochip_info +#include // pthread_t #include +#include // GPIO_V2_LINE_FLAG_EDGE_*** #include "RF24_arch_config.h" // rf24_gpio_pin_t #define INT_EDGE_FALLING GPIO_V2_LINE_FLAG_EDGE_FALLING @@ -33,7 +33,6 @@ struct IrqChipCache { const char* chip = RF24_LINUX_GPIO_CHIP; int fd = -1; - gpiochip_info info; /// Open the File Descriptor for the GPIO chip void openDevice(); diff --git a/utility/SPIDEV/gpio.cpp b/utility/SPIDEV/gpio.cpp index 6bdb25fbc..e153444bf 100644 --- a/utility/SPIDEV/gpio.cpp +++ b/utility/SPIDEV/gpio.cpp @@ -45,27 +45,9 @@ void GPIOChipCache::closeDevice() GPIOChipCache::GPIOChipCache() { - try { - openDevice(); - } - catch (GPIOException& exc) { - chip = "/dev/gpiochip0"; - openDevice(); - } request.num_lines = 1; strcpy(request.consumer, "RF24 lib"); data.mask = 1ULL; // only change value for specified pin - - // cache chip info - memset(&info, 0, sizeof(info)); - int ret = ioctl(fd, GPIO_GET_CHIPINFO_IOCTL, &info); - if (ret < 0) { - std::string msg = "Could not gather info about "; - msg += chip; - throw GPIOException(msg); - return; - } - closeDevice(); // in case other apps want to access it } GPIOChipCache::~GPIOChipCache() @@ -91,7 +73,26 @@ GPIO::~GPIO() void GPIO::open(rf24_gpio_pin_t port, int DDR) { - if (port > gpioCache.info.lines) { + try { + gpioCache.openDevice(); + } + catch (GPIOException& exc) { + gpioCache.chip = "/dev/gpiochip0"; + gpioCache.openDevice(); + } + + // get chip info + gpiochip_info info; + memset(&info, 0, sizeof(info)); + int ret = ioctl(gpioCache.fd, GPIO_GET_CHIPINFO_IOCTL, &info); + if (ret < 0) { + std::string msg = "Could not gather info about "; + msg += gpioCache.chip; + throw GPIOException(msg); + return; + } + + if (port > info.lines) { std::string msg = "pin number " + std::to_string(port) + " not available for " + gpioCache.chip; throw GPIOException(msg); return; @@ -107,8 +108,6 @@ void GPIO::open(rf24_gpio_pin_t port, int DDR) request.fd = pin->second; } - gpioCache.openDevice(); - int ret; if (request.fd <= 0) { ret = ioctl(gpioCache.fd, GPIO_V2_GET_LINE_IOCTL, &request); if (ret == -1 || request.fd <= 0) { diff --git a/utility/SPIDEV/gpio.h b/utility/SPIDEV/gpio.h index 3337f5218..e780244df 100644 --- a/utility/SPIDEV/gpio.h +++ b/utility/SPIDEV/gpio.h @@ -44,7 +44,6 @@ struct GPIOChipCache { const char* chip = RF24_LINUX_GPIO_CHIP; int fd = -1; - gpiochip_info info; /// Open the File Descriptor for the GPIO chip void openDevice(); diff --git a/utility/SPIDEV/interrupt.cpp b/utility/SPIDEV/interrupt.cpp index 9c673deae..bc7d1109b 100644 --- a/utility/SPIDEV/interrupt.cpp +++ b/utility/SPIDEV/interrupt.cpp @@ -10,7 +10,7 @@ #include #include #include "interrupt.h" -#include "gpio.h" // GPIOChipCache +#include "gpio.h" // GPIOChipCache, GPIOException #ifdef __cplusplus extern "C" { @@ -64,7 +64,26 @@ int attachInterrupt(rf24_gpio_pin_t pin, int mode, void (*function)(void)) detachInterrupt(pin); GPIO::close(pin); - if (pin > irqChipCache.info.lines) { + try { + irqChipCache.openDevice(); + } + catch (GPIOException& exc) { + irqChipCache.chip = "/dev/gpiochip0"; + irqChipCache.openDevice(); + } + + // get chip info + gpiochip_info info; + memset(&info, 0, sizeof(info)); + int ret = ioctl(irqChipCache.fd, GPIO_GET_CHIPINFO_IOCTL, &info); + if (ret < 0) { + std::string msg = "[attachInterrupt] Could not gather info about "; + msg += irqChipCache.chip; + throw IRQException(msg); + return 0; + } + + if (pin > info.lines) { std::string msg = "[attachInterrupt] pin " + std::to_string(pin) + " is not available on " + irqChipCache.chip; throw IRQException(msg); return 0; @@ -98,8 +117,7 @@ int attachInterrupt(rf24_gpio_pin_t pin, int mode, void (*function)(void)) } // write pin request's config - irqChipCache.openDevice(); - int ret = ioctl(irqChipCache.fd, GPIO_V2_GET_LINE_IOCTL, &request); + ret = ioctl(irqChipCache.fd, GPIO_V2_GET_LINE_IOCTL, &request); if (ret < 0 || request.fd <= 0) { std::string msg = "[attachInterrupt] Could not get line handle from ioctl; "; msg += strerror(errno);