我有一个应用程序希望通过全双工串行线路进行 I/O。那是:
char buf[4];
write(fd, "ping", 4);
read(fd, buf, 4);
...期望最终得到远程设备响应“ping”字符串而传输的任何四个字节。
但我在半双工 RS485 线路上运行,因此在串行线路上传输的每个字节也会在串行线路上接收(因为它们是同一条线)。因此,上面的代码片段总是在远程设备传输任何内容之前将“ping”读取到缓冲区中。
显然主机代码并没有预料到这一点。
我想出的最佳解决方案是始终在写入后进行读取并验证接收到的字符是否与发送的字符匹配,然后忽略它们。
但还有更好的办法吗?是否有可靠的 Unix 习惯用法来在传输字符期间禁止接收字符?
(我很欣赏我的问题中有很多微妙之处和曲折的小迷宫。例如,UART 是否有 fifo?接收进程是否在同一个线程中运行?等等。如果很容易,我就不会问unix.stackexchange!
更新
我实现了一个简单的例程,在每个例程之后调用write()
等效read()
的字节数,然后使用它strncmp()
来验证它们是否匹配。它看起来很强大,但我仍然有兴趣知道是否有一种驱动程序级别的方法可以做得更好,或者至少是不同的。
答案1
务实地说,如果您所拥有的似乎有效,并且您不希望设置发生任何变化,或者这是一次性的黑客攻击,那么请继续使用您的解决方案。
然而,Linux 有一个 APIRS485对于合适的硬件,你可以尝试一下。某些硬件具有内置的半双工模式,如果将串行端口置于适当的状态,该模式就会起作用。例如,ioctl 用于启用 RS485 模式:
#include <linux/serial.h>
struct serial_rs485 rs485conf = {0};
rs485conf.flags |= SER_RS485_ENABLED;
if (ioctl (fd, TIOCSRS485, &rs485conf) < 0) ...
或者发送时将 RTS 引脚的逻辑电平设置为 1:
rs485conf.flags |= SER_RS485_RTS_ON_SEND;