3 * Swiss-Army-Knife, Set-UID command-line interface to the Raspberry
5 * Copyright (c) 2012 Gordon Henderson
6 ***********************************************************************
7 * This file is part of wiringPi:
8 * https://projects.drogon.net/raspberry-pi/wiringpi/
10 * wiringPi is free software: you can redistribute it and/or modify
11 * it under the terms of the GNU Lesser General Public License as published by
12 * the Free Software Foundation, either version 3 of the License, or
13 * (at your option) any later version.
15 * wiringPi is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License for more details.
20 * You should have received a copy of the GNU Lesser General Public License
21 * along with wiringPi. If not, see <http://www.gnu.org/licenses/>.
22 ***********************************************************************
32 #include <sys/types.h>
36 #include <gertboard.h>
38 extern int wiringPiDebug ;
45 #define VERSION "1.10"
49 char *usage = "Usage: gpio -v\n"
51 " gpio [-g] <read/write/wb/pwm/mode> ...\n"
52 " gpio [-p] <read/write/wb> ...\n"
54 " gpio unexportall/exports ...\n"
55 " gpio export/edge/unexport ...\n"
56 " gpio drive <group> <value>\n"
57 " gpio pwm-bal/pwm-ms \n"
58 " gpio pwmr <range> \n"
59 " gpio pwmc <divider> \n"
60 " gpio load spi/i2c\n"
61 " gpio gbr <channel>\n"
62 " gpio gbw <channel> <value>" ; // No trailing newline needed here.
67 * Change the ownership of the file to the real userId of the calling
68 * program so we can access it.
69 *********************************************************************************
72 static void changeOwner (char *cmd, char *file)
74 uid_t uid = getuid () ;
75 uid_t gid = getgid () ;
77 if (chown (file, uid, gid) != 0)
79 if (errno == ENOENT) // Warn that it's not there
80 fprintf (stderr, "%s: Warning: File not present: %s\n", cmd, file) ;
83 fprintf (stderr, "%s: Unable to change ownership of %s: %s\n", cmd, file, strerror (errno)) ;
92 * Return true/false if the supplied module is loaded
93 *********************************************************************************
96 static int moduleLoaded (char *modName)
98 int len = strlen (modName) ;
100 FILE *fd = fopen ("/proc/modules", "r") ;
105 fprintf (stderr, "gpio: Unable to check modules: %s\n", strerror (errno)) ;
109 while (fgets (line, 80, fd) != NULL)
111 if (strncmp (line, modName, len) != 0)
126 * Load either the spi or i2c modules and change device ownerships, etc.
127 *********************************************************************************
130 static void _doLoadUsage (char *argv [])
132 fprintf (stderr, "Usage: %s load <spi/i2c> [SPI bufferSize in KB | I2C baudrate in Kb/sec]\n", argv [0]) ;
136 static void doLoad (int argc, char *argv [])
138 char *module1, *module2 ;
140 char *file1, *file2 ;
141 char args1 [32], args2 [32] ;
144 _doLoadUsage (argv) ;
146 args1 [0] = args2 [0] = 0 ;
148 /**/ if (strcasecmp (argv [2], "spi") == 0)
151 module2 = "spi_bcm2708" ;
152 file1 = "/dev/spidev0.0" ;
153 file2 = "/dev/spidev0.1" ;
155 sprintf (args1, " bufsize=%d", atoi (argv [3]) * 1024) ;
157 _doLoadUsage (argv) ;
159 else if (strcasecmp (argv [2], "i2c") == 0)
161 module1 = "i2c_dev" ;
162 module2 = "i2c_bcm2708" ;
163 file1 = "/dev/i2c-0" ;
164 file2 = "/dev/i2c-1" ;
166 sprintf (args2, " baudrate=%d", atoi (argv [3]) * 1000) ;
168 _doLoadUsage (argv) ;
171 _doLoadUsage (argv) ;
173 if (!moduleLoaded (module1))
175 sprintf (cmd, "modprobe %s%s", module1, args1) ;
179 if (!moduleLoaded (module2))
181 sprintf (cmd, "modprobe %s%s", module2, args2) ;
185 if (!moduleLoaded (module2))
187 fprintf (stderr, "%s: Unable to load %s\n", argv [0], module2) ;
191 sleep (1) ; // To let things get settled
193 changeOwner (argv [0], file1) ;
194 changeOwner (argv [0], file2) ;
200 * Read all the GPIO pins
201 *********************************************************************************
204 static char *pinNames [] =
206 "GPIO 0", "GPIO 1", "GPIO 2", "GPIO 3", "GPIO 4", "GPIO 5", "GPIO 6", "GPIO 7",
208 "CE0 ", "CE1 ", "MOSI ", "MISO ", "SCLK ",
210 "GPIO 8", "GPIO 9", "GPIO10", "GPIO11",
213 static char *alts [] =
215 "IN ", "OUT ", "ALT0", "ALT1", "ALT2", "ALT3", "ALT4", "ALT5", "XXXX"
218 static void doReadall (void)
222 printf ("+----------+------+--------+------+------+\n") ;
223 printf ("| wiringPi | GPIO | Name | Mode | Value |\n") ;
224 printf ("+----------+------+--------+------+------+\n") ;
226 for (pin = 0 ; pin < 64 ; ++pin)
228 if (wpiPinToGpio (pin) == -1)
231 printf ("| %6d | %3d | %s | %s | %s |\n",
232 pin, wpiPinToGpio (pin),
235 digitalRead (pin) == HIGH ? "High" : "Low ") ;
238 printf ("+----------+------+--------+------+------+\n") ;
244 * List all GPIO exports
245 *********************************************************************************
248 static void doExports (int argc, char *argv [])
255 // Rather crude, but who knows what others are up to...
257 for (first = 0, i = 0 ; i < 64 ; ++i)
260 // Try to read the direction
262 sprintf (fName, "/sys/class/gpio/gpio%d/direction", i) ;
263 if ((fd = open (fName, O_RDONLY)) == -1)
269 printf ("GPIO Pins exported:\n") ;
272 printf ("%4d: ", i) ;
274 if ((l = read (fd, buf, 16)) == 0)
275 sprintf (buf, "%s", "?") ;
278 if ((buf [strlen (buf) - 1]) == '\n')
279 buf [strlen (buf) - 1] = 0 ;
281 printf ("%-3s", buf) ;
285 // Try to Read the value
287 sprintf (fName, "/sys/class/gpio/gpio%d/value", i) ;
288 if ((fd = open (fName, O_RDONLY)) == -1)
290 printf ("No Value file (huh?)\n") ;
294 if ((l = read (fd, buf, 16)) == 0)
295 sprintf (buf, "%s", "?") ;
298 if ((buf [strlen (buf) - 1]) == '\n')
299 buf [strlen (buf) - 1] = 0 ;
301 printf (" %s", buf) ;
303 // Read any edge trigger file
305 sprintf (fName, "/sys/class/gpio/gpio%d/edge", i) ;
306 if ((fd = open (fName, O_RDONLY)) == -1)
312 if ((l = read (fd, buf, 16)) == 0)
313 sprintf (buf, "%s", "?") ;
316 if ((buf [strlen (buf) - 1]) == '\n')
317 buf [strlen (buf) - 1] = 0 ;
319 printf (" %-8s\n", buf) ;
328 * gpio export pin mode
329 * This uses the /sys/class/gpio device interface.
330 *********************************************************************************
333 void doExport (int argc, char *argv [])
342 fprintf (stderr, "Usage: %s export pin mode\n", argv [0]) ;
346 pin = atoi (argv [2]) ;
350 if ((fd = fopen ("/sys/class/gpio/export", "w")) == NULL)
352 fprintf (stderr, "%s: Unable to open GPIO export interface: %s\n", argv [0], strerror (errno)) ;
356 fprintf (fd, "%d\n", pin) ;
359 sprintf (fName, "/sys/class/gpio/gpio%d/direction", pin) ;
360 if ((fd = fopen (fName, "w")) == NULL)
362 fprintf (stderr, "%s: Unable to open GPIO direction interface for pin %d: %s\n", argv [0], pin, strerror (errno)) ;
366 /**/ if ((strcasecmp (mode, "in") == 0) || (strcasecmp (mode, "input") == 0))
367 fprintf (fd, "in\n") ;
368 else if ((strcasecmp (mode, "out") == 0) || (strcasecmp (mode, "output") == 0))
369 fprintf (fd, "out\n") ;
372 fprintf (stderr, "%s: Invalid mode: %s. Should be in or out\n", argv [1], mode) ;
378 // Change ownership so the current user can actually use it!
380 sprintf (fName, "/sys/class/gpio/gpio%d/value", pin) ;
381 changeOwner (argv [0], fName) ;
383 sprintf (fName, "/sys/class/gpio/gpio%d/edge", pin) ;
384 changeOwner (argv [0], fName) ;
392 * Easy access to changing the edge trigger on a GPIO pin
393 * This uses the /sys/class/gpio device interface.
394 *********************************************************************************
397 void doEdge (int argc, char *argv [])
406 fprintf (stderr, "Usage: %s edge pin mode\n", argv [0]) ;
410 pin = atoi (argv [2]) ;
413 // Export the pin and set direction to input
415 if ((fd = fopen ("/sys/class/gpio/export", "w")) == NULL)
417 fprintf (stderr, "%s: Unable to open GPIO export interface: %s\n", argv [0], strerror (errno)) ;
421 fprintf (fd, "%d\n", pin) ;
424 sprintf (fName, "/sys/class/gpio/gpio%d/direction", pin) ;
425 if ((fd = fopen (fName, "w")) == NULL)
427 fprintf (stderr, "%s: Unable to open GPIO direction interface for pin %d: %s\n", argv [0], pin, strerror (errno)) ;
431 fprintf (fd, "in\n") ;
434 sprintf (fName, "/sys/class/gpio/gpio%d/edge", pin) ;
435 if ((fd = fopen (fName, "w")) == NULL)
437 fprintf (stderr, "%s: Unable to open GPIO edge interface for pin %d: %s\n", argv [0], pin, strerror (errno)) ;
441 /**/ if (strcasecmp (mode, "none") == 0) fprintf (fd, "none\n") ;
442 else if (strcasecmp (mode, "rising") == 0) fprintf (fd, "rising\n") ;
443 else if (strcasecmp (mode, "falling") == 0) fprintf (fd, "falling\n") ;
444 else if (strcasecmp (mode, "both") == 0) fprintf (fd, "both\n") ;
447 fprintf (stderr, "%s: Invalid mode: %s. Should be none, rising, falling or both\n", argv [1], mode) ;
451 // Change ownership of the value and edge files, so the current user can actually use it!
453 sprintf (fName, "/sys/class/gpio/gpio%d/value", pin) ;
454 changeOwner (argv [0], fName) ;
456 sprintf (fName, "/sys/class/gpio/gpio%d/edge", pin) ;
457 changeOwner (argv [0], fName) ;
466 * This uses the /sys/class/gpio device interface.
467 *********************************************************************************
470 void doUnexport (int argc, char *argv [])
477 fprintf (stderr, "Usage: %s unexport pin\n", argv [0]) ;
481 pin = atoi (argv [2]) ;
483 if ((fd = fopen ("/sys/class/gpio/unexport", "w")) == NULL)
485 fprintf (stderr, "%s: Unable to open GPIO export interface\n", argv [0]) ;
489 fprintf (fd, "%d\n", pin) ;
497 * Un-Export all the GPIO pins.
498 * This uses the /sys/class/gpio device interface.
499 *********************************************************************************
502 void doUnexportall (int argc, char *argv [])
507 for (pin = 0 ; pin < 63 ; ++pin)
509 if ((fd = fopen ("/sys/class/gpio/unexport", "w")) == NULL)
511 fprintf (stderr, "%s: Unable to open GPIO export interface\n", argv [0]) ;
514 fprintf (fd, "%d\n", pin) ;
522 * gpio mode pin mode ...
523 *********************************************************************************
526 void doMode (int argc, char *argv [])
533 fprintf (stderr, "Usage: %s mode pin mode\n", argv [0]) ;
537 pin = atoi (argv [2]) ;
539 if ((wpMode == WPI_MODE_PINS) && ((pin < 0) || (pin >= NUM_PINS)))
544 /**/ if (strcasecmp (mode, "in") == 0) pinMode (pin, INPUT) ;
545 else if (strcasecmp (mode, "out") == 0) pinMode (pin, OUTPUT) ;
546 else if (strcasecmp (mode, "pwm") == 0) pinMode (pin, PWM_OUTPUT) ;
547 else if (strcasecmp (mode, "up") == 0) pullUpDnControl (pin, PUD_UP) ;
548 else if (strcasecmp (mode, "down") == 0) pullUpDnControl (pin, PUD_DOWN) ;
549 else if (strcasecmp (mode, "tri") == 0) pullUpDnControl (pin, PUD_OFF) ;
552 fprintf (stderr, "%s: Invalid mode: %s. Should be in/out/pwm/up/down/tri\n", argv [1], mode) ;
560 * gpio drive group value
561 *********************************************************************************
564 static void doPadDrive (int argc, char *argv [])
570 fprintf (stderr, "Usage: %s drive group value\n", argv [0]) ;
574 group = atoi (argv [2]) ;
575 val = atoi (argv [3]) ;
577 if ((group < 0) || (group > 2))
579 fprintf (stderr, "%s: drive group not 0, 1 or 2: %d\n", argv [0], group) ;
583 if ((val < 0) || (val > 7))
585 fprintf (stderr, "%s: drive value not 0-7: %d\n", argv [0], val) ;
589 setPadDrive (group, val) ;
595 * gpio gbw channel value
596 * Gertboard Write - To the Analog output
597 *********************************************************************************
600 static void doGbw (int argc, char *argv [])
606 fprintf (stderr, "Usage: %s gbr <channel> <value>\n", argv [0]) ;
610 channel = atoi (argv [2]) ;
611 value = atoi (argv [3]) ;
613 if ((channel < 0) || (channel > 1))
615 fprintf (stderr, "%s: channel must be 0 or 1\n", argv [0]) ;
619 if ((value < 0) || (value > 1023))
621 fprintf (stderr, "%s: value must be from 0 to 255\n", argv [0]) ;
625 if (gertboardSPISetup () == -1)
627 fprintf (stderr, "Unable to initialise the Gertboard SPI interface: %s\n", strerror (errno)) ;
631 gertboardAnalogWrite (channel, value) ;
638 * From the analog input
639 *********************************************************************************
642 static void doGbr (int argc, char *argv [])
648 fprintf (stderr, "Usage: %s gbr <channel>\n", argv [0]) ;
652 channel = atoi (argv [2]) ;
654 if ((channel < 0) || (channel > 1))
656 fprintf (stderr, "%s: channel must be 0 or 1\n", argv [0]) ;
660 if (gertboardSPISetup () == -1)
662 fprintf (stderr, "Unable to initialise the Gertboard SPI interface: %s\n", strerror (errno)) ;
666 printf ("%d\n",gertboardAnalogRead (channel)) ;
673 * gpio write pin value
674 *********************************************************************************
677 static void doWrite (int argc, char *argv [])
683 fprintf (stderr, "Usage: %s write pin value\n", argv [0]) ;
687 pin = atoi (argv [2]) ;
689 if ((wpMode == WPI_MODE_PINS) && ((pin < 0) || (pin >= NUM_PINS)))
692 /**/ if ((strcasecmp (argv [3], "up") == 0) || (strcasecmp (argv [3], "on") == 0))
694 else if ((strcasecmp (argv [3], "down") == 0) || (strcasecmp (argv [3], "off") == 0))
697 val = atoi (argv [3]) ;
700 digitalWrite (pin, LOW) ;
702 digitalWrite (pin, HIGH) ;
708 *********************************************************************************
711 static void doWriteByte (int argc, char *argv [])
717 fprintf (stderr, "Usage: %s wb value\n", argv [0]) ;
721 val = (int)strtol (argv [2], NULL, 0) ;
723 digitalWriteByte (val) ;
729 * Read a pin and return the value
730 *********************************************************************************
733 void doRead (int argc, char *argv [])
739 fprintf (stderr, "Usage: %s read pin\n", argv [0]) ;
743 pin = atoi (argv [2]) ;
745 if ((wpMode == WPI_MODE_PINS) && ((pin < 0) || (pin >= NUM_PINS)))
751 val = digitalRead (pin) ;
753 printf ("%s\n", val == 0 ? "0" : "1") ;
759 * Output a PWM value on a pin
760 *********************************************************************************
763 void doPwm (int argc, char *argv [])
769 fprintf (stderr, "Usage: %s pwm <pin> <value>\n", argv [0]) ;
773 pin = atoi (argv [2]) ;
775 if ((wpMode == WPI_MODE_PINS) && ((pin < 0) || (pin >= NUM_PINS)))
778 val = atoi (argv [3]) ;
780 pwmWrite (pin, val) ;
785 * doPwmMode: doPwmRange: doPwmClock:
786 * Change the PWM mode, range and clock divider values
787 *********************************************************************************
790 static void doPwmMode (int mode)
795 static void doPwmRange (int argc, char *argv [])
801 fprintf (stderr, "Usage: %s pwmr <range>\n", argv [0]) ;
805 range = (unsigned int)strtoul (argv [2], NULL, 10) ;
809 fprintf (stderr, "%s: range must be > 0\n", argv [0]) ;
813 pwmSetRange (range) ;
816 static void doPwmClock (int argc, char *argv [])
822 fprintf (stderr, "Usage: %s pwmc <clock>\n", argv [0]) ;
826 clock = (unsigned int)strtoul (argv [2], NULL, 10) ;
828 if ((clock < 1) || (clock > 4095))
830 fprintf (stderr, "%s: clock must be between 0 and 4096\n", argv [0]) ;
834 pwmSetClock (clock) ;
841 *********************************************************************************
844 int main (int argc, char *argv [])
848 if (getenv ("WIRINGPI_DEBUG") != NULL)
850 printf ("gpio: wiringPi debug mode enabled\n") ;
851 wiringPiDebug = TRUE ;
856 fprintf (stderr, "%s\n", usage) ;
860 if (strcasecmp (argv [1], "-h") == 0)
862 printf ("%s: %s\n", argv [0], usage) ;
866 if (strcasecmp (argv [1], "-v") == 0)
868 printf ("gpio version: %s\n", VERSION) ;
869 printf ("Copyright (c) 2012 Gordon Henderson\n") ;
870 printf ("This is free software with ABSOLUTELY NO WARRANTY.\n") ;
871 printf ("For details type: %s -warranty\n", argv [0]) ;
873 printf ("This Raspberry Pi is a revision %d board.\n", piBoardRev ()) ;
877 if (strcasecmp (argv [1], "-warranty") == 0)
879 printf ("gpio version: %s\n", VERSION) ;
880 printf ("Copyright (c) 2012 Gordon Henderson\n") ;
882 printf (" This program is free software; you can redistribute it and/or modify\n") ;
883 printf (" it under the terms of the GNU Leser General Public License as published\n") ;
884 printf (" by the Free Software Foundation, either version 3 of the License, or\n") ;
885 printf (" (at your option) any later version.\n") ;
887 printf (" This program is distributed in the hope that it will be useful,\n") ;
888 printf (" but WITHOUT ANY WARRANTY; without even the implied warranty of\n") ;
889 printf (" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n") ;
890 printf (" GNU Lesser General Public License for more details.\n") ;
892 printf (" You should have received a copy of the GNU Lesser General Public License\n") ;
893 printf (" along with this program. If not, see <http://www.gnu.org/licenses/>.\n") ;
900 fprintf (stderr, "%s: Must be root to run. Program should be suid root. This is an error.\n", argv [0]) ;
904 // Initial test for /sys/class/gpio operations:
906 /**/ if (strcasecmp (argv [1], "exports" ) == 0) { doExports (argc, argv) ; return 0 ; }
907 else if (strcasecmp (argv [1], "export" ) == 0) { doExport (argc, argv) ; return 0 ; }
908 else if (strcasecmp (argv [1], "edge" ) == 0) { doEdge (argc, argv) ; return 0 ; }
909 else if (strcasecmp (argv [1], "unexportall") == 0) { doUnexportall (argc, argv) ; return 0 ; }
910 else if (strcasecmp (argv [1], "unexport" ) == 0) { doUnexport (argc, argv) ; return 0 ; }
912 // Check for load command:
914 if (strcasecmp (argv [1], "load" ) == 0) { doLoad (argc, argv) ; return 0 ; }
916 // Gertboard commands
918 if (strcasecmp (argv [1], "gbr" ) == 0) { doGbr (argc, argv) ; return 0 ; }
919 if (strcasecmp (argv [1], "gbw" ) == 0) { doGbw (argc, argv) ; return 0 ; }
921 // Check for -g argument
923 if (strcasecmp (argv [1], "-g") == 0)
925 if (wiringPiSetupGpio () == -1)
927 fprintf (stderr, "%s: Unable to initialise GPIO mode.\n", argv [0]) ;
931 for (i = 2 ; i < argc ; ++i)
932 argv [i - 1] = argv [i] ;
934 wpMode = WPI_MODE_GPIO ;
937 // Check for -p argument for PiFace
939 else if (strcasecmp (argv [1], "-p") == 0)
941 if (wiringPiSetupPiFaceForGpioProg () == -1)
943 fprintf (stderr, "%s: Unable to initialise PiFace.\n", argv [0]) ;
947 for (i = 2 ; i < argc ; ++i)
948 argv [i - 1] = argv [i] ;
950 wpMode = WPI_MODE_PIFACE ;
953 // Default to wiringPi mode
957 if (wiringPiSetup () == -1)
959 fprintf (stderr, "%s: Unable to initialise wiringPi mode\n", argv [0]) ;
962 wpMode = WPI_MODE_PINS ;
965 // Check for PWM or Pad Drive operations
967 if (wpMode != WPI_MODE_PIFACE)
969 if (strcasecmp (argv [1], "pwm-bal") == 0) { doPwmMode (PWM_MODE_BAL) ; return 0 ; }
970 if (strcasecmp (argv [1], "pwm-ms") == 0) { doPwmMode (PWM_MODE_MS) ; return 0 ; }
971 if (strcasecmp (argv [1], "pwmr") == 0) { doPwmRange (argc, argv) ; return 0 ; }
972 if (strcasecmp (argv [1], "pwmc") == 0) { doPwmClock (argc, argv) ; return 0 ; }
973 if (strcasecmp (argv [1], "drive") == 0) { doPadDrive (argc, argv) ; return 0 ; }
976 // Check for wiring commands
978 /**/ if (strcasecmp (argv [1], "readall" ) == 0) doReadall () ;
979 else if (strcasecmp (argv [1], "read" ) == 0) doRead (argc, argv) ;
980 else if (strcasecmp (argv [1], "write") == 0) doWrite (argc, argv) ;
981 else if (strcasecmp (argv [1], "wb") == 0) doWriteByte (argc, argv) ;
982 else if (strcasecmp (argv [1], "pwm" ) == 0) doPwm (argc, argv) ;
983 else if (strcasecmp (argv [1], "mode" ) == 0) doMode (argc, argv) ;
986 fprintf (stderr, "%s: Unknown command: %s.\n", argv [0], argv [1]) ;