Created
October 26, 2022 12:40
-
-
Save m-kurbanov/775408521c436a371c3640d49808d08d to your computer and use it in GitHub Desktop.
Example for led-trigger-pattern
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdlib.h> | |
#include <fcntl.h> | |
#include <poll.h> | |
#include <unistd.h> | |
#include <string.h> | |
#include <stdbool.h> | |
#include <errno.h> | |
#include <limits.h> | |
#define ARRAY_SIZE(array) (sizeof(array) / sizeof(array[0])) | |
struct led_pattern { | |
const char *data; | |
const char *repeat; | |
}; | |
static int open_led_attr(const char *led, const char *attr, int flags) | |
{ | |
char name[PATH_MAX]; | |
int fd; | |
snprintf(name, sizeof(name), "%s/%s", led, attr); | |
fd = open(name, flags); | |
if (fd < 0) { | |
fprintf(stderr, "Can't open file '%s'. Error %s\n", | |
name, strerror(errno)); | |
return -1; | |
} | |
return fd; | |
} | |
static int write_led_attr(const char *led, | |
const char *attr, | |
const void *buf, | |
size_t size) | |
{ | |
ssize_t n; | |
int fd; | |
fd = open_led_attr(led, attr, O_WRONLY); | |
if (fd < 0) | |
return fd; | |
n = write(fd, buf, size); | |
if (n != size) { | |
fprintf(stderr, "Can't write to file '%s/%s'. Error %s\n", | |
led, attr, strerror(errno)); | |
return -EIO; | |
} | |
return 0; | |
} | |
static int enable_pattern_trigger(const char *led) | |
{ | |
return write_led_attr(led, "trigger", "pattern", sizeof("pattern") - 1); | |
} | |
static bool pattern_ended(int fd) | |
{ | |
char buf[12] = { 0 }; | |
if (read(fd, buf, sizeof(buf) - 1) < 0) { | |
perror("read error"); | |
return false; | |
} | |
return atoi(buf) == 0; | |
} | |
static int write_led_pattern(const char *led, const struct led_pattern *pattern) | |
{ | |
// clear previous pattern | |
write_led_attr(led, "pattern", "\n", 1); | |
write_led_attr(led, "repeat", pattern->repeat, strlen(pattern->repeat)); | |
write_led_attr(led, "pattern", pattern->data, strlen(pattern->data)); | |
return 0; | |
} | |
static int write_all_led_pattern(const char *leds[], | |
size_t n, | |
const struct led_pattern *pattern) | |
{ | |
size_t i; | |
for (i = 0; i < n; i++) | |
write_led_pattern(leds[i], pattern); | |
return 0; | |
} | |
static int wait_for_all_pattern(const int fds[], size_t n) | |
{ | |
struct pollfd *pfd; | |
size_t i; | |
int ret = 0; | |
pfd = calloc(n, sizeof(struct pollfd)); | |
if (!pfd) | |
return -ENOMEM; | |
while (true) { | |
size_t n_pfd = 0; | |
for (i = 0; i < n; i++) { | |
if (!pattern_ended(fds[i])) { | |
pfd[n_pfd].fd = fds[i]; | |
pfd[n_pfd].events = POLLPRI; | |
pfd[n_pfd].revents = 0; | |
n_pfd++; | |
} | |
lseek(fds[i], 0, SEEK_SET); | |
} | |
if (!n_pfd) | |
goto exit1; | |
if (poll(pfd, n_pfd, -1) == -1) { | |
perror("Failed to poll\n"); | |
ret = -EIO; | |
break; | |
} | |
} | |
exit1: | |
free(pfd); | |
return ret; | |
} | |
static const char *leds[] = { | |
"/sys/class/leds/red0", | |
"/sys/class/leds/red1", | |
"/sys/class/leds/red2", | |
"/sys/class/leds/red3", | |
"/sys/class/leds/red4", | |
}; | |
static const struct led_pattern patterns[] = { | |
{ | |
.data = "0 1000 255 2000", | |
.repeat = "1", | |
}, | |
{ | |
.data = "0 1000 0 0 255 2000 255 0", | |
.repeat = "1", | |
}, | |
}; | |
int main(int argc, char *argv[]) | |
{ | |
const size_t nleds = ARRAY_SIZE(leds); | |
const size_t npatterns = ARRAY_SIZE(patterns); | |
int fds[nleds]; | |
int ret = 1; | |
size_t i; | |
for (i = 0; i < nleds; i++) { | |
if (enable_pattern_trigger(leds[i])) | |
return 1; | |
} | |
for (i = 0; i < nleds; i++) { | |
fds[i] = open_led_attr(leds[i], "is_running", O_RDONLY); | |
if (fds[i] < 0) | |
goto exit1; | |
} | |
for (i = 0; i < npatterns; i++) { | |
write_all_led_pattern(leds, nleds, &patterns[i]); | |
wait_for_all_pattern(fds, ARRAY_SIZE(fds)); | |
} | |
ret = 0; | |
exit1: | |
for (i = 0; i < nleds && fds[i] >= 0; i++) | |
close(fds[i]); | |
return ret; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment