在我的系统中,我使用 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 会溢出,数据会丢失(26ms 内传输 100 字节)。
这种情况下正确的解决方案是什么?如何减少 Linux 内核中的 25 毫秒延迟?
最佳答案
我确定了延迟的根源,它们是由调用函数 printk 引起的。一项功能的执行时间约为 2-3 毫秒。
关于linux - 嵌入式Linux : SC16IS752 buffer overflow,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24760560/