Gordons Projects

--> Projects Top-Level GIT

A new version of wiringPi. Added in more stuff and fixed it up
[wiringPi] / gpio / gpio.c
index 6162090..c954f3b 100644 (file)
@@ -57,6 +57,8 @@ extern void doPins       (void) ;
 
 #define        PI_USB_POWER_CONTROL    38
 #define        I2CDETECT               "/usr/sbin/i2cdetect"
 
 #define        PI_USB_POWER_CONTROL    38
 #define        I2CDETECT               "/usr/sbin/i2cdetect"
+#define        MODPROBE                "/sbin/modprobe"
+#define        RMMOD                   "/sbin/rmmod"
 
 int wpMode ;
 
 
 int wpMode ;
 
@@ -65,6 +67,7 @@ char *usage = "Usage: gpio -v\n"
               "       gpio [-g|-1] [-x extension:params] ...\n"
               "       gpio [-p] <read/write/wb> ...\n"
               "       gpio <read/write/aread/awritewb/pwm/clock/mode> ...\n"
               "       gpio [-g|-1] [-x extension:params] ...\n"
               "       gpio [-p] <read/write/wb> ...\n"
               "       gpio <read/write/aread/awritewb/pwm/clock/mode> ...\n"
+              "       gpio <toggle/blink> <pin>\n"
              "       gpio readall/reset\n"
              "       gpio unexportall/exports\n"
              "       gpio export/edge/unexport ...\n"
              "       gpio readall/reset\n"
              "       gpio unexportall/exports\n"
              "       gpio export/edge/unexport ...\n"
@@ -76,6 +79,8 @@ char *usage = "Usage: gpio -v\n"
              "       gpio load spi/i2c\n"
              "       gpio unload spi/i2c\n"
              "       gpio i2cd/i2cdetect\n"
              "       gpio load spi/i2c\n"
              "       gpio unload spi/i2c\n"
              "       gpio i2cd/i2cdetect\n"
+             "       gpio rbx/rbd\n"
+             "       gpio wb <value>\n"
              "       gpio usbp high/low\n"
              "       gpio gbr <channel>\n"
              "       gpio gbw <channel> <value>" ;     // No trailing newline needed here.
              "       gpio usbp high/low\n"
              "       gpio gbr <channel>\n"
              "       gpio gbw <channel> <value>" ;     // No trailing newline needed here.
