svn commit: r296682 - head/usr.sbin/gpioctl

Oleksandr Tymoshenko gonzo at FreeBSD.org
Fri Mar 11 21:05:18 UTC 2016


Author: gonzo
Date: Fri Mar 11 21:05:16 2016
New Revision: 296682
URL: https://svnweb.freebsd.org/changeset/base/296682

Log:
  Make it possible for operations to refer to GPIO pins by name
  
  - Try to guess what is provided as a pin spec for -t or for get/set
      operation: number or name. Fails in case of ambiguity.
  - Add -p and -N switches to force pin specification interpretation:
      -p forces spec to be pin number, -N forces it to be name
  
  Submitted by:	Emmanuel Vadot <manu at bidouilliste.com>
  Differential Revision:	https://reviews.freebsd.org/D5201

Modified:
  head/usr.sbin/gpioctl/gpioctl.8
  head/usr.sbin/gpioctl/gpioctl.c

Modified: head/usr.sbin/gpioctl/gpioctl.8
==============================================================================
--- head/usr.sbin/gpioctl/gpioctl.8	Fri Mar 11 21:00:14 2016	(r296681)
+++ head/usr.sbin/gpioctl/gpioctl.8	Fri Mar 11 21:05:16 2016	(r296682)
@@ -27,7 +27,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd March 8, 2015
+.Dd March 11, 2016
 .Dt GPIOCTL 1
 .Os
 .Sh NAME
@@ -40,21 +40,25 @@
 .Op Fl v
 .Nm
 .Op Fl f Ar ctldev
+.Op Fl pN
 .Cm -t
 .Ar pin
 .Nm
 .Op Fl f Ar ctldev
+.Op Fl pN
 .Cm -c
 .Ar pin
 .Ar flag
 .Op flag ...
 .Nm
 .Op Fl f Ar ctldev
+.Op Fl pN
 .Cm -n
 .Ar pin
 .Ar pin-name
 .Nm
 .Op Cm -f Ar ctldev
+.Op Fl pN
 .Ar pin
 .Ar [0|1]
 .Sh DESCRIPTION
@@ -62,6 +66,20 @@ The
 .Nm
 utility could be used to manage GPIO pins from userland and list available pins.
 .Pp
+The
+.Pa pin
+argument can either be a
+.Pa pin-number
+or a
+.Pa pin-name .
+If it is a number and a pin has this number as its name and you did not use
+.Fl N
+or
+.Fl p
+, then
+.Nm
+exits.
+.Pp
 The options are as follows:
 .Bl -tag -width ".Fl f Ar ctldev"
 .It Fl c Ar pin Ar flag Op flag ...
@@ -96,9 +114,17 @@ list available pins
 .It Fl n Ar pin Ar pin-name
 set the name used to describe the pin
 .It Fl t Ar pin
-toggle value of provided pin number
+toggle value of provided pin
 .It Fl v
 be verbose: for each listed pin print current configuration
+.It Fl p
+Force
+.Pa pin
+to be interpreted as a pin number
+.It Fl N
+Force
+.Pa pin
+to be interpreted as a pin name
 .El
 .Sh EXAMPLES
 .Bl -bullet
@@ -114,6 +140,18 @@ gpioctl -f /dev/gpioc0 12 1
 Configure pin 12 to be input pin
 .Pp
 gpioctl -f /dev/gpioc0 -c 12 IN
+.It
+Set the name of pin 12 to test
+.Pp
+gpioctl -f /dev/gpioc0 -n 12 test
+.It
+Toggle the value the pin named test
+.Pp
+gpioctl -f /dev/gpioc0 -t test
+.It
+Toggle the value of pin number 12 even if another pin has the name 12
+.Pp
+gpioctl -f /dev/gpioc0 -pt 12
 .El
 .Sh SEE ALSO
 .Xr gpio 4 ,

