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.11"
49 char *usage = "Usage: gpio -v\n"
51 " gpio [-g] <read/write/wb/pwm/clock/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 ", "ALT5", "ALT4", "ALT0", "ALT1", "ALT2", "ALT3"
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, "clock") == 0) pinMode (pin, GPIO_CLOCK) ;
548 else if (strcasecmp (mode, "up") == 0) pullUpDnControl (pin, PUD_UP) ;
549 else if (strcasecmp (mode, "down") == 0) pullUpDnControl (pin, PUD_DOWN) ;
550 else if (strcasecmp (mode, "tri") == 0) pullUpDnControl (pin, PUD_OFF) ;
553 fprintf (stderr, "%s: Invalid mode: %s. Should be in/out/pwm/clock/up/down/tri\n", argv [1], mode) ;
561 * gpio drive group value
562 *********************************************************************************
565 static void doPadDrive (int argc, char *argv [])
571 fprintf (stderr, "Usage: %s drive group value\n", argv [0]) ;
575 group = atoi (argv [2]) ;
576 val = atoi (argv [3]) ;
578 if ((group < 0) || (group > 2))
580 fprintf (stderr, "%s: drive group not 0, 1 or 2: %d\n", argv [0], group) ;
584 if ((val < 0) || (val > 7))
586 fprintf (stderr, "%s: drive value not 0-7: %d\n", argv [0], val) ;
590 setPadDrive (group, val) ;
596 * gpio gbw channel value
597 * Gertboard Write - To the Analog output
598 *********************************************************************************
601 static void doGbw (int argc, char *argv [])
607 fprintf (stderr, "Usage: %s gbr <channel> <value>\n", argv [0]) ;
611 channel = atoi (argv [2]) ;
612 value = atoi (argv [3]) ;
614 if ((channel < 0) || (channel > 1))
616 fprintf (stderr, "%s: channel must be 0 or 1\n", argv [0]) ;
620 if ((value < 0) || (value > 1023))
622 fprintf (stderr, "%s: value must be from 0 to 255\n", argv [0]) ;
626 if (gertboardSPISetup () == -1)
628 fprintf (stderr, "Unable to initialise the Gertboard SPI interface: %s\n", strerror (errno)) ;
632 gertboardAnalogWrite (channel, value) ;
639 * From the analog input
640 *********************************************************************************
643 static void doGbr (int argc, char *argv [])
649 fprintf (stderr, "Usage: %s gbr <channel>\n", argv [0]) ;
653 channel = atoi (argv [2]) ;
655 if ((channel < 0) || (channel > 1))
657 fprintf (stderr, "%s: channel must be 0 or 1\n", argv [0]) ;
661 if (gertboardSPISetup () == -1)
663 fprintf (stderr, "Unable to initialise the Gertboard SPI interface: %s\n", strerror (errno)) ;
667 printf ("%d\n",gertboardAnalogRead (channel)) ;
674 * gpio write pin value
675 *********************************************************************************
678 static void doWrite (int argc, char *argv [])
684 fprintf (stderr, "Usage: %s write pin value\n", argv [0]) ;
688 pin = atoi (argv [2]) ;
690 if ((wpMode == WPI_MODE_PINS) && ((pin < 0) || (pin >= NUM_PINS)))
693 /**/ if ((strcasecmp (argv [3], "up") == 0) || (strcasecmp (argv [3], "on") == 0))
695 else if ((strcasecmp (argv [3], "down") == 0) || (strcasecmp (argv [3], "off") == 0))
698 val = atoi (argv [3]) ;
701 digitalWrite (pin, LOW) ;
703 digitalWrite (pin, HIGH) ;
709 *********************************************************************************
712 static void doWriteByte (int argc, char *argv [])
718 fprintf (stderr, "Usage: %s wb value\n", argv [0]) ;
722 val = (int)strtol (argv [2], NULL, 0) ;
724 digitalWriteByte (val) ;
730 * Read a pin and return the value
731 *********************************************************************************
734 void doRead (int argc, char *argv [])
740 fprintf (stderr, "Usage: %s read pin\n", argv [0]) ;
744 pin = atoi (argv [2]) ;
746 if ((wpMode == WPI_MODE_PINS) && ((pin < 0) || (pin >= NUM_PINS)))
752 val = digitalRead (pin) ;
754 printf ("%s\n", val == 0 ? "0" : "1") ;
760 * Output a clock on a pin
761 *********************************************************************************
764 void doClock (int argc, char *argv [])
770 fprintf (stderr, "Usage: %s clock <pin> <freq>\n", argv [0]) ;
774 pin = atoi (argv [2]) ;
776 if ((wpMode == WPI_MODE_PINS) && ((pin < 0) || (pin >= NUM_PINS)))
779 freq = atoi (argv [3]) ;
781 gpioClockSet (pin, freq) ;
787 * Output a PWM value on a pin
788 *********************************************************************************
791 void doPwm (int argc, char *argv [])
797 fprintf (stderr, "Usage: %s pwm <pin> <value>\n", argv [0]) ;
801 pin = atoi (argv [2]) ;
803 if ((wpMode == WPI_MODE_PINS) && ((pin < 0) || (pin >= NUM_PINS)))
806 val = atoi (argv [3]) ;
808 pwmWrite (pin, val) ;
813 * doPwmMode: doPwmRange: doPwmClock:
814 * Change the PWM mode, range and clock divider values
815 *********************************************************************************
818 static void doPwmMode (int mode)
823 static void doPwmRange (int argc, char *argv [])
829 fprintf (stderr, "Usage: %s pwmr <range>\n", argv [0]) ;
833 range = (unsigned int)strtoul (argv [2], NULL, 10) ;
837 fprintf (stderr, "%s: range must be > 0\n", argv [0]) ;
841 pwmSetRange (range) ;
844 static void doPwmClock (int argc, char *argv [])
850 fprintf (stderr, "Usage: %s pwmc <clock>\n", argv [0]) ;
854 clock = (unsigned int)strtoul (argv [2], NULL, 10) ;
856 if ((clock < 1) || (clock > 4095))
858 fprintf (stderr, "%s: clock must be between 0 and 4096\n", argv [0]) ;
862 pwmSetClock (clock) ;
869 *********************************************************************************
872 int main (int argc, char *argv [])
876 if (getenv ("WIRINGPI_DEBUG") != NULL)
878 printf ("gpio: wiringPi debug mode enabled\n") ;
879 wiringPiDebug = TRUE ;
884 fprintf (stderr, "%s\n", usage) ;
888 if (strcasecmp (argv [1], "-h") == 0)
890 printf ("%s: %s\n", argv [0], usage) ;
894 if (strcasecmp (argv [1], "-v") == 0)
896 printf ("gpio version: %s\n", VERSION) ;
897 printf ("Copyright (c) 2012 Gordon Henderson\n") ;
898 printf ("This is free software with ABSOLUTELY NO WARRANTY.\n") ;
899 printf ("For details type: %s -warranty\n", argv [0]) ;
901 printf ("This Raspberry Pi is a revision %d board.\n", piBoardRev ()) ;
905 if (strcasecmp (argv [1], "-warranty") == 0)
907 printf ("gpio version: %s\n", VERSION) ;
908 printf ("Copyright (c) 2012 Gordon Henderson\n") ;
910 printf (" This program is free software; you can redistribute it and/or modify\n") ;
911 printf (" it under the terms of the GNU Leser General Public License as published\n") ;
912 printf (" by the Free Software Foundation, either version 3 of the License, or\n") ;
913 printf (" (at your option) any later version.\n") ;
915 printf (" This program is distributed in the hope that it will be useful,\n") ;
916 printf (" but WITHOUT ANY WARRANTY; without even the implied warranty of\n") ;
917 printf (" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n") ;
918 printf (" GNU Lesser General Public License for more details.\n") ;
920 printf (" You should have received a copy of the GNU Lesser General Public License\n") ;
921 printf (" along with this program. If not, see <http://www.gnu.org/licenses/>.\n") ;
928 fprintf (stderr, "%s: Must be root to run. Program should be suid root. This is an error.\n", argv [0]) ;
932 // Initial test for /sys/class/gpio operations:
934 /**/ if (strcasecmp (argv [1], "exports" ) == 0) { doExports (argc, argv) ; return 0 ; }
935 else if (strcasecmp (argv [1], "export" ) == 0) { doExport (argc, argv) ; return 0 ; }
936 else if (strcasecmp (argv [1], "edge" ) == 0) { doEdge (argc, argv) ; return 0 ; }
937 else if (strcasecmp (argv [1], "unexportall") == 0) { doUnexportall (argc, argv) ; return 0 ; }
938 else if (strcasecmp (argv [1], "unexport" ) == 0) { doUnexport (argc, argv) ; return 0 ; }
940 // Check for load command:
942 if (strcasecmp (argv [1], "load" ) == 0) { doLoad (argc, argv) ; return 0 ; }
944 // Gertboard commands
946 if (strcasecmp (argv [1], "gbr" ) == 0) { doGbr (argc, argv) ; return 0 ; }
947 if (strcasecmp (argv [1], "gbw" ) == 0) { doGbw (argc, argv) ; return 0 ; }
949 // Check for -g argument
951 if (strcasecmp (argv [1], "-g") == 0)
953 if (wiringPiSetupGpio () == -1)
955 fprintf (stderr, "%s: Unable to initialise GPIO mode.\n", argv [0]) ;
959 for (i = 2 ; i < argc ; ++i)
960 argv [i - 1] = argv [i] ;
962 wpMode = WPI_MODE_GPIO ;
965 // Check for -p argument for PiFace
967 else if (strcasecmp (argv [1], "-p") == 0)
969 if (wiringPiSetupPiFaceForGpioProg () == -1)
971 fprintf (stderr, "%s: Unable to initialise PiFace.\n", argv [0]) ;
975 for (i = 2 ; i < argc ; ++i)
976 argv [i - 1] = argv [i] ;
978 wpMode = WPI_MODE_PIFACE ;
981 // Default to wiringPi mode
985 if (wiringPiSetup () == -1)
987 fprintf (stderr, "%s: Unable to initialise wiringPi mode\n", argv [0]) ;
990 wpMode = WPI_MODE_PINS ;
993 // Check for PWM or Pad Drive operations
995 if (wpMode != WPI_MODE_PIFACE)
997 if (strcasecmp (argv [1], "pwm-bal") == 0) { doPwmMode (PWM_MODE_BAL) ; return 0 ; }
998 if (strcasecmp (argv [1], "pwm-ms") == 0) { doPwmMode (PWM_MODE_MS) ; return 0 ; }
999 if (strcasecmp (argv [1], "pwmr") == 0) { doPwmRange (argc, argv) ; return 0 ; }
1000 if (strcasecmp (argv [1], "pwmc") == 0) { doPwmClock (argc, argv) ; return 0 ; }
1001 if (strcasecmp (argv [1], "drive") == 0) { doPadDrive (argc, argv) ; return 0 ; }
1004 // Check for wiring commands
1006 /**/ if (strcasecmp (argv [1], "readall" ) == 0) doReadall () ;
1007 else if (strcasecmp (argv [1], "read" ) == 0) doRead (argc, argv) ;
1008 else if (strcasecmp (argv [1], "write") == 0) doWrite (argc, argv) ;
1009 else if (strcasecmp (argv [1], "wb") == 0) doWriteByte (argc, argv) ;
1010 else if (strcasecmp (argv [1], "pwm" ) == 0) doPwm (argc, argv) ;
1011 else if (strcasecmp (argv [1], "clock") == 0) doClock (argc, argv) ;
1012 else if (strcasecmp (argv [1], "mode" ) == 0) doMode (argc, argv) ;
1015 fprintf (stderr, "%s: Unknown command: %s.\n", argv [0], argv [1]) ;