From 6991685df277fb2d2974a8debd3e2259b4b5cf21 Mon Sep 17 00:00:00 2001 From: Bartosz Golaszewski Date: Wed, 11 Jan 2017 12:58:22 +0100 Subject: [PATCH] gpiomon: code shrink Use tools-common like other tools. Convert the program to using the simple event monitoring interface. Signed-off-by: Bartosz Golaszewski --- gpiomon.c | 156 +++++++++++++++++++++++++++--------------------------- 1 file changed, 79 insertions(+), 77 deletions(-) diff --git a/gpiomon.c b/gpiomon.c index d9dbcfa..9b40472 100644 --- a/gpiomon.c +++ b/gpiomon.c @@ -9,101 +9,103 @@ */ #include "gpiod.h" +#include "tools-common.h" #include #include +#include -int main(int argc, char **argv) -{ - struct gpiod_line_evreq_config config; - struct gpiod_line_event event; - struct timespec timeout; - struct gpiod_chip *chip; - struct gpiod_line *line; - unsigned int offset; - char *device, *end; - int status; +static const struct option longopts[] = { + { "help", no_argument, NULL, 'h' }, + { "active-low", no_argument, NULL, 'l' }, + { 0 }, +}; - if (argc < 2) { - fprintf(stderr, "%s: gpiochip must be specified\n", argv[0]); - return EXIT_FAILURE; - } +static const char *const shortopts = "hl"; - if (argc < 3) { - fprintf(stderr, - "%s: gpio line offset must be specified\n", argv[0]); - return EXIT_FAILURE; - } +static void print_help(void) +{ + printf("Usage: %s [CHIP NAME/NUMBER] [LINE OFFSET] \n", + get_progname()); + printf("Wait for events on a GPIO line\n"); + printf("Options:\n"); + printf(" -h, --help:\t\tdisplay this message and exit\n"); + printf(" -l, --active-low:\tset the line active state to low\n"); +} - device = argv[1]; - /* FIXME Handle negative numbers. */ - offset = strtoul(argv[2], &end, 10); - if (*end != '\0') { - fprintf(stderr, - "%s: invalid GPIO offset: %s\n", argv[0], argv[2]); - return EXIT_FAILURE; +static int event_callback(int type, const struct timespec *ts, + void *data UNUSED) +{ + const char *evname = NULL; + + switch (type) { + case GPIOD_EVENT_CB_RISING_EDGE: + evname = " RISING EDGE"; + break; + case GPIOD_EVENT_CB_FALLING_EDGE: + evname = "FALLING_EDGE"; + break; + default: + break; } - chip = gpiod_chip_open_lookup(device); - if (!chip) { - fprintf(stderr, - "%s: error accessing gpiochip %s: %s\n", - argv[0], device, gpiod_strerror(gpiod_errno())); - return EXIT_FAILURE; - } + if (evname) + printf("GPIO EVENT: %s [%8ld.%09ld]\n", + evname, ts->tv_sec, ts->tv_nsec); - line = gpiod_chip_get_line(chip, offset); - if (!line) { - fprintf(stderr, - "%s: error accessing line %u: %s\n", - argv[0], offset, gpiod_strerror(gpiod_errno())); - return EXIT_FAILURE; - } + return GPIOD_EVENT_CB_OK; +} - memset(&config, 0, sizeof(config)); - config.consumer = "gpiomon"; - config.event_type = GPIOD_EVENT_BOTH_EDGES; +int main(int argc, char **argv) +{ + bool active_low = false; + struct timespec timeout; + int optc, opti, status; + unsigned int offset; + char *device, *end; - status = gpiod_line_event_request(line, &config); - if (status < 0) { - fprintf(stderr, - "%s: error requesting line event: %s\n", - argv[0], gpiod_strerror(gpiod_errno())); - return EXIT_FAILURE; - } + set_progname(argv[0]); for (;;) { - timeout.tv_sec = 1; - timeout.tv_nsec = 0; - - status = gpiod_line_event_wait(line, &timeout); - if (status < 0) { - fprintf(stderr, - "%s: error waiting for line event: %s\n", - argv[0], gpiod_strerror(gpiod_errno())); - return EXIT_FAILURE; - } else if (status == 0) { - continue; + optc = getopt_long(argc, argv, shortopts, longopts, &opti); + if (optc < 0) + break; + + switch (optc) { + case 'h': + print_help(); + return EXIT_SUCCESS; + case 'l': + active_low = true; + break; + case '?': + die("try %s --help", get_progname()); + default: + abort(); } + } - status = gpiod_line_event_read(line, &event); - if (status < 0) { - fprintf(stderr, - "%s: error reading the line event: %s\n", - argv[0], gpiod_strerror(gpiod_errno())); - return EXIT_FAILURE; - } + argc -= optind; + argv += optind; - printf("GPIO EVENT: %s [%ld.%ld]\n", - event.event_type == GPIOD_EVENT_FALLING_EDGE - ? "FALLING EDGE" - : "RAISING EDGE", - event.ts.tv_sec, event.ts.tv_nsec); - } + if (argc < 1) + die("gpiochip must be specified"); + + if (argc < 2) + die("gpio line offset must be specified"); + + device = argv[0]; + offset = strtoul(argv[1], &end, 10); + if (*end != '\0') + die("invalid GPIO offset: %s", argv[1]); + + timeout.tv_sec = 0; + timeout.tv_nsec = 500000000; - gpiod_line_event_release(line); - gpiod_line_release(line); - gpiod_chip_close(chip); + status = gpiod_simple_event_loop(device, offset, active_low, + &timeout, event_callback, NULL); + if (status < 0) + die_perror("error waiting for events"); return EXIT_SUCCESS; } -- 2.30.2