@@ -103,6 +108,45 @@ static int decodePin (const char *str)
 
 
 /*
 
 
 /*
+ * findExecutable:
+ *     Code to locate the path to the given executable. We have a fixed list
+ *     of locations to try which completely overrides any $PATH environment.
+ *     This may be detrimental, however it avoids the reliance on $PATH
+ *     which may be a security issue when this program is run a set-uid-root.
+ *********************************************************************************
+ */
+
+static const char *searchPath [] =
+{
+  "/sbin",
+  "/usr/sbin",
+  "/bin",
+  "/usr/bin",
+  NULL,
+} ;
+
+static char *findExecutable (const char *progName)
+{
+  static char *path = NULL ;
+  int len = strlen (progName) ;
+  int i = 0 ;
+  struct stat statBuf ;
+
+  for (i = 0 ; searchPath [i] != NULL ; ++i)
+  {
+    path = malloc (strlen (searchPath [i]) + len + 2) ;
+    sprintf (path, "%s/%s", searchPath [i], progName) ;
+
+    if (stat (path, &statBuf) == 0)
+      return path ;
+    free (path) ;
+  }
+
+  return NULL ;
+}
+
+
+/*
  * changeOwner:
  *     Change the ownership of the file to the real userId of the calling
  *     program so we can access it.
  * changeOwner:
  *     Change the ownership of the file to the real userId of the calling
  *     program so we can access it.
@@ -230,15 +274,18 @@ static void doLoad (int argc, char *argv [])
   else
     _doLoadUsage (argv) ;
 
   else
     _doLoadUsage (argv) ;
 
+  if (findExecutable ("modprobe") == NULL)
+    printf ("No found\n") ;
+
   if (!moduleLoaded (module1))
   {
   if (!moduleLoaded (module1))
   {
-    sprintf (cmd, "/sbin/modprobe %s%s", module1, args1) ;
+    sprintf (cmd, "%s %s%s", findExecutable (MODPROBE), module1, args1) ;
     system (cmd) ;
   }
 
   if (!moduleLoaded (module2))
   {
     system (cmd) ;
   }
 
   if (!moduleLoaded (module2))
   {
-    sprintf (cmd, "/sbin/modprobe %s%s", module2, args2) ;
+    sprintf (cmd, "%s %s%s", findExecutable (MODPROBE), module2, args2) ;
     system (cmd) ;
   }
 
     system (cmd) ;
   }
 
@@ -292,13 +339,13 @@ static void doUnLoad (int argc, char *argv [])
 
   if (moduleLoaded (module1))
   {
 
   if (moduleLoaded (module1))
   {
-    sprintf (cmd, "/sbin/rmmod %s", module1) ;
+    sprintf (cmd, "%s %s", findExecutable (RMMOD), module1) ;
     system (cmd) ;
   }
 
   if (moduleLoaded (module2))
   {
     system (cmd) ;
   }
 
   if (moduleLoaded (module2))
   {
-    sprintf (cmd, "/sbin/rmmod %s", module2) ;
+    sprintf (cmd, "%s %s", findExecutable (RMMOD), module2) ;
     system (cmd) ;
   }
 }
     system (cmd) ;
   }
 }
@@ -312,11 +359,10 @@ static void doUnLoad (int argc, char *argv [])
 
 static void doI2Cdetect (int argc, char *argv [])
 {
 
 static void doI2Cdetect (int argc, char *argv [])
 {
-  int port = piBoardRev () == 1 ? 0 : 1 ;
-  char command [128] ;
-  struct stat statBuf ;
+  int port = piGpioLayout () == 1 ? 0 : 1 ;
+  char *c, *command ;
 
 
-  if (stat (I2CDETECT, &statBuf) < 0)
+  if ((c = findExecutable (I2CDETECT)) == NULL)
   {
     fprintf (stderr, "%s: Unable to find i2cdetect command: %s\n", argv [0], strerror (errno)) ;
     return ;
   {
     fprintf (stderr, "%s: Unable to find i2cdetect command: %s\n", argv [0], strerror (errno)) ;
     return ;
@@ -328,7 +374,8 @@ static void doI2Cdetect (int argc, char *argv [])
     return ;
   }
 
     return ;
   }
 
-  sprintf (command, "%s -y %d", I2CDETECT, port) ;
+  command = malloc (strlen (c) + 16) ;
+  sprintf (command, "%s -y %d", c, port) ;
   if (system (command) < 0)
     fprintf (stderr, "%s: Unable to run i2cdetect: %s\n", argv [0], strerror (errno)) ;
 
   if (system (command) < 0)
     fprintf (stderr, "%s: Unable to run i2cdetect: %s\n", argv [0], strerror (errno)) ;
 
@@ -943,7 +990,7 @@ static void doAwrite (int argc, char *argv [])
 
 /*
  * doWriteByte:
 
 /*
  * doWriteByte:
- *     gpio write value
+ *     gpio wb value
  *********************************************************************************
  */
 
  *********************************************************************************
  */
 
