Skip to content

Commit

Permalink
move gpiochipX init out of cache c'tors
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
2bndy5 committed Mar 18, 2024
1 parent d81439f commit 7973ba6
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 50 deletions.
42 changes: 21 additions & 21 deletions utility/RPi/interrupt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down
5 changes: 2 additions & 3 deletions utility/RPi/interrupt.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
#ifndef RF24_UTILITY_RPI_INTERRUPT_H_
#define RF24_UTILITY_RPI_INTERRUPT_H_

#include <pthread.h> // pthread_t
#include <linux/gpio.h> // gpiochip_info
#include <pthread.h> // pthread_t
#include <stdexcept>
#include <linux/gpio.h> // GPIO_V2_LINE_FLAG_EDGE_***
#include "RF24_arch_config.h" // rf24_gpio_pin_t

#define INT_EDGE_FALLING GPIO_V2_LINE_FLAG_EDGE_FALLING
Expand All @@ -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();
Expand Down
41 changes: 20 additions & 21 deletions utility/SPIDEV/gpio.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand All @@ -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;
Expand All @@ -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) {
Expand Down
1 change: 0 additions & 1 deletion utility/SPIDEV/gpio.h
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
26 changes: 22 additions & 4 deletions utility/SPIDEV/interrupt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
#include <pthread.h>
#include <map>
#include "interrupt.h"
#include "gpio.h" // GPIOChipCache
#include "gpio.h" // GPIOChipCache, GPIOException

#ifdef __cplusplus
extern "C" {
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down

0 comments on commit 7973ba6

Please sign in to comment.