Raspberry Pi + Linux Interrupt Latency: 10μs

I decided I wanted to use a capacitive relative humidity sensor in a project with a Raspberry Pi, but that meant timing the charing or discharging of the sensor in an RC circuit. These things don’t have much capacitance, and the data sheet suggests it might not give good results under 1kHz. That makes it look like it’ll need microsecond timing at least to provide usable data.

I first tried making two consecutive calls to clock_gettime() and found that it takes between 2 to 5μs to complete one call on an otherwise idle Raspberry Pi. This wasn’t good enough, so I figured I’d dip into the kernel to see what could be done. The impact of scheduling processes and context switches should be minimized by solving the problem in the kernel. Thus far, this is the most involved attempt I’ve made at messing with the Linux kernel. The result was a bit messy, but I got it working. If you want a peek, its on Github.

I modified the code in bcm2708_gpio.c to record the time from a free-running timer whenever the output of a GPIO was changed, or an input state change triggered an interrupt. After managing to get the code to do about what I intended (sysfs has an extra directory level that I haven’t figured out), I connected two GPIO lines together, set one to be an input and one an output, and set the edge of the input to falling. There is nothing special about the falling edge for this test, but the edge had to be set to trigger the interrupt. Then I set the output to one, then zero, and checked the results.

I found that the timing showed 10 to 11μs would elapse between the output state change and running the GPIO interrupt handler when an X server is also running. Without X, I saw a latency of just under 9μs. The timer was configured to increment once every 4ns, so its precision should be more than adequate for these results. I suppose I could have added a significant digit. I’m surprised the times were so high; given the times on the consecutive calls to clock_gettime(), I was hoping for something better.

I know there are people who will blame Linux for the poor result, but this result is the system timing itself; it includes the hardware. What I saw in the BCM2835 documentation seemed to suggest the processor has an interrupt vector table with one entry, just like Microchip’s PIC16F84, an old 8-bit microcontroller. If so, that would suggest something else causes so much latency that there wasn’t a point in having a larger interrupt table. Even some of Atmel’s AVR 8-bit microcontrollers, like the ATtiny25, have several entries, so it isn’t expensive to do.

While BCM2835 offers poor interrupt response times, it does have nice graphics, runs Linux, and can run all the development tools needed for all this messing around in the kernel. No microcontroller is going to do that, unless it is part of a Rube Goldberg machine. I did build the kernel on my AMD64 deskunder computer, though. It’s much faster.

My biggest surprise doing all this is that it is possible to cause a segmentation fault in the kernel and not crash a single process. Do it a few times, though, and it might crash something. It logged me out once.

Tags: , , , , , , , , , ,

4 Responses to “Raspberry Pi + Linux Interrupt Latency: 10μs”

  1. Geoffrey hunter Says:

    Good investigation into minimum execution times for interrupts for the RPi! I’ve been wanting to use the RPi for many embedded applications, and this is one of the limiting factors.

  2. Maximilian Rixius Says:

    The main problem is probably that there is only one (normal) interrupt level. If the interrupt is already busy (which can take an undefined time), no other interrupt will get a chance. However there is a Fast Interrupt as well, which gets priority, but it can be used for only one interrupt source.

    I intend to generate precisely timed digital output signals for stepper motor control. Lets see what precision I can get on a Raspberry Pi 3…

    • jjackowski Says:

      I missed the fast interrupt; is that something only on newer Raspberry Pi’s? I only did the test on a model B new enough to have 512MB RAM, so I am interested in any results you get for the Pi 3.

      I do recall seeing some documentation suggesting that the Video Core IV processor had a good number of interrupt vectors. Maybe enough information will, or has, become available to program it to manage a low-latency response. Might be a bit awkward, though.

      • Maximilian Rixius Says:

        Fast Interrupt is a core feature of the ARM architecture, so it was probably always available.

        However I’m not so sure anymore that it is of any use to me: I heard that USB uses the fast interrupt and Ethernet in turn is attached to USB. Hmm.

Leave a comment