0
votes

In my system I'm using I2C to 2xUART converter SC16IS752. Linux Kernel sources already has driver for this chip, but only in SPI mode. Now I trying to modify this driver for I2C work. I2C has speed 400 kHz. To this converter's UART connected device on baud 38400. This device every 1s sends packets containing about 100 bytes data. SC16IS752 has 64 bytes RX FIFO, so it must be handled two times per one packet.

And I faced the problem of long latencies. When FIFO reaches threshold value, hardware interrupt occurs and now executes IRQ handler:

static irqreturn_t sc16is7x2_irq(int irq, void *data)
{
    struct sc16is7x2_channel *chan = data;

#ifdef DEBUG
    /* Indicate irq */
    chan->handle_irq = true;
#endif

    /* Trigger work thread */
    sc16is7x2_dowork(chan);
    return IRQ_HANDLED;
}

static void sc16is7x2_dowork(struct sc16is7x2_channel *chan)
{
    printk("sc16is7x2_dowork \n");

    if(!freezing(current))
    {
        queue_work(chan->workqueue, &chan->work);
    }
}

So, as you can see, interrupt handler puts work for handle data from SC16IS752 FIFO in the queue.

And here i faced with problem. sc16is7x2_irq function executes immediately after interrupt occurs. But queued work is performed within 25ms after interrupt occurs. But after this time, FIFO is overflowed and data lost (100 bytes transmits in 26ms).

What is the correct solution in this situation and how to reduce 25ms latency in Linux Kernel?

1
It's hard to tell where these 25ms come from exactly without doing profiling on your system. Context switch surely takes some time, but 25ms looks way too long for that only; maybe a higher priority process(-es) is running. Setting a higher priority might help, though I personally would simply create a second buffer that irq could use to store data and pass a pointer of it to your process. - KBart
I've tried to play with the priorities and scheldule policies, but it also did not give the desired results. I tried to use the utility "nice" for priority management and "chrt" for select scheldule policy. Policies SCHED_FF and SCHED_RR did not give desired results too. - Andrew Gazizov
Priorities won't solve your problem completely anyway, because there's always a chance for another (unrelated) IRQ to arise between your IRQ and the process. Sure that's 1/1000000 chance, but such problems do happen and are damn hard to catch & solve. Depending on your hardware, DMA might also help here as it doesn't use CPU to transfer data. - KBart

1 Answers

0
votes

I identified the source of delays, they were caused by calling functions printk. One function is performed about 2-3 ms.