Modified: head/usr.sbin/gpioctl/gpioctl.c
==============================================================================
--- head/usr.sbin/gpioctl/gpioctl.c	Fri Mar 11 21:00:14 2016	(r296681)
+++ head/usr.sbin/gpioctl/gpioctl.c	Fri Mar 11 21:05:16 2016	(r296682)
@@ -1,6 +1,7 @@
 /*-
  * Copyright (c) 2009, Oleksandr Tymoshenko <gonzo at FreeBSD.org>
  * Copyright (c) 2014, Rui Paulo <rpaulo at FreeBSD.org>
+ * Copyright (c) 2015, Emmanuel Vadot <manu at bidouilliste.com>
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -40,6 +41,10 @@ __FBSDID("$FreeBSD$");
 
 #include <libgpio.h>
 
+#define PIN_TYPE_UNKNOWN	0
+#define PIN_TYPE_NUMBER		1
+#define PIN_TYPE_NAME		2
+
 struct flag_desc {
 	const char *name;
 	uint32_t flag;
@@ -66,10 +71,10 @@ usage(void)
 {
 	fprintf(stderr, "Usage:\n");
 	fprintf(stderr, "\tgpioctl [-f ctldev] -l [-v]\n");
-	fprintf(stderr, "\tgpioctl [-f ctldev] -t pin\n");
-	fprintf(stderr, "\tgpioctl [-f ctldev] -c pin flag ...\n");
-	fprintf(stderr, "\tgpioctl [-f ctldev] -n pin pin-name\n");
-	fprintf(stderr, "\tgpioctl [-f ctldev] pin [0|1]\n");
+	fprintf(stderr, "\tgpioctl [-f ctldev] [-pN] -t pin\n");
+	fprintf(stderr, "\tgpioctl [-f ctldev] [-pN] -c pin flag ...\n");
+	fprintf(stderr, "\tgpioctl [-f ctldev] [-pN] -n pin pin-name\n");
+	fprintf(stderr, "\tgpioctl [-f ctldev] [-pN] pin [0|1]\n");
 	exit(1);
 }
 
@@ -163,6 +168,32 @@ dump_pins(gpio_handle_t handle, int verb
 	free(cfgs);
 }
 
+static int
+get_pinnum_by_name(gpio_handle_t handle, const char *name) {
+	int i, maxpin, pinn;
+	gpio_config_t *cfgs;
+	gpio_config_t *pin;
+
+	pinn = -1;
+	maxpin = gpio_pin_list(handle, &cfgs);
+	if (maxpin < 0) {
+		perror("gpio_pin_list");
+		exit(1);
+	}
+
+	for (i = 0; i <= maxpin; i++) {
+		pin = cfgs + i;
+		gpio_pin_get(handle, pin->g_pin);
+		if (!strcmp(name, pin->g_name)) {
+			pinn = i;
+			break;
+		}
+	}
+	free(cfgs);
+
+	return pinn;
+}
+
 static void
 fail(const char *fmt, ...)
 {
@@ -181,19 +212,16 @@ main(int argc, char **argv)
 	gpio_config_t pin;
 	gpio_handle_t handle;
 	char *ctlfile = NULL;
-	int pinn, pinv, ch;
+	int pinn, pinv, pin_type, ch;
 	int flags, flag, ok;
 	int config, list, name, toggle, verbose;
 
-	config = toggle = verbose = list = name = pinn = 0;
+	config = toggle = verbose = list = name = pin_type = 0;
 
-	while ((ch = getopt(argc, argv, "c:f:ln:t:v")) != -1) {
+	while ((ch = getopt(argc, argv, "cf:lntvNp")) != -1) {
 		switch (ch) {
 		case 'c':
 			config = 1;
-			pinn = str2int(optarg, &ok);
-			if (!ok)
-				fail("Invalid pin number: %s\n", optarg);
 			break;
 		case 'f':
 			ctlfile = optarg;
@@ -203,15 +231,15 @@ main(int argc, char **argv)
 			break;
 		case 'n':
 			name = 1;
-			pinn = str2int(optarg, &ok);
-			if (!ok)
-				fail("Invalid pin number: %s\n", optarg);
+			break;
+		case 'N':
+			pin_type = PIN_TYPE_NAME;
+			break;
+		case'p':
+			pin_type = PIN_TYPE_NUMBER;
 			break;
 		case 't':
 			toggle = 1;
-			pinn = str2int(optarg, &ok);
-			if (!ok)
-				fail("Invalid pin number: %s\n", optarg);
 			break;
 		case 'v':
 			verbose = 1;
@@ -232,33 +260,58 @@ main(int argc, char **argv)
 		exit(1);
 	}
 
+	if (list) {
+		dump_pins(handle, verbose);
+		gpio_close(handle);
+		exit(0);
+	}
+
+	if (argc == 0)
+		usage();
+
+	/* Find the pin number by the name */
+	switch (pin_type) {
+	case PIN_TYPE_UNKNOWN:
+		/* First test if it is a pin number */
+		pinn = str2int(argv[0], &ok);
+		if (ok) {
+			/* Test if we have any pin named by this number and tell the user */
+			if (get_pinnum_by_name(handle, argv[0]) != -1)
+				fail("%s is also a pin name, use -p or -N\n", argv[0]);
+		} else {
+			/* Test if it is a name */
+			if ((pinn = get_pinnum_by_name(handle, argv[0])) == -1)
+				fail("Can't find pin named \"%s\"\n", argv[0]);
+		}
+		break;
+	case PIN_TYPE_NUMBER:
+		pinn = str2int(argv[0], &ok);
+		if (!ok)
+			fail("Invalid pin number: %s\n", argv[0]);
+		break;
+	case PIN_TYPE_NAME:
+		if ((pinn = get_pinnum_by_name(handle, argv[0])) == -1)
+			fail("Can't find pin named \"%s\"\n", argv[0]);
+		break;
+	}
+
 	/* Set the pin name. */
 	if (name) {
-		if (argc == 0) {
+		if (argc != 2)
 			usage();
-			exit(1);
-		}
-		if (gpio_pin_set_name(handle, pinn, argv[0]) < 0) {
+		if (gpio_pin_set_name(handle, pinn, argv[1]) < 0) {
 			perror("gpio_pin_set_name");
 			exit(1);
 		}
 		exit(0);
 	}
 
-	if (list) {
-		dump_pins(handle, verbose);
-		gpio_close(handle);
-		exit(0);
-	}
-
 	if (toggle) {
 		/*
-		 * -t pin assumes no additional arguments
-		 */
-		if (argc > 0) {
+                * -t pin assumes no additional arguments
+                */
+		if (argc > 1)
 			usage();
-			exit(1);
-		}
 		if (gpio_pin_toggle(handle, pinn) < 0) {
 			perror("gpio_pin_toggle");
 			exit(1);
@@ -269,7 +322,7 @@ main(int argc, char **argv)
 
 	if (config) {
 		flags = 0;
-		for (i = 0; i < argc; i++) {
+		for (i = 1; i < argc; i++) {
 			flag = 	str2cap(argv[i]);
 			if (flag < 0)
 				fail("Invalid flag: %s\n", argv[i]);
@@ -287,14 +340,8 @@ main(int argc, char **argv)
 	/*
 	 * Last two cases - set value or print value
 	 */
-	if ((argc == 0) || (argc > 2)) {
+	if ((argc == 0) || (argc > 2))
 		usage();
-		exit(1);
-	}
-
-	pinn = str2int(argv[0], &ok);
-	if (!ok)
-		fail("Invalid pin number: %s\n", argv[0]);
 
 	/*
 	 * Read pin value
@@ -311,7 +358,7 @@ main(int argc, char **argv)
 
 	/* Is it valid number (0 or 1) ? */
 	pinv = str2int(argv[1], &ok);
-	if (!ok || ((pinv != 0) && (pinv != 1)))
+	if (ok == 0 || ((pinv != 0) && (pinv != 1)))
 		fail("Invalid pin value: %s\n", argv[1]);
 
 	/*


More information about the svn-src-all mailing list