What is a safe and easy way to exchange data from a threaded ISR? (Raspberry Pi)

1.2k views Asked by At

I'm trying to develop a C/C++ userspace application on the Raspberry Pi which processes data coming from an SPI device. I'm using the WiringPi Library (function wiringPiISR) which registers a function (the real interrupt handler) that will be called from a pthreaded interrupt handler on an IRQ event.

I heard that STL containers aren't thread safe, but is it enough to have a mutex lock while executing my callback function and of course a lock in the main thread while accessing the buffer/container there?

My "real interrupt handler" which is registered through wiringPiISR looks like this

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

Or is there an easier way to achieve the data exchange between a threaded ISR and main thread?

1

There are 1 answers

2
shodanex On

Is that a real ISR ? Anyway mutex are not a good fit for ISR, because they lead to priority inversion. Let's look at normal mutex usage, with two thread :

  1. Thread A runs and take the mmutex
  2. for some reason, thread A is preempted, and thread B executes.
  3. thread B try to take the mutex, but can't.
  4. thread B is put to sleep, allowing another thread to run, for instance thread C or thread A
  5. ...
  6. At some point, thread A wille be rescheduled, will resume it's operation, and release the mutex.
  7. When thread B is scheduled again, takes the mutex.

Now the scenario is very different when it comes to ISR. ISR won't be put to sleep in favor of a lower priority thread, so the mutex owning thread will not run while you are in the ISR, and you will never get out of point three.

So the real question is, "When running an IRQ handler, is it possible for other code to run ?" Otherwise you are in deadlock !