gpio  1.4.2
General Purpose I/O Package
gpioread.cxx
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////////////
2 //
3 // Package: gpio
4 //
5 // Program: gpioread
6 //
7 // File: gpioread.cxx
8 //
9 /*! \file
10  *
11  * $LastChangedDate: 2015-04-09 15:03:13 -0600 (Thu, 09 Apr 2015) $
12  * $Rev: 3916 $
13  *
14  * \brief Create GPIO exported interface.
15  *
16  * \author Robin Knight (robin.knight@roadnarrows.com)
17  *
18  * \copyright
19  * \h_copy 2015-2017. RoadNarrows LLC.\n
20  * http://www.roadnarrows.com\n
21  * All Rights Reserved
22  */
23 /*
24  * @EulaBegin@
25  * @EulaEnd@
26  */
27 ////////////////////////////////////////////////////////////////////////////////
28 
29 #include <sys/types.h>
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <stdarg.h>
33 #include <unistd.h>
34 #include <time.h>
35 
36 #include <string>
37 
38 #include "rnr/rnrconfig.h"
39 #include "rnr/log.h"
40 #include "rnr/opts.h"
41 #include "rnr/pkg.h"
42 
43 #include "rnr/gpio.h"
44 
45 #include "version.h"
46 
47 using namespace std;
48 
49 /*!
50  * \ingroup cmds
51  * \defgroup gpioread gpioread
52  * \{
53  */
54 
55 #define APP_EC_OK 0 ///< success exit code
56 #define APP_EC_ARGS 2 ///< command-line options/arguments error exit code
57 #define APP_EC_EXEC 4 ///< execution exit code
58 
59 static char *Argv0; ///< the command
60 static char *OptsMethod = (char *)"sysfs"; ///< system file system
61 static int OptsCount = 1; ///< number of reads
62 static double OptsInterval = 1.0; ///< read interval in seconds
63 static bool_t OptsVerbose = false; ///< permissions
64 
65 static int ArgsGpio; ///< gpio number
66 
67 /*!
68  * \brief Program information.
69  */
70 static OptsPgmInfo_T PgmInfo =
71 {
72  // usage_args
73  "<gpio>",
74 
75  // synopsis
76  "Read GPIO pin value.",
77 
78  // long_desc =
79  "The %P command reads the current GPIO pin value (0 or 1) for the specified "
80  "GPIO exported number.",
81 
82  // diagnostics
83  NULL
84 };
85 
86 /*!
87  * \brief Command line options information.
88  */
89 static OptsInfo_T OptsInfo[] =
90 {
91  // -c, --count
92  {
93  "count", // long_opt
94  'c', // short_opt
95  required_argument, // has_arg
96  true, // has_default
97  &OptsCount, // opt_addr
98  OptsCvtArgInt, // fn_cvt
99  OptsFmtInt, // fn_fmt
100  "<count>", // arg_name
101  // opt desc
102  "Number of times to read the GPIO pin. A zero value means forever."
103  },
104 
105  // -i, --interval
106  {
107  "interval", // long_opt
108  'i', // short_opt
109  required_argument, // has_arg
110  true, // has_default
111  &OptsInterval, // opt_addr
112  OptsCvtArgFloat, // fn_cvt
113  OptsFmtFloat, // fn_fmt
114  "<time>", // arg_name
115  // opt desc
116  "Wait interval seconds between reads specified as a floating-point number."
117  },
118 
119 #ifdef MMAP_GPIO
120  // -m, --method
121  {
122  "method", // long_opt
123  'm', // short_opt
124  required_argument, // has_arg
125  true, // has_default
126  &OptsMethod, // opt_addr
127  OptsCvtArgStr, // fn_cvt
128  OptsFmtStr, // fn_fmt
129  "<method>", // arg_name
130  // opt desc
131  "GPIO access method. One of: sysfs mmap."
132  },
133 #endif // MMAP_GPIO
134 
135  // -v, --verbose
136  {
137  "verbose", // long_opt
138  'v', // short_opt
139  no_argument, // has_arg
140  true, // has_default
141  &OptsVerbose, // opt_addr
142  OptsCvtArgBool, // fn_cvt
143  OptsFmtBool, // fn_fmt
144  NULL, // arg_name
145  // opt desc
146  "Print read value(s) in verbose mode."
147  },
148 
149  {NULL, }
150 };
151 
152 static int strToInt(const string &str, int &val)
153 {
154  long long int val1; // must use 64-bit for arm 32-bit compilers
155 
156  if( sscanf(str.c_str(), "%lli", &val1) != 1 )
157  {
158  return RC_ERROR;
159  }
160 
161  val = (int)val1;
162 
163  return OK;
164 }
165 
166 static void printValue(int val)
167 {
168  struct timespec tsNow;
169 
170  if( OptsVerbose )
171  {
172  clock_gettime(CLOCK_REALTIME, &tsNow);
173  printf("[%ld.%09ld] gpio %d = ", tsNow.tv_sec, tsNow.tv_nsec, ArgsGpio);
174  }
175 
176  printf("%d\n", val);
177 }
178 
179 /*!
180  * \brief Main initialization.
181  *
182  * \param argc Command-line argument count.
183  * \param argv Command-line argument list.
184  *
185  * \par Exits:
186  * Program terminates on conversion error.
187  */
188 static void mainInit(int argc, char *argv[])
189 {
190  // name of this process
191  Argv0 = basename(argv[0]);
192 
193  // parse input options
194  argv = OptsGet(Argv0, &PkgInfo, &PgmInfo, OptsInfo, true, &argc, argv);
195 
196  if( OptsCount < 0 )
197  {
198  OptsCount = -OptsCount;
199  }
200 
201  if( OptsInterval < 0.0 )
202  {
204  }
205 
206  if( argc == 0 )
207  {
208  fprintf(stderr, "%s: No GPIO pin number <gpio> specified.\n", Argv0);
209  fprintf(stderr, "Try '%s --help' for more information.\n", Argv0);
210  exit(APP_EC_ARGS);
211  }
212 
213  else if( strToInt(argv[0], ArgsGpio) < 0 )
214  {
215  fprintf(stderr, "%s: '%s': Bad GPIO number.\n", Argv0, argv[0]);
216  fprintf(stderr, "Try '%s --help' for more information.\n", Argv0);
217  exit(APP_EC_ARGS);
218  }
219 }
220 
221 /*!
222  * \brief Read GPIO value(s).
223  *
224  * Method: sysfs
225  *
226  * \return Application exit code.
227  */
228 static int sysfsRead()
229 {
230  int fd;
231  bool bForever;
232  int nReads;
233  int val;
234  uint_t usec;
235 
236  if( (fd = gpioOpen(ArgsGpio)) < 0 )
237  {
238  return APP_EC_EXEC;
239  }
240 
241  bForever = OptsCount == 0? true: false;
242  nReads = 0;
243  usec = (uint_t)(OptsInterval * 1000000);
244 
245  while( bForever || (nReads < OptsCount) )
246  {
247  if( (nReads > 0) && (usec > 0) )
248  {
249  usleep(usec);
250  }
251 
252  if( (val = gpioQuickRead(fd)) < 0 )
253  {
254  gpioClose(fd);
255  return APP_EC_EXEC;
256  }
257 
258  printValue(val);
259 
260  ++nReads;
261  }
262 
263  gpioClose(fd);
264 
265  return APP_EC_OK;
266 }
267 
268 #ifdef MMAP_GPIO
269 /*!
270  * \brief Read GPIO value(s).
271  *
272  * Method: mmap
273  *
274  * \return Application exit code.
275  */
276 static int mmapRead()
277 {
278  bool bForever;
279  int nReads;
280  int val;
281  uint_t usec;
282 
283  if( mmapGpioMap() < 0 )
284  {
285  return APP_EC_EXEC;
286  }
287 
288  bForever = OptsCount == 0? true: false;
289  nReads = 0;
290  usec = (uint_t)(OptsInterval * 1000000);
291 
292  while( bForever || (nReads < OptsCount) )
293  {
294  if( (nReads > 0) && (usec > 0) )
295  {
296  usleep(usec);
297  }
298 
299  if( (val = mmapGpioRead(ArgsGpio)) < 0 )
300  {
301  mmapGpioUnmap();
302  return APP_EC_EXEC;
303  }
304 
305  printValue(val);
306 
307  ++nReads;
308  }
309 
310  mmapGpioUnmap();
311 
312  return APP_EC_OK;
313 }
314 #endif // MMAP_GPIO
315 
316 /*!
317  * \brief Main.
318  *
319  * \param argc Command-line argument count.
320  * \param argv Command-line argument list.
321  *
322  * \return Returns 0 on succes, non-zero on failure.
323  */
324 int main(int argc, char* argv[])
325 {
326  int ec;
327 
328  mainInit(argc, argv);
329 
330  if( !strcmp(OptsMethod, "sysfs") )
331  {
332  ec = sysfsRead();
333  }
334 
335 #ifdef MMAP_GPIO
336  else if( !strcmp(OptsMethod, "mmap") )
337  {
338  ec = mmapRead();
339  }
340 #endif // MMAP_GPIO
341 
342  else
343  {
344  fprintf(stderr,"%s: Unknown GPIO access method.", OptsMethod);
345  ec = APP_EC_ARGS;
346  }
347 
348  return ec;
349 }
350 
351 /*!
352  * \}
353  */
#define APP_EC_OK
success exit code
Definition: gpioread.cxx:55
int gpioOpen(int gpio)
Open GPIO pin.
Definition: gpio.c:492
static bool_t OptsVerbose
permissions
Definition: gpioread.cxx:63
static char * OptsMethod
system file system
Definition: gpioread.cxx:60
GPIO interface declarations and defines.
int gpioQuickRead(int fd)
Quick read GPIO pin&#39;s current value.
Definition: gpio.c:520
static void mainInit(int argc, char *argv[])
Main initialization.
Definition: gpioread.cxx:188
int gpioClose(int fd)
Close GPIO pin.
Definition: gpio.c:510
static const PkgInfo_T PkgInfo
Definition: version.h:45
#define APP_EC_ARGS
command-line options/arguments error exit code
Definition: gpioread.cxx:56
#define APP_EC_EXEC
execution exit code
Definition: gpioread.cxx:57
Package version information.
static OptsPgmInfo_T PgmInfo
Program information.
Definition: gpioread.cxx:70
static int ArgsGpio
gpio number
Definition: gpioread.cxx:65
static int sysfsRead()
Read GPIO value(s).
Definition: gpioread.cxx:228
static OptsInfo_T OptsInfo[]
Command line options information.
Definition: gpioread.cxx:89
static double OptsInterval
read interval in seconds
Definition: gpioread.cxx:62
static int OptsCount
number of reads
Definition: gpioread.cxx:61
static char * Argv0
the command
Definition: gpioread.cxx:59
int main(int argc, char *argv[])
Main.
Definition: gpioread.cxx:324