在我的系统中,我使用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的延迟?
答案 0 :(得分:0)
我确定了延迟的来源,它们是由调用函数printk引起的。一个功能大约需要2-3毫秒。