为什么 WiringPiISR 在被触发时不阻塞主例程?

Why does not WiringPiISR block the main routine when it is fired?

我正在用 C 语言在树莓板上 运行 开发一个程序。在程序中,我想使用 WiringPiISR 来处理引脚触发的中断。但是,我发现 wiringPiISR 并没有阻塞主例程,而是创建了一个并发线程。我错过了什么吗?

最小代码示例:

#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;
}

我希望这个最小程序在中断被触发后永远不会恢复,但在我的例子中,它一直在递增变量检查并将其打印在屏幕上(两个线程同时工作)。

ISR 代表 中断服务程序 又名中断处理程序。

您的代码设置了一个中断处理程序。如果触发中断,则常规代码(在您的情况下为 main() )将被中断并执行中断处理程序。这不是第二个线程,但结果是相似的。

中断处理程序应该只做最少的工作并快速 return 控制被中断的程序。不允许在中断处理程序中使用 sleep(),这会导致未定义的行为。

假设您已经进行了无限循环并故意调用 sleep()

sleep() 可能允许在线程之间切换。

我发现的 documentation 相当具体(强调我的):

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.

sources 不留想象空间。它只是创建一个新线程:

pthread_create (&threadId, NULL, interruptHandler, &pin) ;

等待中断并执行您的处理程序:

static void *interruptHandler (void *arg)
{
  int pin = *(int *)arg ;

  (void)piHiPri (55) ;

  for (;;)
  {
    if (waitForInterrupt (pin, -1) > 0)
      isrFunctions [pin] () ;
  }

  return NULL ;
}

所以你的处理程序作为一个单独的线程运行,你的行为是预期的。