mirror of
https://github.com/thelsing/knx.git
synced 2025-01-02 00:06:43 +01:00
Merge pull request #43 from nanosonde/improve_rf_linux
Improve GPIO for Linux platform
This commit is contained in:
commit
f6ace390ee
@ -11,6 +11,19 @@
|
|||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.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
|
#if MEDIUM_TYPE == 5
|
||||||
KnxFacade<LinuxPlatform, Bau57B0> knx;
|
KnxFacade<LinuxPlatform, Bau57B0> knx;
|
||||||
@ -97,15 +110,39 @@ void setup()
|
|||||||
|
|
||||||
int main(int argc, char **argv)
|
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);
|
knx.platform().cmdLineArgs(argc, argv);
|
||||||
|
|
||||||
setup();
|
setup();
|
||||||
|
|
||||||
while (1)
|
while (loopActive)
|
||||||
{
|
{
|
||||||
knx.loop();
|
knx.loop();
|
||||||
if(knx.configured())
|
if(knx.configured())
|
||||||
appLoop();
|
appLoop();
|
||||||
delayMicroseconds(100);
|
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");
|
||||||
}
|
}
|
||||||
|
@ -602,7 +602,16 @@ void LinuxPlatform::cmdLineArgs(int argc, char** argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Buffer size for string operations (e.g. snprintf())*/
|
/* 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
|
/* Activate GPIO-Pin
|
||||||
* Write GPIO pin number to /sys/class/gpio/export
|
* 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)
|
int gpio_export(int pin)
|
||||||
{
|
{
|
||||||
char buffer[MAXBUFFER]; /* Output Buffer */
|
char buffer[MAX_STRBUF_SIZE]; /* Output Buffer */
|
||||||
ssize_t bytes; /* Used Buffer length */
|
ssize_t bytes; /* Used Buffer length */
|
||||||
int fd; /* Filedescriptor */
|
int fd; /* Filedescriptor */
|
||||||
int res; /* Result from write() */
|
int res; /* Result from write() */
|
||||||
|
|
||||||
|
fprintf(stderr, "Export GPIO pin %d\n", pin);
|
||||||
|
|
||||||
fd = open("/sys/class/gpio/export", O_WRONLY);
|
fd = open("/sys/class/gpio/export", O_WRONLY);
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
@ -622,7 +633,7 @@ int gpio_export(int pin)
|
|||||||
return(-1);
|
return(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
bytes = snprintf(buffer, MAXBUFFER, "%d", pin);
|
bytes = snprintf(buffer, MAX_STRBUF_SIZE, "%d", pin);
|
||||||
res = write(fd, buffer, bytes);
|
res = write(fd, buffer, bytes);
|
||||||
|
|
||||||
if (res < 0)
|
if (res < 0)
|
||||||
@ -643,10 +654,14 @@ int gpio_export(int pin)
|
|||||||
*/
|
*/
|
||||||
int gpio_unexport(int pin)
|
int gpio_unexport(int pin)
|
||||||
{
|
{
|
||||||
char buffer[MAXBUFFER]; /* Output Buffer */
|
char buffer[MAX_STRBUF_SIZE]; /* Output Buffer */
|
||||||
ssize_t bytes; /* Used Buffer length */
|
ssize_t bytes; /* Used Buffer length */
|
||||||
int fd; /* Filedescriptor */
|
int fd; /* Filedescriptor */
|
||||||
int res; /* Result from write() */
|
int res; /* Result from write() */
|
||||||
|
|
||||||
|
fprintf(stderr, "Unexport GPIO pin %d\n", pin);
|
||||||
|
|
||||||
|
close(gpioFds[pin]);
|
||||||
|
|
||||||
fd = open("/sys/class/gpio/unexport", O_WRONLY);
|
fd = open("/sys/class/gpio/unexport", O_WRONLY);
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
@ -655,7 +670,7 @@ int gpio_unexport(int pin)
|
|||||||
return(-1);
|
return(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
bytes = snprintf(buffer, MAXBUFFER, "%d", pin);
|
bytes = snprintf(buffer, MAX_STRBUF_SIZE, "%d", pin);
|
||||||
res = write(fd, buffer, bytes);
|
res = write(fd, buffer, bytes);
|
||||||
|
|
||||||
if (res < 0)
|
if (res < 0)
|
||||||
@ -675,11 +690,13 @@ int gpio_unexport(int pin)
|
|||||||
*/
|
*/
|
||||||
int gpio_direction(int pin, int dir)
|
int gpio_direction(int pin, int dir)
|
||||||
{
|
{
|
||||||
char path[MAXBUFFER]; /* Buffer for path */
|
char path[MAX_STRBUF_SIZE]; /* Buffer for path */
|
||||||
int fd; /* Filedescriptor */
|
int fd; /* Filedescriptor */
|
||||||
int res; /* Result from write() */
|
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);
|
fd = open(path, O_WRONLY);
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
{
|
{
|
||||||
@ -709,26 +726,26 @@ int gpio_direction(int pin, int dir)
|
|||||||
*/
|
*/
|
||||||
int gpio_read(int pin)
|
int gpio_read(int pin)
|
||||||
{
|
{
|
||||||
char path[MAXBUFFER]; /* Buffer for path */
|
char path[MAX_STRBUF_SIZE]; /* Buffer for path */
|
||||||
int fd; /* Filedescriptor */
|
char c;
|
||||||
char result[MAXBUFFER] = {0}; /* Buffer for result */
|
|
||||||
|
|
||||||
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);
|
if (gpioFds[pin] < 0)
|
||||||
if (fd < 0)
|
gpioFds[pin] = open(path, O_RDWR);
|
||||||
|
if (gpioFds[pin] < 0)
|
||||||
{
|
{
|
||||||
perror("Could not read from GPIO(open)!\n");
|
perror("Could not read from GPIO(open)!\n");
|
||||||
return(-1);
|
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");
|
perror("Could not read from GPIO(read)!\n");
|
||||||
return(-1);
|
return(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
close(fd);
|
return (c == '0') ? LOW : HIGH;
|
||||||
return(atoi(result));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Write to GPIO pin
|
/* Write to GPIO pin
|
||||||
@ -736,14 +753,14 @@ int gpio_read(int pin)
|
|||||||
*/
|
*/
|
||||||
int gpio_write(int pin, int value)
|
int gpio_write(int pin, int value)
|
||||||
{
|
{
|
||||||
char path[MAXBUFFER]; /* Buffer for path */
|
char path[MAX_STRBUF_SIZE]; /* Buffer for path */
|
||||||
int fd; /* Filedescriptor */
|
int res; /* Result from write()*/
|
||||||
int res; /* Result from write()*/
|
|
||||||
|
|
||||||
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_WRONLY);
|
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");
|
perror("Could not write to GPIO(open)!\n");
|
||||||
return(-1);
|
return(-1);
|
||||||
@ -751,8 +768,8 @@ int gpio_write(int pin, int value)
|
|||||||
|
|
||||||
switch (value)
|
switch (value)
|
||||||
{
|
{
|
||||||
case LOW : res = write(fd,"0",1); break;
|
case LOW : res = write(gpioFds[pin], "0\n", 2); break;
|
||||||
case HIGH: res = write(fd,"1",1); break;
|
case HIGH: res = write(gpioFds[pin], "1\n", 2); break;
|
||||||
default: res = -1; break;
|
default: res = -1; break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -762,7 +779,6 @@ int gpio_write(int pin, int value)
|
|||||||
return(-1);
|
return(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
close(fd);
|
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -773,10 +789,10 @@ int gpio_write(int pin, int value)
|
|||||||
*/
|
*/
|
||||||
int gpio_edge(unsigned int pin, char edge)
|
int gpio_edge(unsigned int pin, char edge)
|
||||||
{
|
{
|
||||||
char path[MAXBUFFER]; /* Buffer for path */
|
char path[MAX_STRBUF_SIZE]; /* Buffer for path */
|
||||||
int fd; /* Filedescriptor */
|
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 );
|
fd = open(path, O_WRONLY | O_NONBLOCK );
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
@ -808,14 +824,14 @@ int gpio_edge(unsigned int pin, char edge)
|
|||||||
*/
|
*/
|
||||||
int gpio_wait(unsigned int pin, int timeout)
|
int gpio_wait(unsigned int pin, int timeout)
|
||||||
{
|
{
|
||||||
char path[MAXBUFFER]; /* Buffer for path */
|
char path[MAX_STRBUF_SIZE]; /* Buffer for path */
|
||||||
int fd; /* Filedescriptor */
|
int fd; /* Filedescriptor */
|
||||||
struct pollfd polldat[1]; /* Variable for poll() */
|
struct pollfd polldat[1]; /* Variable for poll() */
|
||||||
char buf[MAXBUFFER]; /* Read buffer */
|
char buf[MAX_STRBUF_SIZE]; /* Read buffer */
|
||||||
int rc; /* Result */
|
int rc; /* Result */
|
||||||
|
|
||||||
/* Open GPIO pin */
|
/* 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 );
|
fd = open(path, O_RDONLY | O_NONBLOCK );
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
{
|
{
|
||||||
@ -831,7 +847,7 @@ int gpio_wait(unsigned int pin, int timeout)
|
|||||||
|
|
||||||
/* clear any existing detected edges before */
|
/* clear any existing detected edges before */
|
||||||
lseek(fd, 0, SEEK_SET);
|
lseek(fd, 0, SEEK_SET);
|
||||||
rc = read(fd, buf, MAXBUFFER - 1);
|
rc = read(fd, buf, MAX_STRBUF_SIZE - 1);
|
||||||
|
|
||||||
rc = poll(polldat, 1, timeout);
|
rc = poll(polldat, 1, timeout);
|
||||||
if (rc < 0)
|
if (rc < 0)
|
||||||
|
Loading…
Reference in New Issue
Block a user