update for the v3+

This commit is contained in:
Gordon Henderson 2018-03-14 07:17:04 +00:00
parent 96344ff712
commit 8d188fa0e0
17 changed files with 281 additions and 154 deletions

View File

@ -19,13 +19,6 @@ then run the ldconfig command.
sudo ldconfig sudo ldconfig
If you want to install a static library, you may need to do this manually:
cd wiringPi
make static
sudo make install-static
To un-install wiringPi: To un-install wiringPi:
./build uninstall ./build uninstall

View File

@ -1 +1 @@
2.44 2.46

3
build
View File

@ -64,6 +64,9 @@ if [ x$1 = "xclean" ]; then
echo -n "PiGlow: " ; make clean echo -n "PiGlow: " ; make clean
cd ../scrollPhat cd ../scrollPhat
echo -n "scrollPhat: " ; make clean echo -n "scrollPhat: " ; make clean
cd ../..
echo -n "Deb: " ; rm -f debian-template/wiringpi*.deb
echo
exit exit
fi fi

View File

@ -1,5 +1,5 @@
Package: wiringpi Package: wiringpi
Version: 2.44 Version: 2.46
Section: libraries Section: libraries
Priority: optional Priority: optional
Architecture: armhf Architecture: armhf

View File

@ -1,7 +1,9 @@
/* /*
* pins.c: * blink-thread.c:
* Just display a handy Pi pinnout diagram. * Standard "blink" program in wiringPi. Blinks an LED connected
* Copyright (c) 2012-2017 Gordon Henderson * to the first GPIO pin.
*
* Copyright (c) 2012-2013 Gordon Henderson. <projects@drogon.net>
*********************************************************************** ***********************************************************************
* This file is part of wiringPi: * This file is part of wiringPi:
* https://projects.drogon.net/raspberry-pi/wiringpi/ * https://projects.drogon.net/raspberry-pi/wiringpi/
@ -21,13 +23,39 @@
*********************************************************************** ***********************************************************************
*/ */
#include <stdio.h> #include <stdio.h>
#include <wiringPi.h>
void doPins (void) // LED Pin - wiringPi pin 0 is BCM_GPIO 17.
#define LED 0
PI_THREAD (blinky)
{ {
printf ("The pins command has been deprecated - sorry. Please use the\n") ; for (;;)
printf (" gpio readall\n") ; {
printf ("command to get a list of the pinnouts for your Pi.\n") ; digitalWrite (LED, HIGH) ; // On
delay (500) ; // mS
digitalWrite (LED, LOW) ; // Off
delay (500) ;
}
} }
int main (void)
{
printf ("Raspberry Pi blink\n") ;
wiringPiSetup () ;
pinMode (LED, OUTPUT) ;
piThreadCreate (blinky) ;
for (;;)
{
printf ("Hello, world\n") ;
delay (600) ;
}
return 0 ;
}

View File

