From owner-svn-src-all@freebsd.org Fri Mar 11 21:05:18 2016 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 7988BACDBEA; Fri, 11 Mar 2016 21:05:18 +0000 (UTC) (envelope-from gonzo@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 3A3CF1A94; Fri, 11 Mar 2016 21:05:18 +0000 (UTC) (envelope-from gonzo@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u2BL5HiP061933; Fri, 11 Mar 2016 21:05:17 GMT (envelope-from gonzo@FreeBSD.org) Received: (from gonzo@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u2BL5HTp061931; Fri, 11 Mar 2016 21:05:17 GMT (envelope-from gonzo@FreeBSD.org) Message-Id: <201603112105.u2BL5HTp061931@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: gonzo set sender to gonzo@FreeBSD.org using -f From: Oleksandr Tymoshenko Date: Fri, 11 Mar 2016 21:05:17 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r296682 - head/usr.sbin/gpioctl X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 11 Mar 2016 21:05:18 -0000 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 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 * Copyright (c) 2014, Rui Paulo + * Copyright (c) 2015, Emmanuel Vadot * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -40,6 +41,10 @@ __FBSDID("$FreeBSD$"); #include +#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]); /*