我正在尝试调试自定义Linux串行驱动程序,该驱动程序在某些问题上缺少某些接收数据。它有一个4个串口的中断,波特率是115200.首先,我想看看如何测量中断处理程序需要多长时间。我使用了perf,但事情只是百分之而不是秒。其次,有没有人看到下面的代码有任何问题可以改进以加快速度?
void serial_interrupt(int irq, void *dev_id)
{
...
// Need to loop through each port to see which port caused the interrupt.
list_for_each(lpNode, &serial_ports)
{
struct serial_port_module *ser_dev = list_entry(lpNode, struct serial_port_module, port_list);
lnIsr = ioread8(ser_dev->membase + ser_dev->chan_num * PORT_OFFSET + SERIAL_ISR);
if (lnIsr & IPM512_RX_INT)
{
while (serialdata_is_data_available(ser_dev)) // equals a ioread8()
{
lcIn = ioread8(ser_dev->membase + ser_dev->chan_num * PORT_OFFSET + SERIAL_RBR);
kfifo_in(&ser_dev->rx_fifo, &lcIn, sizeof(lcIn));
// Notify if anyone is doing a blocking read.
wake_up_interruptible(&ser_dev->read_queue);
}
}
}
}
答案 0 :(得分:0)
使用ftrace API尝试追踪延迟问题。现在是时候了解:https://www.kernel.org/doc/Documentation/trace/ftrace.txt
如果这太重了,那么自己添加一些简单的仪器怎么样? getnstimeofday(struct timespec *ts)
相对轻量级...在sysfs调试文件中可以输出一些代码,最坏的情况是执行时间,调用此函数的延迟的一些统计信息,每个中断可用的最坏情况字节数。如果这个数字接近你的硬件FIFO大小,那你就麻烦了。
一个优化是将数据批量读入缓冲区,只要数据可用,然后输入整个缓冲区,然后唤醒任何读者。
while(data_available(dev))
{
buf[cnt++] = ioread8();
}
kfifo_in(fifo, buf, cnt);
wake_up_interruptible();
但代码执行时间这么简单不太可能成为问题。您可能会遇到错过的中断或中断处理的意外延迟。