@ -25,7 +25,6 @@
#include <stdio.h> #include <stdio.h>
#include <unistd.h> #include <unistd.h>
#include <wiringPi.h>
#include <sys/time.h> #include <sys/time.h>
@ -34,17 +33,13 @@
int main() int main()
{ {
int x ; int x ;
struct timeval t1, t2 ; struct timeval t1, t2, t3 ;
int t ; int t ;
int max, min ; int max, min ;
int del ; int del ;
int underRuns, overRuns, exactRuns, total ; int underRuns, overRuns, exactRuns, bogusRuns, total ;
int descheds ; int descheds ;
if (wiringPiSetup () == -1)
return 1 ;
piHiPri (10) ; sleep (1) ;
// Baseline test // Baseline test
@ -58,21 +53,22 @@ int main()
{ {
underRuns = overRuns = exactRuns = total = 0 ; underRuns = overRuns = exactRuns = total = 0 ;
descheds = 0 ; descheds = 0 ;
max = del ; max = 0 ;
min = del ; min = 999 ;
for (x = 0 ; x < CYCLES ; ++x) for (x = 0 ; x < CYCLES ; ++x)
{ {
for (;;) // Repeat this if we get a delay over 999uS for (;;) // Repeat this if we get a delay over 999uS
{ // -> High probability Linux has deschedulled us { // -> High probability Linux has deschedulled us
gettimeofday (&t1, NULL) ; gettimeofday (&t1, NULL) ;
delayMicroseconds (del) ; usleep (del) ;
// delayMicroseconds (del) ;
gettimeofday (&t2, NULL) ; gettimeofday (&t2, NULL) ;
if (t2.tv_usec < t1.tv_usec) // Counter wrapped timersub (&t2, &t1, &t3) ;
t = (1000000 + t2.tv_usec) - t1.tv_usec;
else t = t3.tv_usec ;
t = t2.tv_usec - t1.tv_usec ;
if (t > 999) if (t > 999)
{ {
++descheds ; ++descheds ;
@ -82,25 +78,24 @@ int main()
break ; break ;
} }
if (t > max) if (t == del)
{
max = t ;
++overRuns ;
}
else if (t < min)
{
min = t ;
++underRuns ;
}
else
++exactRuns ; ++exactRuns ;
else if (t < del)
++underRuns ;
else if (t > del)
++overRuns ;
if (t > max)
max = t ;
else if (t < min)
min = t ;
total += t ; total += t ;
} }
printf ("Delay: %3d. Min: %3d, Max: %3d, Unders: %3d, Overs: %3d, Exacts: %3d, Average: %3d, Descheds: %2d\n", printf ("Delay: %3d. Min: %3d, Max: %3d, Unders: %3d, Overs: %3d, Exacts: %3d, Average: %3d, Descheds: %2d\n",
del, min, max, underRuns, overRuns, exactRuns, total / CYCLES, descheds) ; del, min, max, underRuns, overRuns, exactRuns, total / CYCLES, descheds) ;
fflush (stdout) ; fflush (stdout) ;
delay (1) ; usleep (1000) ;
} }
return 0 ; return 0 ;

View File

@ -42,7 +42,7 @@ LIBS = -lwiringPi -lwiringPiDev -lpthread -lrt -lm -lcrypt
# May not need to alter anything below this line # May not need to alter anything below this line
############################################################################### ###############################################################################
SRC = gpio.c readall.c pins.c SRC = gpio.c readall.c
OBJ = $(SRC:.c=.o) OBJ = $(SRC:.c=.o)
@ -77,22 +77,22 @@ ifneq ($(WIRINGPI_SUID),0)
$Q chown root.root $(DESTDIR)$(PREFIX)/bin/gpio $Q chown root.root $(DESTDIR)$(PREFIX)/bin/gpio
$Q chmod 4755 $(DESTDIR)$(PREFIX)/bin/gpio $Q chmod 4755 $(DESTDIR)$(PREFIX)/bin/gpio
endif endif
$Q mkdir -p $(DESTDIR)$(PREFIX)/man/man1 $Q mkdir -p $(DESTDIR)$(PREFIX)/share/man/man1
$Q cp gpio.1 $(DESTDIR)$(PREFIX)/man/man1 $Q cp gpio.1 $(DESTDIR)$(PREFIX)/share/man/man1
.PHONY: install-deb .PHONY: install-deb
install-deb: gpio install-deb: gpio
$Q echo "[Install: deb]" $Q echo "[Install: deb]"
$Q install -m 0755 -d ~/wiringPi/debian-template/wiringPi/usr/bin $Q install -m 0755 -d ~/wiringPi/debian-template/wiringPi/usr/bin
$Q install -m 0755 gpio ~/wiringPi/debian-template/wiringPi/usr/bin $Q install -m 0755 gpio ~/wiringPi/debian-template/wiringPi/usr/bin
$Q install -m 0755 -d ~/wiringPi/debian-template/wiringPi/man/man1 $Q install -m 0755 -d ~/wiringPi/debian-template/wiringPi/usr/share/man/man1
$Q install -m 0644 gpio.1 ~/wiringPi/debian-template/wiringPi/man/man1 $Q install -m 0644 gpio.1 ~/wiringPi/debian-template/wiringPi/usr/share/man/man1
.PHONY: uninstall .PHONY: uninstall
uninstall: uninstall:
$Q echo "[UnInstall]" $Q echo "[UnInstall]"
$Q rm -f $(DESTDIR)$(PREFIX)/bin/gpio $Q rm -f $(DESTDIR)$(PREFIX)/bin/gpio
$Q rm -f $(DESTDIR)$(PREFIX)/man/man1/gpio.1 $Q rm -f $(DESTDIR)$(PREFIX)/share/man/man1/gpio.1
.PHONY: depend .PHONY: depend
depend: depend:

View File

@ -1,4 +1,4 @@
.TH GPIO 1 "September 2015" wiringPi "Command-Line access to Raspberry Pi's GPIO" .TH GPIO 1 "March 2018" wiringPi "Command-Line access to Raspberry Pi's GPIO"
.SH NAME .SH NAME
gpio \- Command-line access to Raspberry Pi's GPIO gpio \- Command-line access to Raspberry Pi's GPIO
@ -9,7 +9,7 @@ gpio \- Command-line access to Raspberry Pi's GPIO
.PP .PP
.B gpio .B gpio
.B [ \-g | \-1 ] .B [ \-g | \-1 ]
.B mode/read/write/aread/awrite/wb/pwm/clock/toggle/blink ... .B mode/read/write/aread/awrite/wb/pwm/pwnTone/clock/toggle/blink ...
.PP .PP
.B gpio .B gpio
.B [ \-x extension:params ] .B [ \-x extension:params ]
@ -21,6 +21,11 @@ gpio \- Command-line access to Raspberry Pi's GPIO
.B ... .B ...
.PP .PP
.B gpio .B gpio
.B [ \-p ]
.B pwnTone pin frequency
.B ...
.PP
.B gpio
.B readall .B readall
.PP .PP
.B gpio .B gpio
@ -256,30 +261,6 @@ Change the PWM mode to balanced (the default) or mark:space ratio (traditional)
.B pwmr .B pwmr
Change the PWM range register. The default is 1024. Change the PWM range register. The default is 1024.
.TP
.B load i2c [baudrate]
This loads the i2c or drivers into the kernel and changes the permissions
on the associated /dev/ entries so that the current user has access to
them. Optionally it will set the I2C baudrate to that supplied in Kb/sec
(or as close as the Pi can manage) The default speed is 100Kb/sec.
Note: On recent kernels with the device tree enabled you should use the
raspi-config program to load/unload the I2C device at boot time.
.TP
.B load spi
This loads the spi drivers into the kernel and changes the permissions
on the associated /dev/ entries so that the current user has access to
them. It used to have the ability to change the buffer size from the
default of 4096 bytes to an arbitrary value, however for some time the
Pi Foundation have compiled the SPI device driver into the kernel and
this has fixed the buffer size. The way to change it now is to edit
the /boot/cmdline.txt file and add on spdev.bufsiz=8192 to set it to
e.g. 8192 bytes then reboot.
Note: On recent kernels with the device tree enabled you should use the
raspi-config program to load/unload the SPI device at boot time.
.TP .TP
.B gbr .B gbr
channel channel
@ -360,7 +341,7 @@ Please report bugs to <projects@drogon.net>
.SH COPYRIGHT .SH COPYRIGHT
Copyright (c) 2012-2015 Gordon Henderson Copyright (c) 2012-2018 Gordon Henderson
This is free software; see the source for copying conditions. There is NO This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

View File

@ -2,7 +2,7 @@
* gpio.c: * gpio.c:
* Swiss-Army-Knife, Set-UID command-line interface to the Raspberry * Swiss-Army-Knife, Set-UID command-line interface to the Raspberry
* Pi's GPIO. * Pi's GPIO.
* Copyright (c) 2012-2017 Gordon Henderson * Copyright (c) 2012-2018 Gordon Henderson
*********************************************************************** ***********************************************************************
* This file is part of wiringPi: * This file is part of wiringPi:
* https://projects.drogon.net/raspberry-pi/wiringpi/ * https://projects.drogon.net/raspberry-pi/wiringpi/
@ -48,7 +48,7 @@ extern int wiringPiDebug ;
extern void doReadall (void) ; extern void doReadall (void) ;
extern void doAllReadall (void) ; extern void doAllReadall (void) ;
extern void doPins (void) ; extern void doQmode (int argc, char *argv []) ;
#ifndef TRUE #ifndef TRUE
# define TRUE (1==1) # define TRUE (1==1)
@ -56,9 +56,9 @@ extern void doPins (void) ;
#endif #endif
#define PI_USB_POWER_CONTROL 38 #define PI_USB_POWER_CONTROL 38
#define I2CDETECT "/usr/sbin/i2cdetect" #define I2CDETECT "i2cdetect"
#define MODPROBE "/sbin/modprobe" #define MODPROBE "modprobe"
#define RMMOD "/sbin/rmmod" #define RMMOD "rmmod"
int wpMode ; int wpMode ;
@ -68,9 +68,9 @@ char *usage = "Usage: gpio -v\n"
" gpio [-d] ...\n" " gpio [-d] ...\n"
" [-x extension:params] [[ -x ...]] ...\n" " [-x extension:params] [[ -x ...]] ...\n"
" gpio [-p] <read/write/wb> ...\n" " gpio [-p] <read/write/wb> ...\n"
" gpio <read/write/aread/awritewb/pwm/clock/mode> ...\n" " gpio <mode/read/write/aread/awritewb/pwm/pwmTone/clock> ...\n"
" gpio <toggle/blink> <pin>\n" " gpio <toggle/blink> <pin>\n"
" gpio readall/reset\n" " gpio readall\n"
" gpio unexportall/exports\n" " gpio unexportall/exports\n"
" gpio export/edge/unexport ...\n" " gpio export/edge/unexport ...\n"
" gpio wfi <pin> <mode>\n" " gpio wfi <pin> <mode>\n"
@ -221,9 +221,7 @@ static void checkDevTree (char *argv [])
fprintf (stderr, fprintf (stderr,
"%s: Unable to load/unload modules as this Pi has the device tree enabled.\n" "%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" " 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" " modules (SPI or I2C) that you wish to load/unload there and reboot.\n", argv [0]) ;
" There is more information here:\n"
" https://www.raspberrypi.org/forums/viewtopic.php?f=28&t=97314\n", argv [0]) ;
exit (1) ; exit (1) ;
} }
} }
@ -1270,7 +1268,7 @@ static void doVersion (char *argv [])
wiringPiVersion (&vMaj, &vMin) ; wiringPiVersion (&vMaj, &vMin) ;
printf ("gpio version: %d.%d\n", vMaj, vMin) ; printf ("gpio version: %d.%d\n", vMaj, vMin) ;
printf ("Copyright (c) 2012-2017 Gordon Henderson\n") ; printf ("Copyright (c) 2012-2018 Gordon Henderson\n") ;
printf ("This is free software with ABSOLUTELY NO WARRANTY.\n") ; printf ("This is free software with ABSOLUTELY NO WARRANTY.\n") ;
printf ("For details type: %s -warranty\n", argv [0]) ; printf ("For details type: %s -warranty\n", argv [0]) ;
printf ("\n") ; printf ("\n") ;
@ -1320,8 +1318,11 @@ int main (int argc, char *argv [])
if (argc == 1) if (argc == 1)
{ {
fprintf (stderr, "%s\n", usage) ; fprintf (stderr,
return 1 ; "%s: At your service!\n"
" Type: gpio -h for full details and\n"
" gpio readall for a quick printout of your connector details\n", argv [0]) ;
exit (EXIT_FAILURE) ;
} }
// Help // Help
@ -1329,7 +1330,7 @@ int main (int argc, char *argv [])
if (strcasecmp (argv [1], "-h") == 0) if (strcasecmp (argv [1], "-h") == 0)
{ {
printf ("%s: %s\n", argv [0], usage) ; printf ("%s: %s\n", argv [0], usage) ;
return 0 ; exit (EXIT_SUCCESS) ;
} }
// Version & Warranty // Version & Warranty
@ -1338,7 +1339,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", piGpioLayout ()) ; printf ("%d\n", piGpioLayout ()) ;
return 0 ; exit (EXIT_SUCCESS) ;
} }
// Version and information // Version and information
@ -1346,13 +1347,13 @@ int main (int argc, char *argv [])
if (strcmp (argv [1], "-v") == 0) if (strcmp (argv [1], "-v") == 0)
{ {
doVersion (argv) ; doVersion (argv) ;
return 0 ; exit (EXIT_SUCCESS) ;
} }
if (strcasecmp (argv [1], "-warranty") == 0) if (strcasecmp (argv [1], "-warranty") == 0)
{ {
printf ("gpio version: %s\n", VERSION) ; printf ("gpio version: %s\n", VERSION) ;
printf ("Copyright (c) 2012-2017 Gordon Henderson\n") ; printf ("Copyright (c) 2012-2018 Gordon Henderson\n") ;
printf ("\n") ; printf ("\n") ;
printf (" This program is free software; you can redistribute it and/or modify\n") ; printf (" This program is free software; you can redistribute it and/or modify\n") ;
printf (" it under the terms of the GNU Leser General Public License as published\n") ; printf (" it under the terms of the GNU Leser General Public License as published\n") ;
@ -1367,13 +1368,13 @@ int main (int argc, char *argv [])
printf (" You should have received a copy of the GNU Lesser General Public License\n") ; printf (" You should have received a copy of the GNU Lesser General Public License\n") ;
printf (" along with this program. If not, see <http://www.gnu.org/licenses/>.\n") ; printf (" along with this program. If not, see <http://www.gnu.org/licenses/>.\n") ;
printf ("\n") ; printf ("\n") ;
return 0 ; exit (EXIT_SUCCESS) ;
} }
if (geteuid () != 0) if (geteuid () != 0)
{ {
fprintf (stderr, "%s: Must be root to run. Program should be suid root. This is an error.\n", argv [0]) ; fprintf (stderr, "%s: Must be root to run. Program should be suid root. This is an error.\n", argv [0]) ;
return 1 ; exit (EXIT_FAILURE) ;
} }
// Initial test for /sys/class/gpio operations: // Initial test for /sys/class/gpio operations:
@ -1517,7 +1518,8 @@ int main (int argc, char *argv [])
else if (strcasecmp (argv [1], "drive" ) == 0) doPadDrive (argc, argv) ; else if (strcasecmp (argv [1], "drive" ) == 0) doPadDrive (argc, argv) ;
else if (strcasecmp (argv [1], "readall" ) == 0) doReadall () ; else if (strcasecmp (argv [1], "readall" ) == 0) doReadall () ;
else if (strcasecmp (argv [1], "nreadall" ) == 0) doReadall () ; else if (strcasecmp (argv [1], "nreadall" ) == 0) doReadall () ;
else if (strcasecmp (argv [1], "pins" ) == 0) doPins () ; 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], "i2cdetect") == 0) doI2Cdetect (argc, argv) ;
else if (strcasecmp (argv [1], "i2cd" ) == 0) doI2Cdetect (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], "reset" ) == 0) doReset (argv [0]) ;
@ -1531,5 +1533,6 @@ int main (int argc, char *argv [])
fprintf (stderr, "%s: Unknown command: %s.\n", argv [0], argv [1]) ; fprintf (stderr, "%s: Unknown command: %s.\n", argv [0], argv [1]) ;
exit (EXIT_FAILURE) ; exit (EXIT_FAILURE) ;
} }
return 0 ; return 0 ;
} }

