wiringPi.c: waitForInterrupt rewritten

This commit is contained in:
phylax2020
2025-02-17 12:23:11 +01:00
parent 3c3b69c888
commit 04dc08e511
2 changed files with 44 additions and 67 deletions

View File

@@ -20,13 +20,13 @@ sudo apt install git
git clone https://github.com/WiringPi/WiringPi.git
cd WiringPi
./build debian
mv debian-template/wiringpi-3.13.deb .
mv debian-template/wiringpi-3.1x.deb .
```
**Debian-Paket installieren:**
```bash
sudo apt install ./wiringpi-3.13.deb
sudo apt install ./wiringpi-3.1x.deb
```
**Debian-Paket deinstallieren:**
@@ -445,17 +445,14 @@ int main (void)
ret = waitForInterrupt(IRQpin, INT_EDGE_FALLING, TIMEOUT, BOUNCETIME_WFI );
if (ret < 0) {
printf("waitForInterrupt returned error %lld\n", ret);
wiringPiISRStop (IRQpin) ;
pinMode(OUTpin, INPUT);
return 0;
}
else if (ret == 0) {
printf("waitForInterrupt timed out %lld\n\n", ret);
wiringPiISRStop (IRQpin) ;
}
else {
printf("waitForInterrupt: falling edge fired at %lld microseconds\n\n", ret);
wiringPiISRStop (IRQpin) ;
}
printf("Testing IRQ @ GPIO%d with trigger @ GPIO%d falling edge and bouncetime %d microseconds. Toggle LED @ OUTpin on IRQ.\n\n", IRQpin, IRQpin, BOUNCETIME, OUTpin);

View File

@@ -2630,30 +2630,33 @@ unsigned int digitalReadByte2 (void)
/*
* waitForInterrupt:
* Pi Specific.
* Wait for Interrupt on a GPIO pin.
* This is actually done via the /dev/gpiochip interface regardless of
* the wiringPi access mode in-use. Maybe sometime it might get a better
* way for a bit more efficiency.
* Returns timestamp in microseconds on interrupt
*********************************************************************************
*/
//--------------------------------------------------------------------
// waitForInteruptInit
// Prepares waitForInterrupt for edgeMode, and debounce_period_us
//
// returns -1 on error
// returns 0 on success
//--------------------------------------------------------------------
int waitForInterruptInit (int pin, int edgeMode, unsigned long debounce_period_us)
long long int waitForInterrupt (int pin, int edgeMode, int mS, unsigned long debounce_period_us) // ms < 0 wait infinite, = 0 return immediately, > 0 wait timeout
{
const char* strmode = "";
long long int ret;
int fd, attr, status, readret;
struct pollfd polls ;
struct gpio_v2_line_event evdata;
struct gpio_v2_line_config config;
struct gpio_v2_line_request req;
int attr, ret;
const char* strmode = "";
if (wiringPiMode == WPI_MODE_PINS) {
if (wiringPiMode == WPI_MODE_PINS)
pin = pinToGpio [pin] ;
} else if (wiringPiMode == WPI_MODE_PHYS) {
else if (wiringPiMode == WPI_MODE_PHYS)
pin = physToGpio [pin] ;
}
/* open gpio */
// sleep(1);
if (wiringPiGpioDeviceGetFd()<0) {
return -1;
}
@@ -2663,6 +2666,7 @@ int waitForInterruptInit (int pin, int edgeMode, unsigned long debounce_period_u
/* setup config */
config.flags = GPIO_V2_LINE_FLAG_INPUT;
switch(edgeMode) {
default:
case INT_EDGE_SETUP:
@@ -2686,11 +2690,11 @@ int waitForInterruptInit (int pin, int edgeMode, unsigned long debounce_period_u
strcpy(req.consumer, "wiringpi_gpio_irq");
if (debounce_period_us) {
attr = config.num_attrs;
config.num_attrs++;
gpiotools_set_bit(&config.attrs[attr].mask, 0);
config.attrs[attr].attr.id = GPIO_V2_LINE_ATTR_ID_DEBOUNCE;
config.attrs[attr].attr.debounce_period_us = debounce_period_us;
attr = config.num_attrs;
config.num_attrs++;
gpiotools_set_bit(&config.attrs[attr].mask, 0);
config.attrs[attr].attr.id = GPIO_V2_LINE_ATTR_ID_DEBOUNCE;
config.attrs[attr].attr.debounce_period_us = debounce_period_us;
}
req.num_lines = 1;
@@ -2698,9 +2702,9 @@ int waitForInterruptInit (int pin, int edgeMode, unsigned long debounce_period_u
req.event_buffer_size = 32;
req.config = config;
ret = ioctl(chipFd, GPIO_V2_GET_LINE_IOCTL, &req);
if (ret == -1) {
ReportDeviceError("GPIO_V2_GET_LINE_IOCTL", pin , strmode, ret);
status = ioctl(chipFd, GPIO_V2_GET_LINE_IOCTL, &req);
if (status == -1) {
ReportDeviceError("GPIO_V2_GET_LINE_IOCTL", pin , strmode, status);
return -1;
}
@@ -2708,54 +2712,24 @@ int waitForInterruptInit (int pin, int edgeMode, unsigned long debounce_period_u
printf ("wiringPi: GPIO get line %d , mode %s succeded, fd=%d\n", pin, strmode, req.fd) ;
}
int fd_line = req.fd;
isrFds [pin] = fd_line;
fd = req.fd;
isrFds [pin] = fd;
isrDebouncePeriodUs[pin] = debounce_period_us;
/* set event fd nonbloack read */
/*
int flags = fcntl(fd_line, F_GETFL);
int flags = fcntl(fd, F_GETFL);
flags |= O_NONBLOCK;
ret = fcntl(fd_line, F_SETFL, flags);
if (ret) {
fprintf(stderr, "wiringPi: ERROR: fcntl set nonblock return=%d\n", ret);
status = fcntl(fd, F_SETFL, flags);
if (status) {
fprintf(stderr, "wiringPi: ERROR: fcntl set nonblock return=%d\n", status);
return -1;
}
*/
return 0;
}
/*
* waitForInterrupt:
* Pi Specific.
* Wait for Interrupt on a GPIO pin.
* This is actually done via the /dev/gpiochip interface regardless of
* the wiringPi access mode in-use. Maybe sometime it might get a better
* way for a bit more efficiency.
* Returns timestamp in microseconds on interrupt
*********************************************************************************
*/
long long int waitForInterrupt (int pin, int edgeMode, int mS, unsigned long debounce_period_us) // ms < 0 wait infinite, = 0 return immediately, > 0 wait timeout
{
long long int ret;
int fd;
struct pollfd polls ;
struct gpio_v2_line_event evdata;
if (wiringPiMode == WPI_MODE_PINS)
pin = pinToGpio [pin] ;
else if (wiringPiMode == WPI_MODE_PHYS)
pin = physToGpio [pin] ;
if (waitForInterruptInit (pin, edgeMode, debounce_period_us ) != 0)
return -1 ;
fd = isrFds[pin];
// Setup poll structure
polls.fd = fd;
polls.events = POLLIN | POLLERR ;
polls.events = POLLIN | POLLPRI;
polls.revents = 0;
ret = (long long int)poll(&polls, 1, mS);
@@ -2772,7 +2746,7 @@ long long int waitForInterrupt (int pin, int edgeMode, int mS, unsigned long deb
printf ("wiringPi: IRQ line %d received %lld, fd=%d\n", pin, ret, isrFds[pin]) ;
if (polls.revents & POLLIN) {
/* read event data */
int readret = read(isrFds [pin], &evdata, sizeof(evdata));
readret = read(isrFds [pin], &evdata, sizeof(evdata));
if (readret == sizeof(evdata)) {
if (wiringPiDebug)
printf ("wiringPi: IRQ at PIN: %d, timestamp: %lld\n", evdata.offset, evdata.timestamp_ns) ;
@@ -2798,6 +2772,12 @@ long long int waitForInterrupt (int pin, int edgeMode, int mS, unsigned long deb
}
}
}
if (isrFds[pin] > 0) {
close(isrFds [pin]); // release line
isrFds [pin] = -1;
isrDebouncePeriodUs[pin] = 0;
}
return ret;
}
@@ -2954,7 +2934,7 @@ void *interruptHandler (void *arg)
// Setup poll structure
polls.fd = fd;
polls.events = POLLIN | POLLPRI;;
polls.events = POLLIN | POLLPRI;
polls.revents = 0;
// get event data, this is also a cancelation point, when pthread_cancel is called