From: Bartosz Golaszewski Date: Thu, 5 Jan 2017 14:22:41 +0000 (+0100) Subject: gpiomon: new tool X-Git-Url: http://git.maquefel.me/?a=commitdiff_plain;h=152a26d34ddf8824a0a00449b24c454e0175250c;p=qemu-gpiodev%2Flibgpiod.git gpiomon: new tool Implement a simple GPIO event monitor. Signed-off-by: Bartosz Golaszewski --- diff --git a/.gitignore b/.gitignore index 060ee04..2879c59 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ gpiodetect gpioinfo gpioget gpioset +gpiomon *.o *.lo doc diff --git a/Makefile.am b/Makefile.am index 585dac4..d47b230 100644 --- a/Makefile.am +++ b/Makefile.am @@ -37,6 +37,10 @@ gpioset_SOURCES = gpioset.c gpioset_LDFLAGS = -lgpiod gpioset_DEPENDENCIES = libgpiod.la +gpiomon_SOURCES = gpiomon.c +gpiomon_LDFLAGS = -lgpiod +gpiomon_DEPENDENCIES = libgpiod.la + doc: doxygen .PHONY: doc diff --git a/gpiomon.c b/gpiomon.c new file mode 100644 index 0000000..1550e25 --- /dev/null +++ b/gpiomon.c @@ -0,0 +1,101 @@ +/* + * Monitor events on a GPIO line. + * + * Copyright (C) 2017 Bartosz Golaszewski + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + */ + +#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; + + if (argc < 2) { + fprintf(stderr, "%s: gpiochip must be specified\n", argv[0]); + return EXIT_FAILURE; + } + + if (argc < 3) { + fprintf(stderr, + "%s: gpio line offset must be specified\n", argv[0]); + return EXIT_FAILURE; + } + + 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; + } + + 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; + } + + 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; + } + + memset(&config, 0, sizeof(config)); + config.consumer = "gpiomon"; + config.event_type = GPIOD_EVENT_BOTH_EDGES; + + 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; + } + + for (;;) { + timeout.tv_sec = 1; + timeout.tv_nsec = 0; + + status = gpiod_line_event_wait(line, &timeout, &event); + 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; + } + + 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); + } + + gpiod_line_event_release(line); + gpiod_line_release(line); + gpiod_chip_close(chip); + + return EXIT_SUCCESS; +}