2

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

我听说 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 和主线程之间的数据交换?

4

1 回答 1

0

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

  1. 线程 A 运行并获取 mmutex
  2. 由于某种原因,线程 A 被抢占,线程 B 执行。
  3. 线程 B 尝试获取互斥锁,但不能。
  4. 线程 B 进入睡眠状态,允许另一个线程运行,例如线程 C 或线程 A
  5. ...
  6. 在某个时刻,线程 A 将被重新调度,将恢复它的操作,并释放互斥锁。
  7. 当线程 B 再次被调度时,获取互斥锁。

现在,当涉及到 ISR 时,情况就大不相同了。ISR 不会因优先级较低的线程而进入休眠状态,因此当您在 ISR 中时,拥有互斥锁的线程将不会运行,并且您永远不会脱离第三点。

所以真正的问题是,“当运行一个 IRQ 处理程序时,是否有可能运行其他代码?” 否则你陷入僵局!

于 2013-12-08T12:39:18.327 回答