Merge pull request #43 from nanosonde/improve_rf_linux

Improve GPIO for Linux platform
This commit is contained in:
thelsing 2019-10-28 21:11:38 +01:00 committed by GitHub
commit f6ace390ee
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 97 additions and 44 deletions

View File

@ -11,6 +11,19 @@
#include <time.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <signal.h>
#include <sched.h>
#include <sys/mman.h>
volatile sig_atomic_t loopActive = 1;
void signalHandler(int sig)
{
(void)sig;
// can be called asynchronously
loopActive = 0;
}
#if MEDIUM_TYPE == 5
KnxFacade<LinuxPlatform, Bau57B0> knx;
@ -97,15 +110,39 @@ void setup()
int main(int argc, char **argv)
{
printf("main() start.\n");
// Prevent swapping of this process
struct sched_param sp;
memset(&sp, 0, sizeof(sp));
sp.sched_priority = sched_get_priority_max(SCHED_FIFO);
sched_setscheduler(0, SCHED_FIFO, &sp);
mlockall(MCL_CURRENT | MCL_FUTURE);
// Register signals
signal(SIGINT, signalHandler);
signal(SIGTERM, signalHandler);
knx.platform().cmdLineArgs(argc, argv);
setup();
while (1)
while (loopActive)
{
knx.loop();
if(knx.configured())
appLoop();
delayMicroseconds(100);
}
// pinMode() will automatically export GPIO pin in sysfs
// Read or writing the GPIO pin for the first time automatically
// opens the "value" sysfs file to read or write the GPIO pin value.
// The following calls will close the "value" sysfs fiel for the pin
// and unexport the GPIO pin.
gpio_unexport(SPI_SS_PIN);
gpio_unexport(GPIO_GDO2_PIN);
gpio_unexport(GPIO_GDO0_PIN);
printf("main() exit.\n");
}

View File

