Message ID | 1461660866-18683-2-git-send-email-linus.walleij@linaro.org |
---|---|
State | Superseded |
Headers | show |
On Wed, Apr 27, 2016 at 6:00 PM, Michael Welling <mwelling@ieee.org> wrote: > On Tue, Apr 26, 2016 at 10:54:26AM +0200, Linus Walleij wrote: >> The gpio-hammer is used from userspace as an example of how >> to retrieve a GPIO handle for one or several GPIO lines and >> hammer the outputs from low to high and back again. It will >> pulse the selected lines once per second for a specified >> number of times or indefinitely if no loop count is >> supplied. >> >> Example output: >> $ gpio-hammer -n gpiochip0 -o5 -o6 -o7 >> Hammer lines [5, 6, 7] on gpiochip0, initial states: [1, 1, 1] >> [-] [5: 0, 6: 0, 7: 0] >> >> Signed-off-by: Linus Walleij <linus.walleij@linaro.org> > > Tested-by: Michael Welling <mwelling@ieee.org> Thanks! :) > Below is the output from my target. You can now get rid of all the "unnamed" in the first column by supplying the line/rail names in gpio-line-names = "A", "B" ...; in the GPIO controller node in the device tree for the platform, if it uses device tree too boot. > You will notice that a kernel warning is > spewed out if I use the mcp23s08. > The processor GPIOs work fine as verified by blinking LEDs. > > root@som3517-som200:~# ./lsgpio > GPIO chip: gpiochip4, "mcp23s08", 8 GPIO lines > line 0: unnamed unused > line 1: unnamed unused > line 2: unnamed unused > line 3: unnamed unused > line 4: unnamed unused > line 5: unnamed unused > line 6: unnamed unused > line 7: unnamed unused > root@som3517-som200:~# ./gpio-hammer -n gpiochip4 -o0 > [ 187.511606] ------------[ cut here ]------------ > [ 187.516949] WARNING: CPU: 0 PID: 830 at /home/michael/projects/linux/linux-git/drivers/gpio/gpiolib.c:1907 gpiod_get_value+0x60/0xa4 Ah that's right, I have to use gpiod_get_value_cansleep(). Will fix that. Yours, Linus Walleij -- To unsubscribe from this list: send the line "unsubscribe linux-gpio" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Wed, Jun 1, 2016 at 5:43 AM, Michael Welling <mwelling@ieee.org> wrote:
> Did you ever find a solution for the exhausted char dev problem?
Not really. It seems it turned up that all systems that bugged were randomly
generated QEMU models, not real systems.
They were also really doing far out stuff already, overwriting existing chardevs
all over the place, which can be seen in logs after commit
49db08c35887 "chrdev: emit a warning when we go below dynamic major range"
which I got merged.
I'm now working on an event ABI so we get feature complete and also surpass
the old sysfs.
Yours,
Linus Walleij
--
To unsubscribe from this list: send the line "unsubscribe linux-gpio" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
On Wed, Jun 1, 2016 at 8:09 PM, Michael Welling <mwelling@ieee.org> wrote: > Is there a way to name a group of GPIOs? Do you mean from the producer side or the consumer side? There is gpio-line-names in DT for the producer side. From the consumer side the same consumer name will be used on all lines if more than one is selected, which I think makes sense. (It's just a label after all.) > It seems you are passing around a byte of data for each GPIO state. > Is there a reason why the bits couldn't bit masked into single variable > given the max number of handles is 64? Sorry not following, I guess you need to post me some part of the patch or so... Yours, Linus Walleij -- To unsubscribe from this list: send the line "unsubscribe linux-gpio" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On Thu, Jun 2, 2016 at 4:59 PM, Michael Welling <mwelling@ieee.org> wrote: > On Wed, Jun 01, 2016 at 11:40:04PM +0200, Linus Walleij wrote: >> On Wed, Jun 1, 2016 at 8:09 PM, Michael Welling <mwelling@ieee.org> wrote: >> >> > Is there a way to name a group of GPIOs? >> >> Do you mean from the producer side or the consumer side? > > Producer side is what I am thinking. > >> There is gpio-line-names in DT for the producer side. >> > The gpio-line-names are naming individual GPIO on a controller. > I am looking to take a set of GPIOs and name them as a group and > be able to access them by that name. Either individually or > simultaneously. There is no such mechanism currently, all lines are individual resources. >> Sorry not following, I guess you need to post me some part of >> the patch or so... > > + fprintf(stdout, "] on %s, initial states: [", device_name); > + for (i = 0; i < nlines; i++) { > + fprintf(stdout, "%d", data.values[i]); > > data.values[i]; > > Each bit is stored in a byte. Yeah the userspace interface is wasteful in that sense. It's a trade-off between storage and simplicity and I had to choose something. If I try to bitstuff the bits then I need to add another ABI to describe how the bits are stuffed in the words. So I get complexity somewhere else instead. Yours, Linus Walleij -- To unsubscribe from this list: send the line "unsubscribe linux-gpio" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/tools/gpio/Makefile b/tools/gpio/Makefile index c155d6bc47a7..aea23949054e 100644 --- a/tools/gpio/Makefile +++ b/tools/gpio/Makefile @@ -1,12 +1,13 @@ CC = $(CROSS_COMPILE)gcc CFLAGS += -O2 -Wall -g -D_GNU_SOURCE -all: lsgpio +all: lsgpio gpio-hammer lsgpio: lsgpio.o gpio-utils.o +gpio-hammer: gpio-hammer.o gpio-utils.o %.o: %.c gpio-utils.h .PHONY: clean clean: - rm -f *.o lsgpio + rm -f *.o lsgpio gpio-hammer diff --git a/tools/gpio/gpio-hammer.c b/tools/gpio/gpio-hammer.c new file mode 100644 index 000000000000..37b3f141053d --- /dev/null +++ b/tools/gpio/gpio-hammer.c @@ -0,0 +1,189 @@ +/* + * gpio-hammer - example swiss army knife to shake GPIO lines on a system + * + * Copyright (C) 2016 Linus Walleij + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + * + * Usage: + * gpio-hammer -n <device-name> -o <offset1> -o <offset2> + */ + +#include <unistd.h> +#include <stdlib.h> +#include <stdbool.h> +#include <stdio.h> +#include <dirent.h> +#include <errno.h> +#include <string.h> +#include <poll.h> +#include <fcntl.h> +#include <getopt.h> +#include <sys/ioctl.h> +#include <linux/gpio.h> + +int hammer_device(const char *device_name, unsigned int *lines, int nlines, + unsigned int loops) +{ + struct gpiohandle_request req; + struct gpiohandle_data data; + char *chrdev_name; + char swirr[] = "-\\|/"; + int fd; + int ret; + int i, j; + unsigned int iteration = 0; + + ret = asprintf(&chrdev_name, "/dev/%s", device_name); + if (ret < 0) + return -ENOMEM; + + fd = open(chrdev_name, 0); + if (fd == -1) { + ret = -errno; + fprintf(stderr, "Failed to open %s\n", chrdev_name); + goto exit_close_error; + } + + /* Request lines as output */ + for (i = 0; i < nlines; i++) + req.lineoffsets[i] = lines[i]; + req.flags = GPIOHANDLE_REQUEST_OUTPUT; /* Request as output */ + strcpy(req.consumer_label, "gpio-hammer"); + req.lines = nlines; + ret = ioctl(fd, GPIO_GET_LINEHANDLE_IOCTL, &req); + if (ret == -1) { + ret = -errno; + fprintf(stderr, "Failed to issue GET LINEHANDLE " + "IOCTL (%d)\n", + ret); + goto exit_close_error; + } + + /* Read initial states */ + ret = ioctl(req.fd, GPIOHANDLE_GET_LINE_VALUES_IOCTL, &data); + if (ret == -1) { + ret = -errno; + fprintf(stderr, "Failed to issue GPIOHANDLE GET LINE " + "VALUES IOCTL (%d)\n", + ret); + goto exit_close_error; + } + fprintf(stdout, "Hammer lines ["); + for (i = 0; i < nlines; i++) { + fprintf(stdout, "%d", lines[i]); + if (i != (nlines - 1)) + fprintf(stdout, ", "); + } + fprintf(stdout, "] on %s, initial states: [", device_name); + for (i = 0; i < nlines; i++) { + fprintf(stdout, "%d", data.values[i]); + if (i != (nlines - 1)) + fprintf(stdout, ", "); + } + fprintf(stdout, "]\n"); + + /* Hammertime! */ + j = 0; + while (1) { + /* Invert all lines so we blink */ + for (i = 0; i < nlines; i++) + data.values[i] = !data.values[i]; + + ret = ioctl(req.fd, GPIOHANDLE_SET_LINE_VALUES_IOCTL, &data); + if (ret == -1) { + ret = -errno; + fprintf(stderr, "Failed to issue GPIOHANDLE SET LINE " + "VALUES IOCTL (%d)\n", + ret); + goto exit_close_error; + } + /* Re-read values to get status */ + ret = ioctl(req.fd, GPIOHANDLE_GET_LINE_VALUES_IOCTL, &data); + if (ret == -1) { + ret = -errno; + fprintf(stderr, "Failed to issue GPIOHANDLE GET LINE " + "VALUES IOCTL (%d)\n", + ret); + goto exit_close_error; + } + + fprintf(stdout, "[%c] ", swirr[j]); + j++; + if (j == sizeof(swirr)-1) + j = 0; + + fprintf(stdout, "["); + for (i = 0; i < nlines; i++) { + fprintf(stdout, "%d: %d", lines[i], data.values[i]); + if (i != (nlines - 1)) + fprintf(stdout, ", "); + } + fprintf(stdout, "]\r"); + fflush(stdout); + sleep(1); + iteration++; + if (loops && iteration == loops) + break; + } + fprintf(stdout, "\n"); + ret = 0; + +exit_close_error: + if (close(fd) == -1) + perror("Failed to close GPIO character device file"); + free(chrdev_name); + return ret; +} + +void print_usage(void) +{ + fprintf(stderr, "Usage: gpio-hammer [options]...\n" + "Hammer GPIO lines, 0->1->0->1...\n" + " -n <name> Hammer GPIOs on a named device (must be stated)\n" + " -o <n> Offset[s] to hammer, at least one, several can be stated\n" + " [-c <n>] Do <n> loops (optional, infinite loop if not stated)\n" + " -? This helptext\n" + "\n" + "Example:\n" + "gpio-hammer -n gpiochip0 -o 4\n" + ); +} + +int main(int argc, char **argv) +{ + const char *device_name = NULL; + unsigned int lines[GPIOHANDLES_MAX]; + unsigned int loops = 0; + int nlines; + int c; + int i; + + i = 0; + while ((c = getopt(argc, argv, "c:n:o:?")) != -1) { + switch (c) { + case 'c': + loops = strtoul(optarg, NULL, 10); + break; + case 'n': + device_name = optarg; + break; + case 'o': + lines[i] = strtoul(optarg, NULL, 10); + i++; + break; + case '?': + print_usage(); + return -1; + } + } + nlines = i; + + if (!device_name || !nlines) { + print_usage(); + return -1; + } + return hammer_device(device_name, lines, nlines, loops); +}
The gpio-hammer is used from userspace as an example of how to retrieve a GPIO handle for one or several GPIO lines and hammer the outputs from low to high and back again. It will pulse the selected lines once per second for a specified number of times or indefinitely if no loop count is supplied. Example output: $ gpio-hammer -n gpiochip0 -o5 -o6 -o7 Hammer lines [5, 6, 7] on gpiochip0, initial states: [1, 1, 1] [-] [5: 0, 6: 0, 7: 0] Signed-off-by: Linus Walleij <linus.walleij@linaro.org> --- tools/gpio/Makefile | 5 +- tools/gpio/gpio-hammer.c | 189 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 192 insertions(+), 2 deletions(-) create mode 100644 tools/gpio/gpio-hammer.c -- 2.4.11 -- To unsubscribe from this list: send the line "unsubscribe linux-gpio" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html