View File

@ -1,7 +1,7 @@
/* /*
* readall.c: * readall.c:
* The readall functions - getting a bit big, so split them out. * The readall functions - getting a bit big, so split them out.
* Copyright (c) 2012-2017 Gordon Henderson * Copyright (c) 2012-2018 Gordon Henderson
*********************************************************************** ***********************************************************************
* This file is part of wiringPi: * This file is part of wiringPi:
* https://projects.drogon.net/raspberry-pi/wiringpi/ * https://projects.drogon.net/raspberry-pi/wiringpi/
@ -287,16 +287,16 @@ void abReadall (int model, int rev)
/* /*
* piPlusReadall: * piPlusReadall:
* Read all the pins on the model A+ or the B+ * Read all the pins on the model A+ or the B+ or actually, all 40-pin Pi's
********************************************************************************* *********************************************************************************
*/ */
static void plus2header (int model) static void plus2header (int model)
{ {
/**/ if (model == PI_MODEL_AP) /**/ if (model == PI_MODEL_AP)
printf (" +-----+-----+---------+------+---+--A Plus--+---+------+---------+-----+-----+\n") ; printf (" +-----+-----+---------+------+---+---Pi A+--+---+------+---------+-----+-----+\n") ;
else if (model == PI_MODEL_BP) else if (model == PI_MODEL_BP)
printf (" +-----+-----+---------+------+---+--B Plus--+---+------+---------+-----+-----+\n") ; printf (" +-----+-----+---------+------+---+---Pi B+--+---+------+---------+-----+-----+\n") ;
else if (model == PI_MODEL_ZERO) else if (model == PI_MODEL_ZERO)
printf (" +-----+-----+---------+------+---+-Pi Zero--+---+------+---------+-----+-----+\n") ; printf (" +-----+-----+---------+------+---+-Pi Zero--+---+------+---------+-----+-----+\n") ;
else if (model == PI_MODEL_ZERO_W) else if (model == PI_MODEL_ZERO_W)
@ -305,6 +305,8 @@ static void plus2header (int model)
printf (" +-----+-----+---------+------+---+---Pi 2---+---+------+---------+-----+-----+\n") ; printf (" +-----+-----+---------+------+---+---Pi 2---+---+------+---------+-----+-----+\n") ;
else if (model == PI_MODEL_3) else if (model == PI_MODEL_3)
printf (" +-----+-----+---------+------+---+---Pi 3---+---+------+---------+-----+-----+\n") ; printf (" +-----+-----+---------+------+---+---Pi 3---+---+------+---------+-----+-----+\n") ;
else if (model == PI_MODEL_3P)
printf (" +-----+-----+---------+------+---+---Pi 3+--+---+------+---------+-----+-----+\n") ;
else else
printf (" +-----+-----+---------+------+---+---Pi ?---+---+------+---------+-----+-----+\n") ; printf (" +-----+-----+---------+------+---+---Pi ?---+---+------+---------+-----+-----+\n") ;
} }
@ -348,7 +350,10 @@ void doReadall (void)
/**/ if ((model == PI_MODEL_A) || (model == PI_MODEL_B)) /**/ if ((model == PI_MODEL_A) || (model == PI_MODEL_B))
abReadall (model, rev) ; abReadall (model, rev) ;
else if ((model == PI_MODEL_BP) || (model == PI_MODEL_AP) || (model == PI_MODEL_2) || (model == PI_MODEL_3) || (model == PI_MODEL_ZERO) || (model == PI_MODEL_ZERO_W)) else if ((model == PI_MODEL_BP) || (model == PI_MODEL_AP) ||
(model == PI_MODEL_2) ||
(model == PI_MODEL_3) || (model == PI_MODEL_3P) ||
(model == PI_MODEL_ZERO) || (model == PI_MODEL_ZERO_W))
piPlusReadall (model) ; piPlusReadall (model) ;
else if ((model == PI_MODEL_CM) || (model == PI_MODEL_CM3)) else if ((model == PI_MODEL_CM) || (model == PI_MODEL_CM3))
allReadall () ; allReadall () ;
@ -356,6 +361,7 @@ void doReadall (void)
printf ("Oops - unable to determine board type... model: %d\n", model) ; printf ("Oops - unable to determine board type... model: %d\n", model) ;
} }
/* /*
* doAllReadall: * doAllReadall:
* Force reading of all pins regardless of Pi model * Force reading of all pins regardless of Pi model
@ -366,3 +372,24 @@ void doAllReadall (void)
{ {
allReadall () ; allReadall () ;
} }
/*
* doQmode:
* Query mode on a pin
*********************************************************************************
*/
void doQmode (int argc, char *argv [])
{
int pin ;
if (argc != 3)
{
fprintf (stderr, "Usage: %s qmode pin\n", argv [0]) ;
exit (EXIT_FAILURE) ;
}
pin = atoi (argv [2]) ;
printf ("%s\n", alts [getAlt (pin)]) ;
}