@ -602,7 +602,16 @@ void LinuxPlatform::cmdLineArgs(int argc, char** argv)
}
/* Buffer size for string operations (e.g. snprintf())*/
#define MAXBUFFER 100
#define MAX_STRBUF_SIZE 100
#define MAX_NUM_GPIO 64
static int gpioFds [MAX_NUM_GPIO] =
{
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
} ;
/* Activate GPIO-Pin
* Write GPIO pin number to /sys/class/gpio/export
@ -610,10 +619,12 @@ void LinuxPlatform::cmdLineArgs(int argc, char** argv)
*/
int gpio_export(int pin)
{
char buffer[MAXBUFFER]; /* Output Buffer */
ssize_t bytes; /* Used Buffer length */
int fd; /* Filedescriptor */
int res; /* Result from write() */
char buffer[MAX_STRBUF_SIZE]; /* Output Buffer */
ssize_t bytes; /* Used Buffer length */
int fd; /* Filedescriptor */
int res; /* Result from write() */
fprintf(stderr, "Export GPIO pin %d\n", pin);
fd = open("/sys/class/gpio/export", O_WRONLY);
if (fd < 0)
@ -622,7 +633,7 @@ int gpio_export(int pin)
return(-1);
}
bytes = snprintf(buffer, MAXBUFFER, "%d", pin);
bytes = snprintf(buffer, MAX_STRBUF_SIZE, "%d", pin);
res = write(fd, buffer, bytes);
if (res < 0)
@ -643,10 +654,14 @@ int gpio_export(int pin)
*/
int gpio_unexport(int pin)
{
char buffer[MAXBUFFER]; /* Output Buffer */
ssize_t bytes; /* Used Buffer length */
int fd; /* Filedescriptor */
int res; /* Result from write() */
char buffer[MAX_STRBUF_SIZE]; /* Output Buffer */
ssize_t bytes; /* Used Buffer length */
int fd; /* Filedescriptor */
int res; /* Result from write() */
fprintf(stderr, "Unexport GPIO pin %d\n", pin);
close(gpioFds[pin]);
fd = open("/sys/class/gpio/unexport", O_WRONLY);
if (fd < 0)
@ -655,7 +670,7 @@ int gpio_unexport(int pin)
return(-1);
}
bytes = snprintf(buffer, MAXBUFFER, "%d", pin);
bytes = snprintf(buffer, MAX_STRBUF_SIZE, "%d", pin);
res = write(fd, buffer, bytes);
if (res < 0)
@ -675,11 +690,13 @@ int gpio_unexport(int pin)
*/
int gpio_direction(int pin, int dir)
{
char path[MAXBUFFER]; /* Buffer for path */
int fd; /* Filedescriptor */
int res; /* Result from write() */
char path[MAX_STRBUF_SIZE]; /* Buffer for path */
int fd; /* Filedescriptor */
int res; /* Result from write() */
snprintf(path, MAXBUFFER, "/sys/class/gpio/gpio%d/direction", pin);
fprintf(stderr, "Set GPIO direction for pin %d to %s\n", pin, (dir==INPUT) ? "INPUT":"OUTPUT");
snprintf(path, MAX_STRBUF_SIZE, "/sys/class/gpio/gpio%d/direction", pin);
fd = open(path, O_WRONLY);
if (fd < 0)
{
@ -709,26 +726,26 @@ int gpio_direction(int pin, int dir)
*/
int gpio_read(int pin)
{
char path[MAXBUFFER]; /* Buffer for path */
int fd; /* Filedescriptor */
char result[MAXBUFFER] = {0}; /* Buffer for result */
char path[MAX_STRBUF_SIZE]; /* Buffer for path */
char c;
snprintf(path, MAXBUFFER, "/sys/class/gpio/gpio%d/value", pin);
fd = open(path, O_RDONLY);
if (fd < 0)
snprintf(path, MAX_STRBUF_SIZE, "/sys/class/gpio/gpio%d/value", pin);
if (gpioFds[pin] < 0)
gpioFds[pin] = open(path, O_RDWR);
if (gpioFds[pin] < 0)
{
perror("Could not read from GPIO(open)!\n");
return(-1);
}
if (read(fd, result, 3) < 0)
lseek(gpioFds [pin], 0L, SEEK_SET) ;
if (read(gpioFds[pin], &c, 1) < 0)
{
perror("Could not read from GPIO(read)!\n");
return(-1);
}
close(fd);
return(atoi(result));
return (c == '0') ? LOW : HIGH;
}
/* Write to GPIO pin
@ -736,14 +753,14 @@ int gpio_read(int pin)
*/
int gpio_write(int pin, int value)
{
char path[MAXBUFFER]; /* Buffer for path */
int fd; /* Filedescriptor */
int res; /* Result from write()*/
char path[MAX_STRBUF_SIZE]; /* Buffer for path */
int res; /* Result from write()*/
snprintf(path, MAXBUFFER, "/sys/class/gpio/gpio%d/value", pin);
fd = open(path, O_WRONLY);
snprintf(path, MAX_STRBUF_SIZE, "/sys/class/gpio/gpio%d/value", pin);
if (gpioFds[pin] < 0)
gpioFds[pin] = open(path, O_RDWR);
if (fd < 0)
if (gpioFds[pin] < 0)
{
perror("Could not write to GPIO(open)!\n");
return(-1);
@ -751,8 +768,8 @@ int gpio_write(int pin, int value)
switch (value)
{
case LOW : res = write(fd,"0",1); break;
case HIGH: res = write(fd,"1",1); break;
case LOW : res = write(gpioFds[pin], "0\n", 2); break;
case HIGH: res = write(gpioFds[pin], "1\n", 2); break;
default: res = -1; break;
}
@ -762,7 +779,6 @@ int gpio_write(int pin, int value)
return(-1);
}
close(fd);
return(0);
}
@ -773,10 +789,10 @@ int gpio_write(int pin, int value)
*/
int gpio_edge(unsigned int pin, char edge)
{
char path[MAXBUFFER]; /* Buffer for path */
int fd; /* Filedescriptor */
char path[MAX_STRBUF_SIZE]; /* Buffer for path */
int fd; /* Filedescriptor */
snprintf(path, MAXBUFFER, "/sys/class/gpio/gpio%d/edge", pin);
snprintf(path, MAX_STRBUF_SIZE, "/sys/class/gpio/gpio%d/edge", pin);
fd = open(path, O_WRONLY | O_NONBLOCK );
if (fd < 0)
@ -808,14 +824,14 @@ int gpio_edge(unsigned int pin, char edge)
*/
int gpio_wait(unsigned int pin, int timeout)
{
char path[MAXBUFFER]; /* Buffer for path */
int fd; /* Filedescriptor */
struct pollfd polldat[1]; /* Variable for poll() */
char buf[MAXBUFFER]; /* Read buffer */
int rc; /* Result */
char path[MAX_STRBUF_SIZE]; /* Buffer for path */
int fd; /* Filedescriptor */
struct pollfd polldat[1]; /* Variable for poll() */
char buf[MAX_STRBUF_SIZE]; /* Read buffer */
int rc; /* Result */
/* Open GPIO pin */
snprintf(path, MAXBUFFER, "/sys/class/gpio/gpio%d/value", pin);
snprintf(path, MAX_STRBUF_SIZE, "/sys/class/gpio/gpio%d/value", pin);
fd = open(path, O_RDONLY | O_NONBLOCK );
if (fd < 0)
{
@ -831,7 +847,7 @@ int gpio_wait(unsigned int pin, int timeout)
/* clear any existing detected edges before */
lseek(fd, 0, SEEK_SET);
rc = read(fd, buf, MAXBUFFER - 1);
rc = read(fd, buf, MAX_STRBUF_SIZE - 1);
rc = poll(polldat, 1, timeout);
if (rc < 0)