问题
I am developing a program in C to run on a raspberry board. In the program i want to use WiringPiISR to handle a pin triggered interrupt. However, I have found that instead of blocking the main routine, the wiringPiISR creates a concurrent thread. Am i missing something?
Minimal code example :
#include <WiringPi.h>
#include <unistd.h>
int Check=0;
void Isr()
{
while (1)
{
sleep(1);
Check++;
}
}
int main()
{
wiringPiSetup () ;
pinMode(7, INPUT) ;
wiringPiISR (7, INT_EDGE_BOTH ,&Isr);
while (1)
{
sleep(2);
printf("check : %d", Check );
}
return 0;
}
I would expect this minimal program to never resume after the interrupt is fired but in my case it kept on incrementing the variable check and printing it on the screen ( both threads working concurrently).
回答1:
The documentation I've found is rather specific (emphasis mine):
int wiringPiISR (int pin, int edgeType, void (*function)(void)) ;
This function is run at a high priority (if the program is run using sudo, or as root) and executes concurrently with the main program. It has full access to all the global variables, open file handles and so on.
The sources don't leave anything to imagination. It just crates a new thread:
pthread_create (&threadId, NULL, interruptHandler, &pin) ;
that waits for interrupt and executes your handler:
static void *interruptHandler (void *arg)
{
int pin = *(int *)arg ;
(void)piHiPri (55) ;
for (;;)
{
if (waitForInterrupt (pin, -1) > 0)
isrFunctions [pin] () ;
}
return NULL ;
}
So your handler runs as a separate thread and your behavior is expected.
回答2:
ISR stands for interrupt service routine aka interrupt handler.
Your code sets up an interrupt handler. If the interrupt is fired, the regular code (main()
in your case) is interrupted and the interrupt handler is executed. It's not a second thread but the result is similar.
Interrupt handlers should only do minimal work and quickly return control to the interrupted program. The use of sleep()
in an interrupt handler is not allowed and causes undefined behavior.
回答3:
Assuming that you've made the infinite loop and the call of sleep()
on purpose:
sleep()
probably allows to switch between the threads.
来源:https://stackoverflow.com/questions/57315755/why-does-not-wiringpiisr-block-the-main-routine-when-it-is-fired