gpio.c 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429
  1. /*
  2. * gpio.c:
  3. * Set-UID command-line interface to the Raspberry Pi's GPIO
  4. * Copyright (c) 2012 Gordon Henderson
  5. ***********************************************************************
  6. * This file is part of wiringPi:
  7. * https://projects.drogon.net/raspberry-pi/wiringpi/
  8. *
  9. * wiringPi is free software: you can redistribute it and/or modify
  10. * it under the terms of the GNU General Public License as published by
  11. * the Free Software Foundation, either version 3 of the License, or
  12. * (at your option) any later version.
  13. *
  14. * wiringPi is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. * GNU General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU General Public License
  20. * along with wiringPi. If not, see <http://www.gnu.org/licenses/>.
  21. ***********************************************************************
  22. */
  23. #include <wiringPi.h>
  24. #include <stdio.h>
  25. #include <stdlib.h>
  26. #include <stdint.h>
  27. #include <string.h>
  28. #include <unistd.h>
  29. #include <errno.h>
  30. #include <sys/types.h>
  31. #include <fcntl.h>
  32. #define VERSION "1.0"
  33. static int wpMode ;
  34. char *usage = "Usage: gpio -v\n"
  35. " gpio [-g] <read/write/pwm/mode/> ...\n"
  36. " gpio <export/unexport/exports> ..." ;
  37. /*
  38. * doExports:
  39. * List all GPIO exports
  40. *********************************************************************************
  41. */
  42. void doExports (void)
  43. {
  44. int fd ;
  45. int i, l, first ;
  46. char fName [128] ;
  47. char dir, val ;
  48. // Rather crude, but who knows what others are up to...
  49. for (first = 0, i = 0 ; i < 64 ; ++i)
  50. {
  51. // Try to read the direction
  52. sprintf (fName, "/sys/class/gpio/gpio%d/direction", i) ;
  53. if ((fd = open (fName, O_RDONLY)) == -1)
  54. continue ;
  55. if (first == 0)
  56. {
  57. ++first ;
  58. printf ("GPIO Pins exported:\n") ;
  59. }
  60. printf ("%4d: ", i) ;
  61. if ((l = read (fd, &dir, 1)) == 0)
  62. {
  63. printf ("Empty direction file (why?)\n") ;
  64. close (fd) ;
  65. continue ;
  66. }
  67. /**/ if (dir == 'o')
  68. printf ("Output ") ;
  69. else if (dir == 'i')
  70. printf ("Input ") ;
  71. else
  72. printf ("Wrong ") ;
  73. close (fd) ;
  74. // Try to Read the value
  75. sprintf (fName, "/sys/class/gpio/gpio%d/value", i) ;
  76. if ((fd = open (fName, O_RDONLY)) == -1)
  77. {
  78. printf ("No Value file (huh?)\n") ;
  79. continue ;
  80. }
  81. if ((l = read (fd, &val, 1)) == 0)
  82. {
  83. printf ("Empty Value file (why?)\n") ;
  84. close (fd) ;
  85. continue ;
  86. }
  87. /**/ if (val == '0' )
  88. printf ("(0)\n") ;
  89. else if (val == '1')
  90. printf ("(1)\n") ;
  91. else
  92. printf ("(?)\n") ;
  93. close (fd) ;
  94. }
  95. }
  96. /*
  97. * doExport:
  98. * gpio export pin mode
  99. * This uses the /sys/class/gpio device interface.
  100. *********************************************************************************
  101. */
  102. void doExport (int argc, char *argv [])
  103. {
  104. FILE *fd ;
  105. int pin ;
  106. char *mode ;
  107. char fName [128] ;
  108. uid_t uid ;
  109. gid_t gid ;
  110. if (argc != 4)
  111. {
  112. fprintf (stderr, "Usage: %s export pin mode\n", argv [0]) ;
  113. exit (1) ;
  114. }
  115. pin = atoi (argv [2]) ;
  116. mode = argv [3] ;
  117. if ((fd = fopen ("/sys/class/gpio/export", "w")) == NULL)
  118. {
  119. fprintf (stderr, "%s: Unable to open GPIO export interface: %s\n", argv [0], strerror (errno)) ;
  120. exit (1) ;
  121. }
  122. fprintf (fd, "%d\n", pin) ;
  123. fclose (fd) ;
  124. sprintf (fName, "/sys/class/gpio/gpio%d/direction", pin) ;
  125. if ((fd = fopen (fName, "w")) == NULL)
  126. {
  127. fprintf (stderr, "%s: Unable to open GPIO direction interface for pin %d: %s\n", argv [0], pin, strerror (errno)) ;
  128. exit (1) ;
  129. }
  130. /**/ if (strcasecmp (mode, "in") == 0)
  131. fprintf (fd, "in\n") ;
  132. else if (strcasecmp (mode, "out") == 0)
  133. fprintf (fd, "out\n") ;
  134. else
  135. {
  136. fprintf (stderr, "%s: Invalid mode: %s. Should be in or out\n", argv [1], mode) ;
  137. exit (1) ;
  138. }
  139. fclose (fd) ;
  140. // Change ownership so the current user can actually use it!
  141. uid = getuid () ;
  142. gid = getgid () ;
  143. sprintf (fName, "/sys/class/gpio/gpio%d/value", pin) ;
  144. if (chown (fName, uid, gid) != 0)
  145. {
  146. fprintf (stderr, "%s: Unable to change ownership of the value file: %s\n", argv [1], strerror (errno)) ;
  147. exit (1) ;
  148. }
  149. }
  150. /*
  151. * doUnexport:
  152. * gpio unexport pin
  153. * This uses the /sys/class/gpio device interface.
  154. *********************************************************************************
  155. */
  156. void doUnexport (int argc, char *argv [])
  157. {
  158. FILE *fd ;
  159. int pin ;
  160. if (argc != 3)
  161. {
  162. fprintf (stderr, "Usage: %s unexport pin\n", argv [0]) ;
  163. exit (1) ;
  164. }
  165. pin = atoi (argv [2]) ;
  166. if ((fd = fopen ("/sys/class/gpio/unexport", "w")) == NULL)
  167. {
  168. fprintf (stderr, "%s: Unable to open GPIO export interface\n", argv [0]) ;
  169. exit (1) ;
  170. }
  171. fprintf (fd, "%d\n", pin) ;
  172. fclose (fd) ;
  173. }
  174. /*
  175. * doMode:
  176. * gpio mode pin mode ...
  177. *********************************************************************************
  178. */
  179. void doMode (int argc, char *argv [])
  180. {
  181. int pin ;
  182. char *mode ;
  183. if (argc != 4)
  184. {
  185. fprintf (stderr, "Usage: %s mode pin mode\n", argv [0]) ;
  186. exit (1) ;
  187. }
  188. pin = atoi (argv [2]) ;
  189. if ((wpMode == WPI_MODE_PINS) && ((pin < 0) || (pin >= NUM_PINS)))
  190. return ;
  191. mode = argv [3] ;
  192. /**/ if (strcasecmp (mode, "in") == 0)
  193. pinMode (pin, INPUT) ;
  194. else if (strcasecmp (mode, "out") == 0)
  195. pinMode (pin, OUTPUT) ;
  196. else if (strcasecmp (mode, "pwm") == 0)
  197. pinMode (pin, PWM_OUTPUT) ;
  198. else if (strcasecmp (mode, "up") == 0)
  199. pullUpDnControl (pin, PUD_UP) ;
  200. else if (strcasecmp (mode, "down") == 0)
  201. pullUpDnControl (pin, PUD_DOWN) ;
  202. else if (strcasecmp (mode, "tri") == 0)
  203. pullUpDnControl (pin, PUD_OFF) ;
  204. else
  205. {
  206. fprintf (stderr, "%s: Invalid mode: %s. Should be in/out/pwm/up/down/tri\n", argv [1], mode) ;
  207. exit (1) ;
  208. }
  209. }
  210. /*
  211. * doWrite:
  212. * gpio write pin value
  213. *********************************************************************************
  214. */
  215. void doWrite (int argc, char *argv [])
  216. {
  217. int pin, val ;
  218. if (argc != 4)
  219. {
  220. fprintf (stderr, "Usage: %s write pin value\n", argv [0]) ;
  221. exit (1) ;
  222. }
  223. pin = atoi (argv [2]) ;
  224. if ((wpMode == WPI_MODE_PINS) && ((pin < 0) || (pin >= NUM_PINS)))
  225. return ;
  226. val = atoi (argv [3]) ;
  227. /**/ if (val == 0)
  228. digitalWrite (pin, LOW) ;
  229. else
  230. digitalWrite (pin, HIGH) ;
  231. }
  232. /*
  233. * doRead:
  234. * Read a pin and return the value
  235. *********************************************************************************
  236. */
  237. void doRead (int argc, char *argv [])
  238. {
  239. int pin, val ;
  240. if (argc != 3)
  241. {
  242. fprintf (stderr, "Usage: %s read pin\n", argv [0]) ;
  243. exit (1) ;
  244. }
  245. pin = atoi (argv [2]) ;
  246. if ((wpMode == WPI_MODE_PINS) && ((pin < 0) || (pin >= NUM_PINS)))
  247. {
  248. printf ("0\n") ;
  249. return ;
  250. }
  251. val = digitalRead (pin) ;
  252. printf ("%s\n", val == 0 ? "0" : "1") ;
  253. }
  254. /*
  255. * doPwm:
  256. * Output a PWM value on a pin
  257. *********************************************************************************
  258. */
  259. void doPwm (int argc, char *argv [])
  260. {
  261. int pin, val ;
  262. if (argc != 4)
  263. {
  264. fprintf (stderr, "Usage: %s pwm <pin> <value>\n", argv [0]) ;
  265. exit (1) ;
  266. }
  267. pin = atoi (argv [2]) ;
  268. if ((wpMode == WPI_MODE_PINS) && ((pin < 0) || (pin >= NUM_PINS)))
  269. return ;
  270. val = atoi (argv [3]) ;
  271. pwmWrite (pin, val) ;
  272. }
  273. /*
  274. * main:
  275. * Start here
  276. *********************************************************************************
  277. */
  278. int main (int argc, char *argv [])
  279. {
  280. int i ;
  281. if (argc == 1)
  282. {
  283. fprintf (stderr, "%s: %s\n", argv [0], usage) ;
  284. return 1 ;
  285. }
  286. if (geteuid () != 0)
  287. {
  288. fprintf (stderr, "%s: Must be root to run\n", argv [0]) ;
  289. return 1 ;
  290. }
  291. if (strcasecmp (argv [1], "-v") == 0)
  292. {
  293. printf ("gpio version: %s\n", VERSION) ;
  294. printf ("Copyright (c) 2012 Gordon Henderson\n") ;
  295. printf ("This is free software with ABSOLUTELY NO WARRANTY.\n") ;
  296. return 0 ;
  297. }
  298. // Initial test for /sys/class/gpio operations:
  299. /**/ if (strcasecmp (argv [1], "exports" ) == 0)
  300. { doExports () ; return 0 ; }
  301. else if (strcasecmp (argv [1], "export" ) == 0)
  302. { doExport (argc, argv) ; return 0 ; }
  303. else if (strcasecmp (argv [1], "unexport") == 0)
  304. { doUnexport (argc, argv) ; return 0 ; }
  305. // Check for -g argument
  306. if (strcasecmp (argv [1], "-g") == 0)
  307. {
  308. if (wiringPiSetupGpio () == -1)
  309. {
  310. fprintf (stderr, "%s: Unable to initialise GPIO in GPIO mode.\n", argv [0]) ;
  311. exit (1) ;
  312. }
  313. for (i = 2 ; i < argc ; ++i)
  314. argv [i - 1] = argv [i] ;
  315. --argc ;
  316. wpMode = WPI_MODE_GPIO ;
  317. }
  318. else
  319. {
  320. if (wiringPiSetup () == -1)
  321. {
  322. fprintf (stderr, "%s: Unable to initialise GPIO in wiringPi mode\n", argv [0]) ;
  323. exit (1) ;
  324. }
  325. wpMode = WPI_MODE_PINS ;
  326. }
  327. /**/ if (strcasecmp (argv [1], "write" ) == 0)
  328. doWrite (argc, argv) ;
  329. else if (strcasecmp (argv [1], "read" ) == 0)
  330. doRead (argc, argv) ;
  331. else if (strcasecmp (argv [1], "mode" ) == 0)
  332. doMode (argc, argv) ;
  333. else if (strcasecmp (argv [1], "pwm" ) == 0)
  334. doPwm (argc, argv) ;
  335. else
  336. {
  337. fprintf (stderr, "%s: Unknown command: %s. (read/write/pwm/mode expected)\n", argv [0], argv [1]) ;
  338. exit (1) ;
  339. }
  340. return 0 ;
  341. }