root/tools/gpio/gpio-hammer.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. hammer_device
  2. print_usage
  3. main

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * gpio-hammer - example swiss army knife to shake GPIO lines on a system
   4  *
   5  * Copyright (C) 2016 Linus Walleij
   6  *
   7  * Usage:
   8  *      gpio-hammer -n <device-name> -o <offset1> -o <offset2>
   9  */
  10 
  11 #include <unistd.h>
  12 #include <stdlib.h>
  13 #include <stdbool.h>
  14 #include <stdio.h>
  15 #include <dirent.h>
  16 #include <errno.h>
  17 #include <string.h>
  18 #include <poll.h>
  19 #include <fcntl.h>
  20 #include <getopt.h>
  21 #include <sys/ioctl.h>
  22 #include <linux/gpio.h>
  23 #include "gpio-utils.h"
  24 
  25 int hammer_device(const char *device_name, unsigned int *lines, int nlines,
  26                   unsigned int loops)
  27 {
  28         struct gpiohandle_data data;
  29         char swirr[] = "-\\|/";
  30         int fd;
  31         int ret;
  32         int i, j;
  33         unsigned int iteration = 0;
  34 
  35         memset(&data.values, 0, sizeof(data.values));
  36         ret = gpiotools_request_linehandle(device_name, lines, nlines,
  37                                            GPIOHANDLE_REQUEST_OUTPUT, &data,
  38                                            "gpio-hammer");
  39         if (ret < 0)
  40                 goto exit_error;
  41         else
  42                 fd = ret;
  43 
  44         ret = gpiotools_get_values(fd, &data);
  45         if (ret < 0)
  46                 goto exit_close_error;
  47 
  48         fprintf(stdout, "Hammer lines [");
  49         for (i = 0; i < nlines; i++) {
  50                 fprintf(stdout, "%d", lines[i]);
  51                 if (i != (nlines - 1))
  52                         fprintf(stdout, ", ");
  53         }
  54         fprintf(stdout, "] on %s, initial states: [", device_name);
  55         for (i = 0; i < nlines; i++) {
  56                 fprintf(stdout, "%d", data.values[i]);
  57                 if (i != (nlines - 1))
  58                         fprintf(stdout, ", ");
  59         }
  60         fprintf(stdout, "]\n");
  61 
  62         /* Hammertime! */
  63         j = 0;
  64         while (1) {
  65                 /* Invert all lines so we blink */
  66                 for (i = 0; i < nlines; i++)
  67                         data.values[i] = !data.values[i];
  68 
  69                 ret = gpiotools_set_values(fd, &data);
  70                 if (ret < 0)
  71                         goto exit_close_error;
  72 
  73                 /* Re-read values to get status */
  74                 ret = gpiotools_get_values(fd, &data);
  75                 if (ret < 0)
  76                         goto exit_close_error;
  77 
  78                 fprintf(stdout, "[%c] ", swirr[j]);
  79                 j++;
  80                 if (j == sizeof(swirr)-1)
  81                         j = 0;
  82 
  83                 fprintf(stdout, "[");
  84                 for (i = 0; i < nlines; i++) {
  85                         fprintf(stdout, "%d: %d", lines[i], data.values[i]);
  86                         if (i != (nlines - 1))
  87                                 fprintf(stdout, ", ");
  88                 }
  89                 fprintf(stdout, "]\r");
  90                 fflush(stdout);
  91                 sleep(1);
  92                 iteration++;
  93                 if (loops && iteration == loops)
  94                         break;
  95         }
  96         fprintf(stdout, "\n");
  97         ret = 0;
  98 
  99 exit_close_error:
 100         gpiotools_release_linehandle(fd);
 101 exit_error:
 102         return ret;
 103 }
 104 
 105 void print_usage(void)
 106 {
 107         fprintf(stderr, "Usage: gpio-hammer [options]...\n"
 108                 "Hammer GPIO lines, 0->1->0->1...\n"
 109                 "  -n <name>  Hammer GPIOs on a named device (must be stated)\n"
 110                 "  -o <n>     Offset[s] to hammer, at least one, several can be stated\n"
 111                 " [-c <n>]    Do <n> loops (optional, infinite loop if not stated)\n"
 112                 "  -?         This helptext\n"
 113                 "\n"
 114                 "Example:\n"
 115                 "gpio-hammer -n gpiochip0 -o 4\n"
 116         );
 117 }
 118 
 119 int main(int argc, char **argv)
 120 {
 121         const char *device_name = NULL;
 122         unsigned int lines[GPIOHANDLES_MAX];
 123         unsigned int loops = 0;
 124         int nlines;
 125         int c;
 126         int i;
 127 
 128         i = 0;
 129         while ((c = getopt(argc, argv, "c:n:o:?")) != -1) {
 130                 switch (c) {
 131                 case 'c':
 132                         loops = strtoul(optarg, NULL, 10);
 133                         break;
 134                 case 'n':
 135                         device_name = optarg;
 136                         break;
 137                 case 'o':
 138                         lines[i] = strtoul(optarg, NULL, 10);
 139                         i++;
 140                         break;
 141                 case '?':
 142                         print_usage();
 143                         return -1;
 144                 }
 145         }
 146         nlines = i;
 147 
 148         if (!device_name || !nlines) {
 149                 print_usage();
 150                 return -1;
 151         }
 152         return hammer_device(device_name, lines, nlines, loops);
 153 }

/* [<][>][^][v][top][bottom][index][help] */