Skip to content

Commit

Permalink
move GPIO chip cache declaration to gpio.h
Browse files Browse the repository at this point in the history
This should allow for easier code reuse when implementing a similar cache for interrupts
  • Loading branch information
2bndy5 committed Mar 13, 2024
1 parent 16d6849 commit 553a8f1
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 59 deletions.
105 changes: 47 additions & 58 deletions utility/SPIDEV/gpio.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,75 +22,64 @@ struct gpio_v2_line_request request;
struct gpio_v2_line_values data;
struct gpiochip_info chipMeta;

// A struct to keep a track of the open/closed file descriptor for specified GPIO chip
struct GlobalCache
void GPIOChipCache::openDevice()
{
const char* chip = RF24_SPIDEV_GPIO_CHIP;
int fd = -1;

// Open the File Descriptor for the GPIO chip
void openDevice()
{
if (fd < 0) {
fd = open(chip, O_RDONLY);
if (fd < 0) {
fd = open(chip, O_RDONLY);
if (fd < 0) {
std::string msg = "Can't open device ";
msg += chip;
msg += "; ";
msg += strerror(errno);
throw GPIOException(msg);
}
std::string msg = "Can't open device ";
msg += chip;
msg += "; ";
msg += strerror(errno);
throw GPIOException(msg);
}
}
}

/// Close the File Descriptor for the GPIO chip
void closeDevice()
{
if (fd >= 0) {
close(fd);
fd = -1;
}
void GPIOChipCache::closeDevice()
{
if (fd >= 0) {
close(fd);
fd = -1;
}
}

// should be called automatically on program start.
// Here, we do some one-off configuration.
GlobalCache()
{
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
int ret = ioctl(fd, GPIO_GET_CHIPINFO_IOCTL, &chipMeta);
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()
{
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
int ret = ioctl(fd, GPIO_GET_CHIPINFO_IOCTL, &chipMeta);
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
}

// Should be called automatically on program exit.
// What we need here is to make sure that the File Descriptors used to
// control GPIO pins are properly closed.
~GlobalCache()
{
closeDevice();
for (std::map<rf24_gpio_pin_t, gpio_fd>::iterator i = cachedPins.begin(); i != cachedPins.end(); ++i) {
if (i->second > 0) {
close(i->second);
}
GPIOChipCache::~GPIOChipCache()
{
closeDevice();
for (std::map<rf24_gpio_pin_t, gpio_fd>::iterator i = cachedPins.begin(); i != cachedPins.end(); ++i) {
if (i->second > 0) {
close(i->second);
}
}
} gpioCache;
}

// GPIO chip cache manager
GPIOChipCache gpioCache;

GPIO::GPIO()
{
Expand Down
23 changes: 22 additions & 1 deletion utility/SPIDEV/gpio.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,28 @@ class GPIOException : public std::runtime_error
}
};

typedef int GPIOfdCache_t;
/// A struct to manage the GPIO chip file descriptor.
/// This struct's destructor should close any cached GPIO pin requests' file descriptors.
struct GPIOChipCache
{
const char* chip = RF24_SPIDEV_GPIO_CHIP;
int fd = -1;

/// Open the File Descriptor for the GPIO chip
void openDevice();

/// Close the File Descriptor for the GPIO chip
void closeDevice();

/// should be called automatically on program start.
/// Here, we do some one-off configuration.
GPIOChipCache();

/// Should be called automatically on program exit.
/// What we need here is to make sure that the File Descriptors used to
/// control GPIO pins are properly closed.
~GPIOChipCache();
};

class GPIO
{
Expand Down

0 comments on commit 553a8f1

Please sign in to comment.