请求/应答方案往往效率低下,并且在串行端口上很快出现。如果您对吞吐量感兴趣,请查看窗口协议,例如 kermit 文件发送协议。
现在,如果你想坚持你的协议并减少延迟,选择、轮询、读取都会给你大致相同的延迟,因为正如 Andy Ross 所指出的,真正的延迟是在硬件 fifo 处理中。
如果幸运的话,您可以在不打补丁的情况下调整驱动程序的行为,但您仍然需要查看驱动程序代码。然而,让 ARM 处理 10 kHz 的中断率肯定不会有利于整体系统性能......
另一种选择是填充您的数据包,以便您每次都达到 fifo 阈值。它还将确认是否是 fifo 阈值问题。
10 ms @ 115200 足以传输 100 个字节(假设为 8N1),所以您看到的可能是因为未设置 low_latency 标志。尝试
setserial /dev/<tty_name> low_latency
它将设置 low_latency 标志,当在 tty 层中向上移动数据时,内核会使用该标志:
void tty_flip_buffer_push(struct tty_struct *tty)
{
unsigned long flags;
spin_lock_irqsave(&tty->buf.lock, flags);
if (tty->buf.tail != NULL)
tty->buf.tail->commit = tty->buf.tail->used;
spin_unlock_irqrestore(&tty->buf.lock, flags);
if (tty->low_latency)
flush_to_ldisc(&tty->buf.work);
else
schedule_work(&tty->buf.work);
}
schedule_work 调用可能是您观察到的 10 毫秒延迟的原因。