@@ -964,6 +1011,30 @@ static void doWriteByte (int argc, char *argv [])
 
 
 /*
 
 
 /*
+ * doReadByte:
+ *     gpio rbx|rbd value
+ *********************************************************************************
+ */
+
+static void doReadByte (int argc, char *argv [], int printHex)
+{
+  int val ;
+
+  if (argc != 2)
+  {
+    fprintf (stderr, "Usage: %s rbx|rbd\n", argv [0]) ;
+    exit (1) ;
+  }
+
+  val = digitalReadByte () ;
+  if (printHex)
+    printf ("%02X\n", val) ;
+  else
+    printf ("%d\n", val) ;
+}
+
+
+/*
  * doRead:
  *     Read a pin and return the value
  *********************************************************************************
  * doRead:
  *     Read a pin and return the value
  *********************************************************************************
@@ -1027,6 +1098,34 @@ void doToggle (int argc, char *argv [])
 
 
 /*
 
 
 /*
+ * doBlink:
+ *     Blink an IO pin
+ *********************************************************************************
+ */
+
+void doBlink (int argc, char *argv [])
+{
+  int pin ;
+
+  if (argc != 3)
+  {
+    fprintf (stderr, "Usage: %s blink pin\n", argv [0]) ;
+    exit (1) ;
+  }
+
+  pin = atoi (argv [2]) ;
+
+  pinMode (pin, OUTPUT) ;
+  for (;;)
+  {
+    digitalWrite (pin, !digitalRead (pin)) ;
+    delay (500) ;
+  }
+
+}
+
+
+/*
  * doPwmTone:
  *     Output a tone in a PWM pin
  *********************************************************************************
  * doPwmTone:
  *     Output a tone in a PWM pin
  *********************************************************************************
@@ -1162,6 +1261,8 @@ static void doVersion (char *argv [])
 {
   int model, rev, mem, maker, warranty ;
   struct stat statBuf ;
 {
   int model, rev, mem, maker, warranty ;
   struct stat statBuf ;
+  char name [80] ;
+  FILE *fd ;
 
   printf ("gpio version: %s\n", VERSION) ;
   printf ("Copyright (c) 2012-2015 Gordon Henderson\n") ;
 
   printf ("gpio version: %s\n", VERSION) ;
   printf ("Copyright (c) 2012-2015 Gordon Henderson\n") ;
@@ -1179,12 +1280,18 @@ static void doVersion (char *argv [])
   if (stat ("/proc/device-tree", &statBuf) == 0)       // We're on a devtree system ...
     printf ("  * Device tree is enabled.\n") ;
 
   if (stat ("/proc/device-tree", &statBuf) == 0)       // We're on a devtree system ...
     printf ("  * Device tree is enabled.\n") ;
 
-  if (stat ("/dev/gpiomem", &statBuf) == 0)            // User level GPIO is GO
+  if (stat ("/proc/device-tree/model", &statBuf) == 0) // Output Kernel idea of board type
   {
   {
-    printf ("  * This Raspberry Pi supports user-level GPIO access.\n") ;
-    printf ("    -> See the man-page for more details\n") ;
-    printf ("    -> ie. export WIRINGPI_GPIOMEM=1\n") ;
+    if ((fd = fopen ("/proc/device-tree/model", "r")) != NULL)
+    {
+      fgets (name, 80, fd) ;
+      fclose (fd) ;
+      printf ("  *--> %s\n", name) ;
+    }
   }
   }
+
+  if (stat ("/dev/gpiomem", &statBuf) == 0)            // User level GPIO is GO
+    printf ("  * This Raspberry Pi supports user-level GPIO access.\n") ;
   else
     printf ("  * Root or sudo required for GPIO access.\n") ;
 }
   else
     printf ("  * Root or sudo required for GPIO access.\n") ;
 }
@@ -1225,7 +1332,7 @@ int main (int argc, char *argv [])
 
   if ((strcmp (argv [1], "-R") == 0) || (strcmp (argv [1], "-V") == 0))
   {
 
   if ((strcmp (argv [1], "-R") == 0) || (strcmp (argv [1], "-V") == 0))
   {
-    printf ("%d\n", piBoardRev ()) ;
+    printf ("%d\n", piGpioLayout ()) ;
     return 0 ;
   }
 
     return 0 ;
   }
 
@@ -1375,6 +1482,7 @@ int main (int argc, char *argv [])
 // GPIO Nicies
 
   else if (strcasecmp (argv [1], "toggle" ) == 0) doToggle    (argc, argv) ;
 // GPIO Nicies
 
   else if (strcasecmp (argv [1], "toggle" ) == 0) doToggle    (argc, argv) ;
+  else if (strcasecmp (argv [1], "blink"  ) == 0) doBlink     (argc, argv) ;
 
 // Pi Specifics
 
 
 // Pi Specifics
 
@@ -1391,6 +1499,8 @@ int main (int argc, char *argv [])
   else if (strcasecmp (argv [1], "i2cd"     ) == 0) doI2Cdetect  (argc, argv) ;
   else if (strcasecmp (argv [1], "reset"    ) == 0) doReset      (argv [0]) ;
   else if (strcasecmp (argv [1], "wb"       ) == 0) doWriteByte  (argc, argv) ;
   else if (strcasecmp (argv [1], "i2cd"     ) == 0) doI2Cdetect  (argc, argv) ;
   else if (strcasecmp (argv [1], "reset"    ) == 0) doReset      (argv [0]) ;
   else if (strcasecmp (argv [1], "wb"       ) == 0) doWriteByte  (argc, argv) ;
+  else if (strcasecmp (argv [1], "rbx"      ) == 0) doReadByte   (argc, argv, TRUE) ;
+  else if (strcasecmp (argv [1], "rbd"      ) == 0) doReadByte   (argc, argv, FALSE) ;
   else if (strcasecmp (argv [1], "clock"    ) == 0) doClock      (argc, argv) ;
   else if (strcasecmp (argv [1], "wfi"      ) == 0) doWfi        (argc, argv) ;
   else
   else if (strcasecmp (argv [1], "clock"    ) == 0) doClock      (argc, argv) ;
   else if (strcasecmp (argv [1], "wfi"      ) == 0) doWfi        (argc, argv) ;
   else