mirror of
https://github.com/clockworkpi/WiringPi.git
synced 2026-03-21 19:32:40 +01:00
update for the v3+
This commit is contained in:
@@ -40,6 +40,7 @@ CC = gcc
|
||||
INCLUDE = -I.
|
||||
DEFS = -D_GNU_SOURCE
|
||||
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
|
||||
|
||||
@@ -68,13 +69,9 @@ OBJ = $(SRC:.c=.o)
|
||||
|
||||
all: $(DYNAMIC)
|
||||
|
||||
static: $(STATIC)
|
||||
|
||||
$(STATIC): $(OBJ)
|
||||
$Q echo "[Link (Static)]"
|
||||
$Q ar rcs $(STATIC) $(OBJ)
|
||||
$Q ranlib $(STATIC)
|
||||
# @size $(STATIC)
|
||||
.PHONY: static
|
||||
static:
|
||||
$Q cat noMoreStatic
|
||||
|
||||
$(DYNAMIC): $(OBJ)
|
||||
$Q echo "[Link (Dynamic)]"
|
||||
@@ -107,15 +104,6 @@ install: $(DYNAMIC)
|
||||
$Q ln -sf $(DESTDIR)$(PREFIX)/lib/libwiringPi.so.$(VERSION) $(DESTDIR)/lib/libwiringPi.so
|
||||
$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
|
||||
install-deb: $(DYNAMIC)
|
||||
$Q echo "[Install Headers: deb]"
|
||||
|
||||
20
wiringPi/noMoreStatic
Normal file
20
wiringPi/noMoreStatic
Normal 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.
|
||||
@@ -139,6 +139,9 @@ static volatile unsigned int GPIO_PWM ;
|
||||
#define PAGE_SIZE (4*1024)
|
||||
#define BLOCK_SIZE (4*1024)
|
||||
|
||||
static unsigned int usingGpioMem = FALSE ;
|
||||
static int wiringPiSetuped = FALSE ;
|
||||
|
||||
// PWM
|
||||
// Word offsets into the PWM control region
|
||||
|
||||
@@ -185,15 +188,22 @@ static volatile unsigned int GPIO_PWM ;
|
||||
|
||||
// Locals to hold pointers to the hardware
|
||||
|
||||
static volatile uint32_t *gpio ;
|
||||
static volatile uint32_t *pwm ;
|
||||
static volatile uint32_t *clk ;
|
||||
static volatile uint32_t *pads ;
|
||||
static volatile unsigned int *gpio ;
|
||||
static volatile unsigned int *pwm ;
|
||||
static volatile unsigned int *clk ;
|
||||
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.
|
||||
// The order of entries here to correspond with the PI_MODEL_X
|
||||
@@ -223,7 +233,7 @@ const char *piModelNames [16] =
|
||||
"CM3", // 10
|
||||
"Unknown11", // 11
|
||||
"Pi Zero-W", // 12
|
||||
"Unknown13", // 13
|
||||
"Pi 3+", // 13
|
||||
"Unknown14", // 14
|
||||
"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:
|
||||
* 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
|
||||
// other than a genuine Raspberry Pi.
|
||||
|
||||
#ifdef DONT_CARE_ANYMORE
|
||||
if (! (strstr (line, "BCM2708") || strstr (line, "BCM2709") || strstr (line, "BCM2835")))
|
||||
{
|
||||
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") ;
|
||||
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
|
||||
// In-future, I ought to use the device tree as there are now Pi entries in
|
||||
// /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
|
||||
|
||||
@@ -938,7 +999,7 @@ void piBoardId (int *model, int *rev, int *mem, int *maker, int *warranty)
|
||||
if ((revision & (1 << 23)) != 0) // New way
|
||||
{
|
||||
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 ;
|
||||
bType = (revision & (0xFF << 4)) >> 4 ;
|
||||
@@ -1183,7 +1244,7 @@ void pwmSetClock (int divisor)
|
||||
|
||||
/*
|
||||
* 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 ;
|
||||
|
||||
setupCheck ("pinModeAlt") ;
|
||||
|
||||
if ((pin & PI_GPIO_MASK) == 0) // On-board pin
|
||||
{
|
||||
/**/ if (wiringPiMode == WPI_MODE_PINS)
|
||||
@@ -1351,6 +1414,8 @@ void pinMode (int pin, int mode)
|
||||
struct wiringPiNodeStruct *node = wiringPiNodes ;
|
||||
int origPin = pin ;
|
||||
|
||||
setupCheck ("pinMode") ;
|
||||
|
||||
if ((pin & PI_GPIO_MASK) == 0) // On-board pin
|
||||
{
|
||||
/**/ 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
|
||||
return ;
|
||||
|
||||
usingGpioMemCheck ("pinMode PWM") ;
|
||||
|
||||
// Set pin to PWM mode
|
||||
|
||||
*(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
|
||||
return ;
|
||||
|
||||
usingGpioMemCheck ("pinMode CLOCK") ;
|
||||
|
||||
// Set pin to GPIO_CLOCK mode and set the clock frequency to 100KHz
|
||||
|
||||
*(gpio + fSel) = (*(gpio + fSel) & ~(7 << shift)) | (alt << shift) ;
|
||||
@@ -1416,10 +1485,7 @@ void pinMode (int pin, int mode)
|
||||
|
||||
/*
|
||||
* pullUpDownCtrl:
|
||||
* 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.
|
||||
* Control the internal pull-up/down resistors on a GPIO pin.
|
||||
*********************************************************************************
|
||||
*/
|
||||
|
||||
@@ -1427,6 +1493,8 @@ void pullUpDnControl (int pin, int pud)
|
||||
{
|
||||
struct wiringPiNodeStruct *node = wiringPiNodes ;
|
||||
|
||||
setupCheck ("pullUpDnControl") ;
|
||||
|
||||
if ((pin & PI_GPIO_MASK) == 0) // On-Board Pin
|
||||
{
|
||||
/**/ if (wiringPiMode == WPI_MODE_PINS)
|
||||
@@ -1588,6 +1656,8 @@ void pwmWrite (int pin, int value)
|
||||
{
|
||||
struct wiringPiNodeStruct *node = wiringPiNodes ;
|
||||
|
||||
setupCheck ("pwmWrite") ;
|
||||
|
||||
if ((pin & PI_GPIO_MASK) == 0) // On-Board Pin
|
||||
{
|
||||
/**/ if (wiringPiMode == WPI_MODE_PINS)
|
||||
@@ -1597,6 +1667,7 @@ void pwmWrite (int pin, int value)
|
||||
else if (wiringPiMode != WPI_MODE_GPIO)
|
||||
return ;
|
||||
|
||||
usingGpioMemCheck ("pwmWrite") ;
|
||||
*(pwm + gpioToPwmPort [pin]) = value ;
|
||||
}
|
||||
else
|
||||
@@ -1656,6 +1727,8 @@ void pwmToneWrite (int pin, int freq)
|
||||
{
|
||||
int range ;
|
||||
|
||||
setupCheck ("pwmToneWrite") ;
|
||||
|
||||
if (freq == 0)
|
||||
pwmWrite (pin, 0) ; // Off
|
||||
else
|
||||
@@ -2139,16 +2212,15 @@ int wiringPiSetup (void)
|
||||
{
|
||||
int fd ;
|
||||
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,
|
||||
// (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)
|
||||
if (wiringPiSetuped)
|
||||
return 0 ;
|
||||
|
||||
alreadyDoneThis = TRUE ;
|
||||
wiringPiSetuped = TRUE ;
|
||||
|
||||
if (getenv (ENV_DEBUG) != NULL)
|
||||
wiringPiDebug = TRUE ;
|
||||
@@ -2204,11 +2276,18 @@ int wiringPiSetup (void)
|
||||
// Try /dev/mem. If that fails, then
|
||||
// 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)
|
||||
return wiringPiFailure (WPI_ALMOST, "wiringPiSetup: Unable to open /dev/mem or /dev/gpiomem: %s.\n Try running with sudo?\n", strerror (errno)) ;
|
||||
piGpioBase = 0 ;
|
||||
if ((fd = open ("/dev/gpiomem", O_RDWR | O_SYNC | O_CLOEXEC) ) >= 0) // We're using gpiomem
|
||||
{
|
||||
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.
|
||||
@@ -2245,7 +2324,6 @@ int wiringPiSetup (void)
|
||||
if (pads == MAP_FAILED)
|
||||
return wiringPiFailure (WPI_ALMOST, "wiringPiSetup: mmap (PADS) failed: %s\n", strerror (errno)) ;
|
||||
|
||||
#ifdef USE_TIMER
|
||||
// The system 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_PRE_DIV) = 0x00000F9 ;
|
||||
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 () ;
|
||||
|
||||
@@ -2325,16 +2410,10 @@ int wiringPiSetupSys (void)
|
||||
int pin ;
|
||||
char fName [128] ;
|
||||
|
||||
static int alreadyDoneThis = FALSE ;
|
||||
|
||||
// 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)
|
||||
if (wiringPiSetuped)
|
||||
return 0 ;
|
||||
|
||||
alreadyDoneThis = TRUE ;
|
||||
wiringPiSetuped = TRUE ;
|
||||
|
||||
if (getenv (ENV_DEBUG) != NULL)
|
||||
wiringPiDebug = TRUE ;
|
||||
|
||||
@@ -99,6 +99,7 @@
|
||||
#define PI_MODEL_ZERO 9
|
||||
#define PI_MODEL_CM3 10
|
||||
#define PI_MODEL_ZERO_W 12
|
||||
#define PI_MODEL_3P 13
|
||||
|
||||
#define PI_VERSION_1 0
|
||||
#define PI_VERSION_1_1 1
|
||||
@@ -162,6 +163,15 @@ struct wiringPiNodeStruct
|
||||
|
||||
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
|
||||
// c++ wrappers thanks to a comment by Nick Lott
|
||||
|
||||
@@ -871,7 +871,7 @@ int loadWPiExtension (char *progName, char *extensionData, int printErrors)
|
||||
char *p ;
|
||||
char *extension = extensionData ;
|
||||
struct extensionFunctionStruct *extensionFn ;
|
||||
unsigned pinBase = 0 ;
|
||||
int pinBase = 0 ;
|
||||
|
||||
verbose = printErrors ;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user