Vincent
Vincent

Reputation: 175

Handling IRQ delay in linux driver

I've build a linux driver for an SPI device. The SPI device sends an IRQ to the processor when a new data is ready to be read.

The IRQ fires about every 3 ms, then the driver goes to read 2 bytes with SPI.

The problem I have is that sometimes, there's more than 6 ms between the IRQ has been fired and the moment where SPI transfer starts, which means I lost 2 bytes of the SPI device.

In addition, there's a uncertain delay between the 2 bytes; sometime it's close to 0, sometime it's up to 300us..

Then my question is : how can I reduce the latency between IRQ and SPI readings ?

And how to avoid latency between the 2 bytes ?

I've tried compiling the kernel with premptive option, it does not change things that much.

As for the hardware, I'm using a mini2440 board running at 400 MHz, using a hardware SPI port (not i/o simulated SPI).

Thanks for help.

BR, Vincent.

Upvotes: 2

Views: 1526

Answers (3)

Gero
Gero

Reputation: 17

I had a similar problem: I basically got an IRQ and needed to drain a queue via SPI in less than 10 ms or the chip would start to drop data. With high system load (ssh login was actually enough) sometimes the delay between the IRQ handler enqueueing the next SPI transfer with spi_async and the SPI transfer actually happening exceeded 11 ms.

The solution I found was the rt flag in struct spi_device (see here). Enabling that will set the thread that controls the SPI to real-time priority, which made the timing of all SPI transfers super reliable. And by the way that change also removes delay before the complete callback.

Just as a heads up, I think this was not available in earlier kernel versions.

Upvotes: 1

Vincent
Vincent

Reputation: 175

The thing is Linux SPI stack uses queues for transmitting the messages.

This means that there is no guarantee about the delay between the moment you ask to send the SPI message, and the moment where it is effectively sent.

Finally, to fullfill my 3ms requirements between each SPI message, I had to stop using Linux SPI stack, and directly write into the CPU's register inside my own IRQ.

That's highly dirty, but it's the only way to make it work with small delays.

Upvotes: 0

thkala
thkala

Reputation: 86443

From the brochure of the Samsung S3C2440A CPU, the SPI interface hardware supports both interrupt and DMA-based operation. A look at the actual datasheet reveals that the hardware also supports a polling mode.

If you want to achieve high data rates reliably, the DMA-based approach is what you need. Once a DMA operation is configured, the hardware will move the data to RAM on its own, without the need for low-latency interrupt handling.

That said, I do not know the state of the Linux SPI drivers for your CPU. It could be a matter of missing support for DMA, of specific system settings or even of how you are using the driver from your own code. The details w.r.t. SPI are often highly dependent on the particular implementation...

Upvotes: 2

Related Questions