View File

@ -1,3 +1,3 @@
#define VERSION "2.44" #define VERSION "2.46"
#define VERSION_MAJOR 2 #define VERSION_MAJOR 2
#define VERSION_MINOR 44 #define VERSION_MINOR 46

View File

@ -40,6 +40,7 @@ CC = gcc
INCLUDE = -I. INCLUDE = -I.
DEFS = -D_GNU_SOURCE DEFS = -D_GNU_SOURCE
CFLAGS = $(DEBUG) $(DEFS) -Wformat=2 -Wall -Wextra -Winline $(INCLUDE) -pipe -fPIC CFLAGS = $(DEBUG) $(DEFS) -Wformat=2 -Wall -Wextra -Winline $(INCLUDE) -pipe -fPIC
#CFLAGS = $(DEBUG) $(DEFS) -Wformat=2 -Wall -Wextra -Wconversion -Winline $(INCLUDE) -pipe -fPIC
LIBS = -lm -lpthread -lrt -lcrypt LIBS = -lm -lpthread -lrt -lcrypt
@ -68,13 +69,9 @@ OBJ = $(SRC:.c=.o)
all: $(DYNAMIC) all: $(DYNAMIC)
static: $(STATIC) .PHONY: static
static:
$(STATIC): $(OBJ) $Q cat noMoreStatic
$Q echo "[Link (Static)]"
$Q ar rcs $(STATIC) $(OBJ)
$Q ranlib $(STATIC)
# @size $(STATIC)
$(DYNAMIC): $(OBJ) $(DYNAMIC): $(OBJ)
$Q echo "[Link (Dynamic)]" $Q echo "[Link (Dynamic)]"
@ -107,15 +104,6 @@ install: $(DYNAMIC)
$Q ln -sf $(DESTDIR)$(PREFIX)/lib/libwiringPi.so.$(VERSION) $(DESTDIR)/lib/libwiringPi.so $Q ln -sf $(DESTDIR)$(PREFIX)/lib/libwiringPi.so.$(VERSION) $(DESTDIR)/lib/libwiringPi.so
$Q $(LDCONFIG) $Q $(LDCONFIG)
.PHONY: install-static
install-static: $(STATIC)
$Q echo "[Install Headers]"
$Q install -m 0755 -d $(DESTDIR)$(PREFIX)/include
$Q install -m 0644 $(HEADERS) $(DESTDIR)$(PREFIX)/include
$Q echo "[Install Static Lib]"
$Q install -m 0755 -d $(DESTDIR)$(PREFIX)/lib
$Q install -m 0755 libwiringPi.a $(DESTDIR)$(PREFIX)/lib
.PHONY: install-deb .PHONY: install-deb
install-deb: $(DYNAMIC) install-deb: $(DYNAMIC)
$Q echo "[Install Headers: deb]" $Q echo "[Install Headers: deb]"

