mirror of
				https://github.com/thelsing/knx.git
				synced 2025-10-26 10:26:25 +01:00 
			
		
		
		
	Keep GPIO value sysfs file open for reading/writing
This commit is contained in:
		
							parent
							
								
									4ef513410a
								
							
						
					
					
						commit
						15b318992d
					
				| @ -11,6 +11,16 @@ | |||||||
| #include <time.h> | #include <time.h> | ||||||
| #include <stdlib.h> | #include <stdlib.h> | ||||||
| #include <stdio.h> | #include <stdio.h> | ||||||
|  | #include <signal.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 +107,32 @@ void setup() | |||||||
| 
 | 
 | ||||||
| int main(int argc, char **argv) | int main(int argc, char **argv) | ||||||
| { | { | ||||||
|  |     printf("main() start.\n"); | ||||||
|  | 
 | ||||||
|  |     // 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,11 +619,13 @@ 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,11 +654,15 @@ 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