从线程ISR交换数据的安全简便方法是什么? (覆盆子皮)

时间:2013-12-08 12:01:06

标签: multithreading raspberry-pi interrupt irq isr

我正在尝试在Raspberry Pi上开发一个C / C ++用户空间应用程序,用于处理来自SPI设备的数据。我正在使用 WiringPi 库(函数 wiringPiISR )来注册将从pthreaded调用的函数(真正的中断处理程序) IRQ事件中的中断处理程序。

我听说STL容器不是线程安全的,但是在执行我的回调函数时是否足以有一个互斥锁,当然在访问那里的缓冲区/容器时锁定主线程?

通过 wiringPiISR 注册的“真正的中断处理程序”看起来像这样

std::deque<uint8_t> buffer;

static void irq_handler()
{
    uint8_t data;
    while (digitalRead(IRQ_PIN)==0)
    {
        data = spi_txrx(CMD_READBYTE);
        pthread_mutex_lock(&mutex1);
        callback(data);
        pthread_mutex_unlock(&mutex1);
    }
}

static void callback(uint8_t byte)
{
    buffer.push_back(byte);
}

或者是否有更简单的方法来实现线程ISR和主线程之间的数据交换?

1 个答案:

答案 0 :(得分:0)

这是真正的ISR吗? 无论如何,互斥都不适合ISR,因为它们会导致优先级倒置。 让我们看看正常的互斥用法,有两个线程:

  1. 线程A运行并采用mmutex
  2. 由于某种原因,线程A被抢占,线程B执行。
  3. 主题B尝试使用互斥锁,但不能
  4. 线程B进入休眠状态,允许另一个线程运行,例如线程C或线程A
  5. ...
  6. 在某些时候,线程A将被重新安排,将恢复它的操作,并释放互斥锁。
  7. 当再次安排线程B时,请使用互斥锁。
  8. 现在,ISR的情况非常不同。互联网不会因为优先级较低的线程而处于睡眠状态,因此当您在ISR中时,互斥锁拥有线程将无法运行,您将永远不会脱离第三点。

    所以真正的问题是,&#34;当运行IRQ处理程序时,是否可以运行其他代码?&#34;否则你就陷入了僵局!