20
wiringPi/noMoreStatic Normal file
View File

@ -0,0 +1,20 @@
wiringPi is no-longer shipped with the ability to statically link it.
Many reasons but the biggest issue is people who have statically linked
wiringPi into their product - for example a Pi UPS device or a Tetris-like
game and not subsequently shipped their modified sources. These people are
no better than common thieves with complete disregard to the conditions
of the LGPL that wiringPi ships with.
Additionally, many think it's a good idea to statically link wiringPi
into their favourite language - like Node, and Java and other itsy bitsy
little things. These people have a complete and utter disregard to what
happens underneath when e.g. the Linux kernel changes on the Pi then
wiringPi stops as it depends on some Pi kernel features, then the poor
user get in-touch with me and I've had over 10,000 emails so-far and
it's now beyond a joke.
DO NOT STATICALLY LINK WIRINGPI.
Gordon Henderson, March 2018.

View File

@ -139,6 +139,9 @@ static volatile unsigned int GPIO_PWM ;
#define PAGE_SIZE (4*1024) #define PAGE_SIZE (4*1024)
#define BLOCK_SIZE (4*1024) #define BLOCK_SIZE (4*1024)
static unsigned int usingGpioMem = FALSE ;
static int wiringPiSetuped = FALSE ;
// PWM // PWM
// Word offsets into the PWM control region // Word offsets into the PWM control region
@ -185,15 +188,22 @@ static volatile unsigned int GPIO_PWM ;
// Locals to hold pointers to the hardware // Locals to hold pointers to the hardware
static volatile uint32_t *gpio ; static volatile unsigned int *gpio ;
static volatile uint32_t *pwm ; static volatile unsigned int *pwm ;
static volatile uint32_t *clk ; static volatile unsigned int *clk ;
static volatile uint32_t *pads ; static volatile unsigned int *pads ;
static volatile unsigned int *timer ;
static volatile unsigned int *timerIrqRaw ;
// Export variables for the hardware pointers
volatile unsigned int *_wiringPiGpio ;
volatile unsigned int *_wiringPiPwm ;
volatile unsigned int *_wiringPiClk ;
volatile unsigned int *_wiringPiPads ;
volatile unsigned int *_wiringPiTimer ;
volatile unsigned int *_wiringPiTimerIrqRaw ;
#ifdef USE_TIMER
static volatile uint32_t *timer ;
static volatile uint32_t *timerIrqRaw ;
#endif
// Data for use with the boardId functions. // Data for use with the boardId functions.
// The order of entries here to correspond with the PI_MODEL_X // The order of entries here to correspond with the PI_MODEL_X
@ -223,7 +233,7 @@ const char *piModelNames [16] =
"CM3", // 10 "CM3", // 10
"Unknown11", // 11 "Unknown11", // 11
"Pi Zero-W", // 12 "Pi Zero-W", // 12
"Unknown13", // 13 "Pi 3+", // 13
"Unknown14", // 14 "Unknown14", // 14
"Unknown15", // 15 "Unknown15", // 15
} ; } ;
@ -651,6 +661,41 @@ int wiringPiFailure (int fatal, const char *message, ...)
} }
/*
* setupCheck
* Another sanity check because some users forget to call the setup
* function. Mosty because they need feeding C drip by drip )-:
*********************************************************************************
*/
static void setupCheck (const char *fName)
{
if (!wiringPiSetuped)
{
fprintf (stderr, "%s: You have not called one of the wiringPiSetup\n"
" functions, so I'm aborting your program before it crashes anyway.\n", fName) ;
exit (EXIT_FAILURE) ;
}
}
/*
* gpioMemCheck:
* See if we're using the /dev/gpiomem interface, if-so then some operations
* can't be done and will crash the Pi.
*********************************************************************************
*/
static void usingGpioMemCheck (const char *what)
{
if (usingGpioMem)
{
fprintf (stderr, "%s: Unable to do this when using /dev/gpiomem. Try sudo?\n", what) ;
exit (EXIT_FAILURE) ;
}
}
/* /*
* piGpioLayout: * piGpioLayout:
* Return a number representing the hardware revision of the board. * Return a number representing the hardware revision of the board.
@ -720,6 +765,7 @@ int piGpioLayout (void)
// I do not support so don't email me your bleating whinges about anything // I do not support so don't email me your bleating whinges about anything
// other than a genuine Raspberry Pi. // other than a genuine Raspberry Pi.
#ifdef DONT_CARE_ANYMORE
if (! (strstr (line, "BCM2708") || strstr (line, "BCM2709") || strstr (line, "BCM2835"))) if (! (strstr (line, "BCM2708") || strstr (line, "BCM2709") || strstr (line, "BCM2835")))
{ {
fprintf (stderr, "Unable to determine hardware version. I see: %s,\n", line) ; fprintf (stderr, "Unable to determine hardware version. I see: %s,\n", line) ;
@ -730,12 +776,27 @@ int piGpioLayout (void)
fprintf (stderr, "Raspberry Pi ONLY.\n") ; fprintf (stderr, "Raspberry Pi ONLY.\n") ;
exit (EXIT_FAILURE) ; exit (EXIT_FAILURE) ;
} }
#endif
// Right - we're Probably on a Raspberry Pi. Check the revision field for the real // Actually... That has caused me more than 10,000 emails so-far. Mosty by
// people who think they know better by creating a statically linked
// version that will not run with a new 4.9 kernel. I utterly hate and
// despise those people.
//
// I also get bleats from people running other than Raspbian with another
// distros compiled kernel rather than a foundation compiled kernel, so
// this might actually help them. It might not - I only have the capacity
// to support Raspbian.
//
// However, I've decided to leave this check out and rely purely on the
// Revision: line for now. It will not work on a non-pi hardware or weird
// kernels that don't give you a suitable revision line.
// So - we're Probably on a Raspberry Pi. Check the revision field for the real
// hardware type // hardware type
// In-future, I ought to use the device tree as there are now Pi entries in // In-future, I ought to use the device tree as there are now Pi entries in
// /proc/device-tree/ ... // /proc/device-tree/ ...
// but I'll leave that for the next revision. // but I'll leave that for the next revision. Or the next.
// Isolate the Revision line // Isolate the Revision line
@ -938,7 +999,7 @@ void piBoardId (int *model, int *rev, int *mem, int *maker, int *warranty)
if ((revision & (1 << 23)) != 0) // New way if ((revision & (1 << 23)) != 0) // New way
{ {
if (wiringPiDebug) if (wiringPiDebug)
printf ("piBoardId: New Way: revision is: 0x%08X\n", revision) ; printf ("piBoardId: New Way: revision is: %08X\n", revision) ;
bRev = (revision & (0x0F << 0)) >> 0 ; bRev = (revision & (0x0F << 0)) >> 0 ;
bType = (revision & (0xFF << 4)) >> 4 ; bType = (revision & (0xFF << 4)) >> 4 ;
@ -1183,7 +1244,7 @@ void pwmSetClock (int divisor)
/* /*
* gpioClockSet: * gpioClockSet:
* Set the freuency on a GPIO clock pin * Set the frequency on a GPIO clock pin
********************************************************************************* *********************************************************************************
*/ */
@ -1322,6 +1383,8 @@ void pinModeAlt (int pin, int mode)
{ {
int fSel, shift ; int fSel, shift ;
setupCheck ("pinModeAlt") ;
if ((pin & PI_GPIO_MASK) == 0) // On-board pin if ((pin & PI_GPIO_MASK) == 0) // On-board pin
{ {
/**/ if (wiringPiMode == WPI_MODE_PINS) /**/ if (wiringPiMode == WPI_MODE_PINS)
@ -1351,6 +1414,8 @@ void pinMode (int pin, int mode)
struct wiringPiNodeStruct *node = wiringPiNodes ; struct wiringPiNodeStruct *node = wiringPiNodes ;
int origPin = pin ; int origPin = pin ;
setupCheck ("pinMode") ;
if ((pin & PI_GPIO_MASK) == 0) // On-board pin if ((pin & PI_GPIO_MASK) == 0) // On-board pin
{ {
/**/ if (wiringPiMode == WPI_MODE_PINS) /**/ if (wiringPiMode == WPI_MODE_PINS)
@ -1384,6 +1449,8 @@ void pinMode (int pin, int mode)
if ((alt = gpioToPwmALT [pin]) == 0) // Not a hardware capable PWM pin if ((alt = gpioToPwmALT [pin]) == 0) // Not a hardware capable PWM pin
return ; return ;
usingGpioMemCheck ("pinMode PWM") ;
// Set pin to PWM mode // Set pin to PWM mode
*(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) | (alt << shift) ; *(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) | (alt << shift) ;
@ -1398,6 +1465,8 @@ void pinMode (int pin, int mode)
if ((alt = gpioToGpClkALT0 [pin]) == 0) // Not a GPIO_CLOCK pin if ((alt = gpioToGpClkALT0 [pin]) == 0) // Not a GPIO_CLOCK pin
return ; return ;
usingGpioMemCheck ("pinMode CLOCK") ;
// Set pin to GPIO_CLOCK mode and set the clock frequency to 100KHz // Set pin to GPIO_CLOCK mode and set the clock frequency to 100KHz
*(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) | (alt << shift) ; *(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) | (alt << shift) ;
@ -1416,10 +1485,7 @@ void pinMode (int pin, int mode)
/* /*
* pullUpDownCtrl: * pullUpDownCtrl:
* Control the internal pull-up/down resistors on a GPIO pin * Control the internal pull-up/down resistors on a GPIO pin.
* The Arduino only has pull-ups and these are enabled by writing 1
* to a port when in input mode - this paradigm doesn't quite apply
* here though.
********************************************************************************* *********************************************************************************
*/ */
@ -1427,6 +1493,8 @@ void pullUpDnControl (int pin, int pud)
{ {
struct wiringPiNodeStruct *node = wiringPiNodes ; struct wiringPiNodeStruct *node = wiringPiNodes ;
setupCheck ("pullUpDnControl") ;
if ((pin & PI_GPIO_MASK) == 0) // On-Board Pin if ((pin & PI_GPIO_MASK) == 0) // On-Board Pin
{ {
/**/ if (wiringPiMode == WPI_MODE_PINS) /**/ if (wiringPiMode == WPI_MODE_PINS)
@ -1588,6 +1656,8 @@ void pwmWrite (int pin, int value)
{ {
struct wiringPiNodeStruct *node = wiringPiNodes ; struct wiringPiNodeStruct *node = wiringPiNodes ;
setupCheck ("pwmWrite") ;
if ((pin & PI_GPIO_MASK) == 0) // On-Board Pin if ((pin & PI_GPIO_MASK) == 0) // On-Board Pin
{ {
/**/ if (wiringPiMode == WPI_MODE_PINS) /**/ if (wiringPiMode == WPI_MODE_PINS)
@ -1597,6 +1667,7 @@ void pwmWrite (int pin, int value)
else if (wiringPiMode != WPI_MODE_GPIO) else if (wiringPiMode != WPI_MODE_GPIO)
return ; return ;
usingGpioMemCheck ("pwmWrite") ;
*(pwm + gpioToPwmPort [pin]) = value ; *(pwm + gpioToPwmPort [pin]) = value ;
} }
else else
@ -1656,6 +1727,8 @@ void pwmToneWrite (int pin, int freq)
{ {
int range ; int range ;
setupCheck ("pwmToneWrite") ;
if (freq == 0) if (freq == 0)
pwmWrite (pin, 0) ; // Off pwmWrite (pin, 0) ; // Off
else else
@ -2139,16 +2212,15 @@ int wiringPiSetup (void)
{ {
int fd ; int fd ;
int model, rev, mem, maker, overVolted ; int model, rev, mem, maker, overVolted ;
static int alreadyDoneThis = FALSE ;
// It's actually a fatal error to call any of the wiringPiSetup routines more than once, // It's actually a fatal error to call any of the wiringPiSetup routines more than once,
// (you run out of file handles!) but I'm fed-up with the useless twats who email // (you run out of file handles!) but I'm fed-up with the useless twats who email
// me bleating that there is a bug in my code, so screw-em. // me bleating that there is a bug in my code, so screw-em.
if (alreadyDoneThis) if (wiringPiSetuped)
return 0 ; return 0 ;
alreadyDoneThis = TRUE ; wiringPiSetuped = TRUE ;
if (getenv (ENV_DEBUG) != NULL) if (getenv (ENV_DEBUG) != NULL)
wiringPiDebug = TRUE ; wiringPiDebug = TRUE ;
@ -2204,11 +2276,18 @@ int wiringPiSetup (void)
// Try /dev/mem. If that fails, then // Try /dev/mem. If that fails, then
// try /dev/gpiomem. If that fails then game over. // try /dev/gpiomem. If that fails then game over.
if ((fd = open ("/dev/mem", O_RDWR | O_SYNC | O_CLOEXEC) ) < 0) if ((fd = open ("/dev/mem", O_RDWR | O_SYNC | O_CLOEXEC)) < 0)
{ {
if ((fd = open ("/dev/gpiomem", O_RDWR | O_SYNC | O_CLOEXEC) ) < 0) if ((fd = open ("/dev/gpiomem", O_RDWR | O_SYNC | O_CLOEXEC) ) >= 0) // We're using gpiomem
return wiringPiFailure (WPI_ALMOST, "wiringPiSetup: Unable to open /dev/mem or /dev/gpiomem: %s.\n Try running with sudo?\n", strerror (errno)) ; {
piGpioBase = 0 ; piGpioBase = 0 ;
usingGpioMem = TRUE ;
}
else
return wiringPiFailure (WPI_ALMOST, "wiringPiSetup: Unable to open /dev/mem or /dev/gpiomem: %s.\n"
" Aborting your program because if it can not access the GPIO\n"
" hardware then it most certianly won't work\n"
" Try running with sudo?\n", strerror (errno)) ;
} }
// Set the offsets into the memory interface. // Set the offsets into the memory interface.
@ -2245,7 +2324,6 @@ int wiringPiSetup (void)
if (pads == MAP_FAILED) if (pads == MAP_FAILED)
return wiringPiFailure (WPI_ALMOST, "wiringPiSetup: mmap (PADS) failed: %s\n", strerror (errno)) ; return wiringPiFailure (WPI_ALMOST, "wiringPiSetup: mmap (PADS) failed: %s\n", strerror (errno)) ;
#ifdef USE_TIMER
// The system timer // The system timer
timer = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, GPIO_TIMER) ; timer = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, GPIO_TIMER) ;
@ -2259,7 +2337,14 @@ int wiringPiSetup (void)
*(timer + TIMER_CONTROL) = 0x0000280 ; *(timer + TIMER_CONTROL) = 0x0000280 ;
*(timer + TIMER_PRE_DIV) = 0x00000F9 ; *(timer + TIMER_PRE_DIV) = 0x00000F9 ;
timerIrqRaw = timer + TIMER_IRQ_RAW ; timerIrqRaw = timer + TIMER_IRQ_RAW ;
#endif
// Export the base addresses for any external software that might need them
_wiringPiGpio = gpio ;
_wiringPiPwm = pwm ;
_wiringPiClk = clk ;
_wiringPiPads = pads ;
_wiringPiTimer = timer ;
initialiseEpoch () ; initialiseEpoch () ;
@ -2325,16 +2410,10 @@ int wiringPiSetupSys (void)
int pin ; int pin ;
char fName [128] ; char fName [128] ;
static int alreadyDoneThis = FALSE ; if (wiringPiSetuped)
// It's actually a fatal error to call any of the wiringPiSetup routines more than once,
// (you run out of file handles!) but I'm fed-up with the useless twats who email
// me bleating that there is a bug in my code, so screw-em.
if (alreadyDoneThis)
return 0 ; return 0 ;
alreadyDoneThis = TRUE ; wiringPiSetuped = TRUE ;
if (getenv (ENV_DEBUG) != NULL) if (getenv (ENV_DEBUG) != NULL)
wiringPiDebug = TRUE ; wiringPiDebug = TRUE ;

View File

@ -99,6 +99,7 @@
#define PI_MODEL_ZERO 9 #define PI_MODEL_ZERO 9
#define PI_MODEL_CM3 10 #define PI_MODEL_CM3 10
#define PI_MODEL_ZERO_W 12 #define PI_MODEL_ZERO_W 12
#define PI_MODEL_3P 13
#define PI_VERSION_1 0 #define PI_VERSION_1 0
#define PI_VERSION_1_1 1 #define PI_VERSION_1_1 1
@ -162,6 +163,15 @@ struct wiringPiNodeStruct
extern struct wiringPiNodeStruct *wiringPiNodes ; extern struct wiringPiNodeStruct *wiringPiNodes ;
// Export variables for the hardware pointers
extern volatile unsigned int *_wiringPiGpio ;
extern volatile unsigned int *_wiringPiPwm ;
extern volatile unsigned int *_wiringPiClk ;
extern volatile unsigned int *_wiringPiPads ;
extern volatile unsigned int *_wiringPiTimer ;
extern volatile unsigned int *_wiringPiTimerIrqRaw ;
// Function prototypes // Function prototypes
// c++ wrappers thanks to a comment by Nick Lott // c++ wrappers thanks to a comment by Nick Lott

View File

@ -871,7 +871,7 @@ int loadWPiExtension (char *progName, char *extensionData, int printErrors)
char *p ; char *p ;
char *extension = extensionData ; char *extension = extensionData ;
struct extensionFunctionStruct *extensionFn ; struct extensionFunctionStruct *extensionFn ;
unsigned pinBase = 0 ; int pinBase = 0 ;
verbose = printErrors ; verbose = printErrors ;

Binary file not shown.