gpio  1.4.2
General Purpose I/O Package
gpioprobe.cxx
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////////////
2 //
3 // Package: gpio
4 //
5 // Program: gpioprobe
6 //
7 // File: gpioprobe.cxx
8 //
9 /*! \file
10  *
11  * $LastChangedDate: 2015-04-09 15:03:13 -0600 (Thu, 09 Apr 2015) $
12  * $Rev: 3916 $
13  *
14  * \brief Bit bang pattern out GPIO pin.
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 
35 #include <string>
36 
37 #include "rnr/rnrconfig.h"
38 #include "rnr/log.h"
39 #include "rnr/opts.h"
40 #include "rnr/pkg.h"
41 
42 #include "rnr/gpio.h"
43 
44 #include "version.h"
45 using namespace std;
46 
47 /*!
48  * \ingroup cmds
49  * \defgroup gpioprobe gpioprobe
50  * \{
51  */
52 
53 #define APP_EC_OK 0 ///< success exit code
54 #define APP_EC_ARGS 2 ///< command-line options/arguments error exit code
55 #define APP_EC_EXEC 4 ///< execution exit code
56 
57 static char *Argv0; ///< the command
58 static char *OptsMethod = (char *)"sysfs"; ///< system file system
59 static int ArgsGpio; ///< gpio number
60 
61 /*!
62  * \brief Program information.
63  */
64 static OptsPgmInfo_T PgmInfo =
65 {
66  // usage_args
67  "<gpio>",
68 
69  // synopsis
70  "Safely probe GPIO settings and state.",
71 
72  // long_desc =
73  "The %P command probes the settings and state of GPIO exported number.",
74 
75  // diagnostics
76  NULL
77 };
78 
79 /*!
80  * \brief Command line options information.
81  */
82 static OptsInfo_T OptsInfo[] =
83 {
84 #ifdef MMAP_GPIO
85  // -m, --method
86  {
87  "method", // long_opt
88  'm', // short_opt
89  required_argument, // has_arg
90  true, // has_default
91  &OptsMethod, // opt_addr
92  OptsCvtArgStr, // fn_cvt
93  OptsFmtStr, // fn_fmt
94  "<method>", // arg_name
95  // opt desc
96  "GPIO access method. One of: sysfs mmap."
97  },
98 #endif // MMAP_GPIO
99 
100  {NULL, }
101 };
102 
103 static int strToInt(const string &str, int &val)
104 {
105  long long int val1; // must use 64-bit for arm 32-bit compilers
106 
107  if( sscanf(str.c_str(), "%lli", &val1) != 1 )
108  {
109  return RC_ERROR;
110  }
111 
112  val = (int)val1;
113 
114  return OK;
115 }
116 
117 static int strToBits(const string &str, byte_t *p)
118 {
119  string s;
120  int bit;
121  size_t i;
122  int val = 0;
123 
124  if( str.substr(0, 2) == "0b" )
125  {
126  s = str.substr(2, str.size()-2);
127  bit = 0x80;
128  for(i=0; i<8 & i<s.size(); ++i)
129  {
130  if( s[i] == '1' )
131  {
132  val |= bit;
133  }
134  else if( s[i] != '0' )
135  {
136  return RC_ERROR;
137  }
138  bit >>= 1;
139  }
140  }
141  else
142  {
143  if( sscanf(str.c_str(), "%i", &val) != 1 )
144  {
145  return RC_ERROR;
146  }
147  }
148 
149  *p = (byte_t)val;
150 
151  return OK;
152 }
153 
154 /*!
155  * \brief Main initialization.
156  *
157  * \param argc Command-line argument count.
158  * \param argv Command-line argument list.
159  *
160  * \par Exits:
161  * Program terminates on conversion error.
162  */
163 static void mainInit(int argc, char *argv[])
164 {
165  // name of this process
166  Argv0 = basename(argv[0]);
167 
168  // parse input options
169  argv = OptsGet(Argv0, &PkgInfo, &PgmInfo, OptsInfo, true, &argc, argv);
170 
171  if( argc == 0 )
172  {
173  fprintf(stderr, "%s: No exported GPIO/header pin number specified.\n",
174  Argv0);
175  fprintf(stderr, "Try '%s --help' for more information.\n", Argv0);
176  exit(APP_EC_ARGS);
177  }
178 
179  else if( strToInt(argv[0], ArgsGpio) < 0 )
180  {
181  fprintf(stderr, "%s: '%s': Bad GPIO number.\n", Argv0, argv[0]);
182  fprintf(stderr, "Try '%s --help' for more information.\n", Argv0);
183  exit(APP_EC_ARGS);
184  }
185 }
186 
187 /*!
188  * \brief Probe GPIO state.
189  *
190  * Method: sysfs
191  *
192  * \param [out] pInfo Pointer to GPIO info.
193  *
194  * \return Application exit code.
195  */
196 static int sysfsProbe(gpio_info_t *pInfo)
197 {
198  int ec;
199 
200  if( gpioProbe(ArgsGpio, pInfo) < 0 )
201  {
202  ec = APP_EC_EXEC;
203  }
204  else
205  {
206  ec = APP_EC_OK;
207  }
208 
209  return ec;
210 }
211 
212 static int sysfsProbeAndPrint()
213 {
214  gpio_info_t info;
215  const char *s;
216  int ec;
217 
218  ec = sysfsProbe(&info);
219 
220  if( ec != APP_EC_OK )
221  {
222  fprintf(stderr, "Error: sysfs GPIO Probe failed.\n");
223  return ec;
224  }
225 
226  printf("GPIO Info\n");
227  printf(" exported gpio number: %d\n", info.gpio);
228  if( info.pin > 0 )
229  {
230  printf(" external pin number: %d\n", info.pin);
231  }
232  else
233  {
234  printf(" external pin number: N/A\n");
235  }
236 
237  switch( info.dir )
238  {
239  case GPIO_DIR_IN:
240  s = GPIO_DIR_IN_STR;
241  break;
242  case GPIO_DIR_OUT:
243  s = GPIO_DIR_OUT_STR;
244  break;
245  default:
246  s = "?";
247  break;
248  }
249  printf(" direction: %s\n", s);
250 
251  switch( info.edge )
252  {
253  case GPIO_EDGE_NONE:
254  s = GPIO_EDGE_NONE_STR;
255  break;
256  case GPIO_EDGE_RISING:
258  break;
259  case GPIO_EDGE_FALLING:
261  break;
262  case GPIO_EDGE_BOTH:
263  s = GPIO_EDGE_BOTH_STR;
264  break;
265  default:
266  s = "?";
267  break;
268  }
269  printf(" edge: %s\n", s);
270 
271  printf(" pull: N/A\n");
272  printf(" value: %d\n", info.value);
273 }
274 
275 #ifdef MMAP_GPIO
276 /*!
277  * \brief Probe GPIO state.
278  *
279  * Method: mmap
280  *
281  * \param [out] pInfo Pointer to GPIO info.
282  *
283  * \return Application exit code.
284  */
285 static int mmapProbe(mmap_gpio_info_t *pInfo)
286 {
287  int ec;
288 
289  if( mmapGpioMap() < 0 )
290  {
291  return APP_EC_EXEC;
292  }
293 
294  if( mmapGpioProbe(ArgsGpio, pInfo) < 0 )
295  {
296  ec = APP_EC_EXEC;
297  }
298  else
299  {
300  ec = APP_EC_OK;
301  }
302 
303  mmapGpioUnmap();
304 
305  return ec;
306 }
307 
308 static int mmapProbeAndPrint()
309 {
310  mmap_gpio_info_t info;
311  const char *s;
312  int ec;
313 
314  ec = mmapProbe(&info);
315 
316  if( ec != APP_EC_OK )
317  {
318  fprintf(stderr, "Error: mmapped GPIO Probe failed.\n");
319  return ec;
320  }
321 
322  printf("GPIO Info\n");
323  printf(" exported gpio number: %d\n", info.gpio);
324  if( info.pin > 0 )
325  {
326  printf(" external pin number: %d\n", info.pin);
327  }
328  else
329  {
330  printf(" external pin number: N/A\n");
331  }
332 
333  printf(" mmap base address: 0x%lx\n", info.base);
334  printf(" mmap channel offset: 0x%x\n", info.channel);
335  printf(" mmap bit: %d\n", info.bit);
336 
337  switch( info.dir )
338  {
339  case GPIO_DIR_IN:
340  s = GPIO_DIR_IN_STR;
341  break;
342  case GPIO_DIR_OUT:
343  s = GPIO_DIR_OUT_STR;
344  break;
345  default:
346  s = "?";
347  break;
348  }
349  printf(" direction: %s\n", s);
350 
351  switch( info.edge )
352  {
353  case GPIO_EDGE_NONE:
354  s = GPIO_EDGE_NONE_STR;
355  break;
356  case GPIO_EDGE_RISING:
358  break;
359  case GPIO_EDGE_FALLING:
361  break;
362  case GPIO_EDGE_BOTH:
363  s = GPIO_EDGE_BOTH_STR;
364  break;
365  default:
366  s = "?";
367  break;
368  }
369  printf(" edge: %s\n", s);
370 
371  switch( info.pull )
372  {
373  case GPIO_PULL_UP:
374  s = GPIO_PULL_UP_STR;
375  break;
376  case GPIO_PULL_DN:
377  s = GPIO_PULL_DN_STR;
378  break;
379  default:
380  s = GPIO_PULL_DS_STR;
381  break;
382  }
383  printf(" pull: %s\n", s);
384 
385  printf(" value: %d\n", info.value);
386 
387  return APP_EC_OK;
388 }
389 
390 #endif // MMAP_GPIO
391 
392 /*!
393  * \brief Main.
394  *
395  * \param argc Command-line argument count.
396  * \param argv Command-line argument list.
397  *
398  * \return Returns 0 on succes, non-zero on failure.
399  */
400 int main(int argc, char* argv[])
401 {
402  int ec;
403 
404  mainInit(argc, argv);
405 
406  if( !strcmp(OptsMethod, "sysfs") )
407  {
408  ec = sysfsProbeAndPrint();
409  }
410 #ifdef MMAP_GPIO
411  else if( !strcmp(OptsMethod, "mmap") )
412  {
413  ec = mmapProbeAndPrint();
414  }
415 #endif // MMAP_GPIO
416  else
417  {
418  fprintf(stderr,"%s: Unknown GPIO access method.", OptsMethod);
419  ec = APP_EC_ARGS;
420  }
421 
422  return ec;
423 }
424 
425 /*!
426  * \}
427  */
#define GPIO_EDGE_FALLING
falling edge
Definition: gpio.h:78
#define GPIO_PULL_DN_STR
enable pulldown string
Definition: gpio.h:93
static int ArgsGpio
gpio number
Definition: gpioprobe.cxx:59
int gpio
sysfs exported gpio number
Definition: gpio.h:100
static void mainInit(int argc, char *argv[])
Main initialization.
Definition: gpioprobe.cxx:163
GPIO interface declarations and defines.
int gpioProbe(int gpio, gpio_info_t *p)
Safely probe GPIO parameters.
Definition: gpio.c:346
#define GPIO_EDGE_BOTH
both edges
Definition: gpio.h:79
#define GPIO_EDGE_FALLING_STR
falling edge string
Definition: gpio.h:82
#define GPIO_DIR_IN
input
Definition: gpio.h:68
#define GPIO_PULL_DS_STR
disable pullup/down string
Definition: gpio.h:91
static char * OptsMethod
system file system
Definition: gpioprobe.cxx:58
#define GPIO_PULL_UP_STR
enable pullup string
Definition: gpio.h:92
#define APP_EC_OK
success exit code
Definition: gpioprobe.cxx:53
#define GPIO_DIR_OUT_STR
output string
Definition: gpio.h:71
int edge
gpio edge type trigger
Definition: gpio.h:103
static char * Argv0
the command
Definition: gpioprobe.cxx:57
static OptsPgmInfo_T PgmInfo
Program information.
Definition: gpioprobe.cxx:64
#define GPIO_EDGE_BOTH_STR
both edges string
Definition: gpio.h:83
#define GPIO_EDGE_NONE_STR
no edge string
Definition: gpio.h:80
#define APP_EC_EXEC
execution exit code
Definition: gpioprobe.cxx:55
#define GPIO_PULL_DN
enable pulldown
Definition: gpio.h:90
GPIO info structure.
Definition: gpio.h:98
int dir
gpio direction
Definition: gpio.h:102
#define GPIO_DIR_OUT
output
Definition: gpio.h:69
static const PkgInfo_T PkgInfo
Definition: version.h:45
#define GPIO_DIR_IN_STR
input string
Definition: gpio.h:70
#define GPIO_EDGE_NONE
no edge
Definition: gpio.h:76
static int sysfsProbe(gpio_info_t *pInfo)
Probe GPIO state.
Definition: gpioprobe.cxx:196
int pin
external header pin number
Definition: gpio.h:101
Package version information.
#define GPIO_EDGE_RISING_STR
rising edge string
Definition: gpio.h:81
#define APP_EC_ARGS
command-line options/arguments error exit code
Definition: gpioprobe.cxx:54
#define GPIO_EDGE_RISING
rising edge
Definition: gpio.h:77
int main(int argc, char *argv[])
Main.
Definition: gpioprobe.cxx:400
static OptsInfo_T OptsInfo[]
Command line options information.
Definition: gpioprobe.cxx:82
#define GPIO_PULL_UP
enable pullup
Definition: gpio.h:89
int value
current value
Definition: gpio.h:105