如何确定 linux 串行端口上剩余的写入/输出缓冲区空间量?

Posted

技术标签:

【中文标题】如何确定 linux 串行端口上剩余的写入/输出缓冲区空间量?【英文标题】:How can I determine the amount of write/output buffer space left on a linux serial port? 【发布时间】:2012-11-01 16:08:39 【问题描述】:

您可以使用 ioctl 确定在 linux 下可以从串行端口读取多少数据。是否可以确定串行端口在写入时剩余多少缓冲区空间?实际上,我想将一个数据块写入串行端口,只有当它可以一次性全部卸载时才成功,或者如果必须被分块则失败。对端口的写入和读取是非阻塞的。我不希望这是 UARTs 缓冲区,而是 UARTs 缓冲区之前的内核内存缓冲区(我猜)。

【问题讨论】:

怀疑它归结为硬件 tx/rx FIFO 大小,它是由内核从你那里抽象出来的......但内核是否只是将它保存在内部当对硬件来说太多时缓冲?我不知道。 这是我所期望的,所以内核内部缓冲区必须有一些上限。我期望能够检索的界限。 可能值得重新评估问题定义并考虑替代设计选项。也许异步 IO 方案会更好。或open w/O_NONBLOCK,寻找EAGAIN 实际上我正在尝试复制 send() 为套接字提供的功能,即要么全部执行,要么不执行。我将物理传输从应用程序的其余部分抽象出来。整个系统已经是非阻塞的了,所以我知道写不会阻塞,只是不知道会不会把我要的数据全部卸载到内核空间。 好的,试试O_NONBLOCK 【参考方案1】:

您可以确定写入/输出的数量。

供阅读:

ioctl(device_handler, TIOCINQ, &bytes);

写:

ioctl(device_handler, TIOCOUTQ, &bytes);

FIFO 缓冲区大小:

serial_struct serinfo;
memset(&serinfo, 0, sizeof(serinfo));
ioctl(device_handler, TIOCGSERIAL, &serinfo);
serinfo.xmit_fifo_size;

问候, 弗吉尼亚州。

【讨论】:

我已经将它用于套接字,我不知道它适用于任何设备。 serial_struct 需要改为 struct serial_icounter_struct【参考方案2】:

串口是字符设备而不是块设备。它没有缓冲区。 字符设备(如串口、键盘、鼠标)只读写一个字符而不是一个单词。 例如,如果你听某人写的连续剧“祝你有美好的一天”,如果你从他开始打字的时候就没有听,你就看不到整个短语。收听时只会看到输入的字符

【讨论】:

但是里面肯定有一些缓冲吗?至少有 UARTs FIFO。 FIONREAD ioctl 在看什么缓冲区? 是的,有缓冲,但据我所知,它只能在内核模式下访问。您必须在内核中加载一个模块,才能监听设备驱动 我可以使用 FIONREAD ioctl 找到读取的内核模式缓冲大小,但写入却没有并行,这似乎很奇怪。 :-P【参考方案3】:

如果您使用文件描述符访问串行端口,您可以使用select 来检查描述符是否准备好进行非阻塞写入。我不知道这适用于串行端口。我将它用于 TCP 套接字并且它有效。

【讨论】:

以上是关于如何确定 linux 串行端口上剩余的写入/输出缓冲区空间量?的主要内容,如果未能解决你的问题,请参考以下文章

如何强制串行端口写入方法在发送数据之前等待线路清除?

为啥我不能从 Android 上的串行端口打开/写入?

试图从 QDialog 写入串行端口。

如何通过usb端口通信从arduino将串行数据写入phpmyadmin

从串行端口写入和读取

时序问题:QT 写入串行端口,然后读取