嵌入式Linux:SC16IS752缓冲区溢出

时间:2014-07-15 14:14:09

标签: linux

在我的系统中,我使用I2C到2xUART转换器SC16IS752。 Linux内核源代码已经有了该芯片的驱动程序,但仅限于SPI模式。现在我尝试修改此驱动程序以进行I2C工作。 I2C的速度为400 kHz。在波特38400上连接到该转换器的UART连接设备。该设备每1s发送一个包含大约100字节数据的数据包。 SC16IS752具有64字节RX FIFO,因此每个数据包必须处理两次。

我遇到了长时间延迟的问题。当FIFO达到阈值时,发生硬件中断,现在执行IRQ处理程序:

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

因此,正如您所看到的,中断处理程序将来自SC16IS752 FIFO的句柄数据的工作放入队列中。

这里我遇到了问题。 sc16is7x2_irq函数在中断发生后立即执行。 但是在中断发生后的25ms内完成排队工作。但在此之后,FIFO溢出且数据丢失(100字节在26ms内传输)。

在这种情况下,正确的解决方案是什么以及如何在Linux内核中减少25ms的延迟?

1 个答案:

答案 0 :(得分:0)

我确定了延迟的来源,它们是由调用函数printk引起的。一个功能大约需要2-3毫秒。