diff --git a/VERSION b/VERSION index eb39e53..5a95802 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -3.3 +3.5 diff --git a/gpio/gpio.1 b/gpio/gpio.1 index 7b71596..bf5864a 100644 --- a/gpio/gpio.1 +++ b/gpio/gpio.1 @@ -48,7 +48,7 @@ high | low range .PP .B gpio -.B load \ i2c/spi ... +.B i2cd .PP .B gpio .B gbr @@ -67,8 +67,7 @@ converters on the Gertboard. It's designed for simple testing and diagnostic purposes, but can be used in shell scripts for general if somewhat slow control of the GPIO pins. -It can also control the IO's on the PiFace IO board and load the SPI and I2C -kernel modules if required. +It can also control the IO's on the PiFace IO board. .SH OPTIONS @@ -208,6 +207,10 @@ Change the PWM mode to balanced (the default) or mark:space ratio (traditional) Change the PWM range register. The default is 1024. .TP +.B i2cd +Executes i2c-detect for the default I2C port on the P1 connector. + +.TP .B gbr channel diff --git a/gpio/gpio.c b/gpio/gpio.c index af853ab..d468ed9 100644 --- a/gpio/gpio.c +++ b/gpio/gpio.c @@ -72,15 +72,11 @@ char *usage = "Usage: gpio -v\n" " gpio ...\n" " gpio \n" " gpio readall\n" -// " gpio unexportall/exports\n" -// " gpio export/edge/unexport ...\n" " gpio wfi \n" " gpio drive \n" " gpio pwm-bal/pwm-ms \n" " gpio pwmr \n" " gpio pwmc \n" - " gpio load spi/i2c\n" - " gpio unload spi/i2c\n" " gpio i2cd/i2cdetect\n" " gpio rbx/rbd\n" " gpio wb \n" @@ -110,287 +106,6 @@ static int decodePin (const char *str) #endif -/* - * 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. - ********************************************************************************* - */ - -static void changeOwner (char *cmd, char *file) -{ - uid_t uid = getuid () ; - uid_t gid = getgid () ; - - if (chown (file, uid, gid) != 0) - { - -// Removed (ignoring) the check for not existing as I'm fed-up with morons telling me that -// the warning message is an error. - - if (errno != ENOENT) - fprintf (stderr, "%s: Unable to change ownership of %s: %s\n", cmd, file, strerror (errno)) ; - } -} - - -/* - * moduleLoaded: - * Return true/false if the supplied module is loaded - ********************************************************************************* - */ - -static int moduleLoaded (char *modName) -{ - int len = strlen (modName) ; - int found = FALSE ; - FILE *fd = fopen ("/proc/modules", "r") ; - char line [80] ; - - if (fd == NULL) - { - fprintf (stderr, "gpio: Unable to check /proc/modules: %s\n", strerror (errno)) ; - exit (1) ; - } - - while (fgets (line, 80, fd) != NULL) - { - if (strncmp (line, modName, len) != 0) - continue ; - - found = TRUE ; - break ; - } - - fclose (fd) ; - - return found ; -} - - -/* - * doLoad: - * Load either the spi or i2c modules and change device ownerships, etc. - ********************************************************************************* - */ - -static void checkDevTree (char *argv []) -{ - struct stat statBuf ; - - if (stat ("/proc/device-tree", &statBuf) == 0) // We're on a devtree system ... - { - fprintf (stderr, -"%s: Unable to load/unload modules as this Pi has the device tree enabled.\n" -" You need to run the raspi-config program (as root) and select the\n" -" modules (SPI or I2C) that you wish to load/unload there and reboot.\n", argv [0]) ; - exit (1) ; - } -} - -static void _doLoadUsage (char *argv []) -{ - fprintf (stderr, "Usage: %s load [I2C baudrate in Kb/sec]\n", argv [0]) ; - exit (1) ; -} - -static void doLoad (int argc, char *argv []) -{ - char *module1, *module2 ; - char cmd [80] ; - char *file1, *file2 ; - char args1 [32], args2 [32] ; - - checkDevTree (argv) ; - - if (argc < 3) - _doLoadUsage (argv) ; - - args1 [0] = args2 [0] = 0 ; - - /**/ if (strcasecmp (argv [2], "spi") == 0) - { - module1 = "spidev" ; - module2 = "spi_bcm2708" ; - file1 = "/dev/spidev0.0" ; - file2 = "/dev/spidev0.1" ; - if (argc == 4) - { - fprintf (stderr, "%s: Unable to set the buffer size now. Load aborted. Please see the man page.\n", argv [0]) ; - exit (1) ; - } - else if (argc > 4) - _doLoadUsage (argv) ; - } - else if (strcasecmp (argv [2], "i2c") == 0) - { - module1 = "i2c_dev" ; - module2 = "i2c_bcm2708" ; - file1 = "/dev/i2c-0" ; - file2 = "/dev/i2c-1" ; - if (argc == 4) - sprintf (args2, " baudrate=%d", atoi (argv [3]) * 1000) ; - else if (argc > 4) - _doLoadUsage (argv) ; - } - else - _doLoadUsage (argv) ; - - if (findExecutable ("modprobe") == NULL) - printf ("No found\n") ; - - if (!moduleLoaded (module1)) - { - sprintf (cmd, "%s %s%s", findExecutable (MODPROBE), module1, args1) ; - int ret = system(cmd); - if (ret == -1) { - perror("Error executing command"); - } else if (WIFEXITED(ret)) { - int exit_status = WEXITSTATUS(ret); - if (exit_status != 0) { - fprintf(stderr, "Command failed with exit status %d\n", exit_status); - } - } else { - fprintf(stderr, "Command terminated by signal\n"); - } - } - - if (!moduleLoaded (module2)) - { - sprintf (cmd, "%s %s%s", findExecutable (MODPROBE), module2, args2) ; - int ret = system(cmd); - if (ret == -1) { - perror("Error executing command"); - } else if (WIFEXITED(ret)) { - int exit_status = WEXITSTATUS(ret); - if (exit_status != 0) { - fprintf(stderr, "Command failed with exit status %d\n", exit_status); - } - } else { - fprintf(stderr, "Command terminated by signal\n"); - } - } - - if (!moduleLoaded (module2)) - { - fprintf (stderr, "%s: Unable to load %s\n", argv [0], module2) ; - exit (1) ; - } - - sleep (1) ; // To let things get settled - - changeOwner (argv [0], file1) ; - changeOwner (argv [0], file2) ; -} - - -/* - * doUnLoad: - * Un-Load either the spi or i2c modules and change device ownerships, etc. - ********************************************************************************* - */ - -static void _doUnLoadUsage (char *argv []) -{ - fprintf (stderr, "Usage: %s unload \n", argv [0]) ; - exit (1) ; -} - -static void doUnLoad (int argc, char *argv []) -{ - char *module1, *module2 ; - char cmd [80] ; - - checkDevTree (argv) ; - - if (argc != 3) - _doUnLoadUsage (argv) ; - - /**/ if (strcasecmp (argv [2], "spi") == 0) - { - module1 = "spidev" ; - module2 = "spi_bcm2708" ; - } - else if (strcasecmp (argv [2], "i2c") == 0) - { - module1 = "i2c_dev" ; - module2 = "i2c_bcm2708" ; - } - else - _doUnLoadUsage (argv) ; - - if (moduleLoaded (module1)) - { - sprintf (cmd, "%s %s", findExecutable (RMMOD), module1) ; - int ret = system(cmd); - if (ret == -1) { - perror("Error executing command"); - } else if (WIFEXITED(ret)) { - int exit_status = WEXITSTATUS(ret); - if (exit_status != 0) { - fprintf(stderr, "Command failed with exit status %d\n", exit_status); - } - } else { - fprintf(stderr, "Command terminated by signal\n"); - } - } - - if (moduleLoaded (module2)) - { - sprintf (cmd, "%s %s", findExecutable (RMMOD), module2) ; - int ret = system(cmd); - if (ret == -1) { - perror("Error executing command"); - } else if (WIFEXITED(ret)) { - int exit_status = WEXITSTATUS(ret); - if (exit_status != 0) { - fprintf(stderr, "Command failed with exit status %d\n", exit_status); - } - } else { - fprintf(stderr, "Command terminated by signal\n"); - } - } -} - /* * doI2Cdetect: @@ -398,28 +113,19 @@ static void doUnLoad (int argc, char *argv []) ********************************************************************************* */ -static void doI2Cdetect (UNU int argc, char *argv []) +static void doI2Cdetect (const char *progName) { int port = piGpioLayout () == GPIO_LAYOUT_PI1_REV1 ? 0 : 1 ; - char *c, *command ; + char command[64]; - if ((c = findExecutable (I2CDETECT)) == NULL) - { - fprintf (stderr, "%s: Unable to find i2cdetect command: %s\n", argv [0], strerror (errno)) ; - return ; + snprintf(command, 64, "i2cdetect -y %d", port); + int ret = system(command); + if (ret < 0) { + fprintf (stderr, "%s: Unable to run i2cdetect: %s\n", progName, strerror(errno)); } - - if (!moduleLoaded ("i2c_dev")) - { - fprintf (stderr, "%s: The I2C kernel module(s) are not loaded.\n", argv [0]) ; - return ; + if (0x7F00 == (ret & 0xFF00)) { + fprintf (stderr, "%s: i2cdetect not found, please install i2c-tools\n", progName); } - - 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)) ; - } @@ -427,6 +133,10 @@ void SYSFS_DEPRECATED(const char *progName) { fprintf(stderr, "%s: GPIO Sysfs Interface for Userspace is deprecated (https://www.kernel.org/doc/Documentation/gpio/sysfs.txt).\n Function is now useless and empty.\n\n", progName); } +void LOAD_DEPRECATED(const char *progName) { + fprintf(stderr, "%s: load/unload modules is deprecated. You need to run the raspi-config program (as root) and select the interface option (SPI or I2C) that you wish to de-/activate.\n\n", progName); +} + /* * doExports: -> deprecated, removed * List all GPIO exports @@ -1269,7 +979,7 @@ int main (int argc, char *argv []) exit (EXIT_FAILURE) ; } -// Initial test for /sys/class/gpio operations: - -> deprecated, empty but still there +// Initial test for /sys/class/gpio operations: --> deprecated, empty but still there /**/ if (strcasecmp (argv [1], "exports" ) == 0) { SYSFS_DEPRECATED(argv[0]); return 0 ; } else if (strcasecmp (argv [1], "export" ) == 0) { SYSFS_DEPRECATED(argv[0]); return 0 ; } @@ -1277,10 +987,10 @@ int main (int argc, char *argv []) else if (strcasecmp (argv [1], "unexport" ) == 0) { SYSFS_DEPRECATED(argv[0]); return 0 ; } else if (strcasecmp (argv [1], "unexportall") == 0) { SYSFS_DEPRECATED(argv[0]); return 0 ; } -// Check for load command: +// Check for un-/load command: --> deprecated, empty but still there - if (strcasecmp (argv [1], "load" ) == 0) { doLoad (argc, argv) ; return 0 ; } - if (strcasecmp (argv [1], "unload" ) == 0) { doUnLoad (argc, argv) ; return 0 ; } + if (strcasecmp (argv [1], "load" ) == 0) { LOAD_DEPRECATED(argv[0]) ; return 0 ; } + if (strcasecmp (argv [1], "unload" ) == 0) { LOAD_DEPRECATED(argv[0]) ; return 0 ; } // Check for usb power command @@ -1413,8 +1123,8 @@ int main (int argc, char *argv []) else if (strcasecmp (argv [1], "nreadall" ) == 0) doReadall () ; else if (strcasecmp (argv [1], "pins" ) == 0) doReadall () ; else if (strcasecmp (argv [1], "qmode" ) == 0) doQmode (argc, argv) ; - else if (strcasecmp (argv [1], "i2cdetect") == 0) doI2Cdetect (argc, argv) ; - else if (strcasecmp (argv [1], "i2cd" ) == 0) doI2Cdetect (argc, argv) ; + else if (strcasecmp (argv [1], "i2cdetect") == 0) doI2Cdetect (argv [0]) ; + else if (strcasecmp (argv [1], "i2cd" ) == 0) doI2Cdetect (argv [0]) ; 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) ; diff --git a/version.h b/version.h index 6f3b26e..87082e3 100644 --- a/version.h +++ b/version.h @@ -1,3 +1,3 @@ -#define VERSION "3.3" +#define VERSION "3.5" #define VERSION_MAJOR 3 -#define VERSION_MINOR 3 +#define VERSION_MINOR 5