unix 与调制解调器进行串行通信,tcdrain/tcflush

t3psigkw  于 2023-08-04  发布在  Unix
关注(0)|答案(1)|浏览(150)

我试图创建一个可靠的串行通信与超高频调制解调器。以下是我做的步骤:
要向调制解调器发送命令,请执行以下操作:

1. tcflush(fd, TCIOFLUSH)
 2. readEmpty(fd) -> custom function that reads from fd in a while loop until no characters left, so that fd is empty before reading
 3. write(fd,buf,len) -> send the command to the uhf modem
 4. tcdrain(fd) -> wait for the command to reach the modem

字符串
然后,为了阅读回复,我进入了一个循环,其中:

1. Wait on a select() statement with a relatively big initial timeout
 2. read(fd)
 3. Update timeout value to smaller one, since I already started reading some data, and go back to select(), waiting for more possible data


我的问题是:

  1. tcdrain()tcflush()的用法是这样正确的吗?有没有其他选择?
    1.我读到tcdrain()正在阻塞,可能发生它永远不会返回。有没有办法为tcdrain创建超时机制,或者使用其他没有这个问题的替代方案?
xxhby3vn

xxhby3vn1#

我正在尝试建立一个可靠的串行通讯...
这是一个有价值的目标。

  1. tcdrain()和tcflush()的用法是这样正确的吗?
    不太清楚

**tcdrain()**通常只需要用于与硬件显式同步,例如在传输停止位后翻转控制线。否则,对该完成事件的检测通常可以用更高级别的事件(例如响应的到达)代替。

您对tcdrain()*的“ 等待命令到达调制解调器 *”的表示法是乐观的。tcdrain()系统调用只等待本地外设传输数据。接下来会发生什么是完全未知的。通过这一次系统调用,数据到达目的地永远不会得到保证。电缆可能会从系统中拔下,数据/消息(例如命令)将永远不会到达其预期目的地(例如调制解调器)。
IMO
tcflush()通常只需要在更改线路设置(例如:波特率、帧大小、奇偶校验)或在错误情况之后的清除期间作为最后手段。
您的用户空间程序是在多任务环境中执行的,通常不会与来自串行链路的数据以及终端处理和缓冲层(例如研究Linux serial drivers)。除非您认为您可以完全控制串行消息何时到达(例如在主-从连接的主侧),我可以想象这样一种情况,其中行为不当的从单元在不适当的时间发送消息以阻挠仅读取“干净”消息的简单方案。
IOW不是使用
tcfliush()*试图(徒劳地)删除“不需要的”字节,读取处理需要健壮,以处理不仅仅是完美接收的、完整的和及时的响应。
有没有其他选择?
为了您的“
可靠的串行通信 *”的预期目的,是的。
不需要使用
tcdrain()
。来自调制解调器的响应是请求被成功发送和接收的确认。
不需要使用tcflush()。而不是无条件地丢弃数据,接收数据的处理需要是鲁棒的,并且能够检测畸形或意外响应。
你故意丢弃调制解调器发送的数据而不加任何考虑的计划似乎不符合你的“* 可靠串行通信 *”的目标。既然调制解调器发送了这些数据,那么这些数据是否具有某种至少值得检查的价值或意义?该方案似乎更像是“让我们保持程序简单”。
1.我读到tcdrain()正在阻塞,并且可能发生它永远不会返回的情况。有没有办法为tcdrain创建一个超时机制,或者使用其他没有这个问题的方法?
您可以通过仅在实际需要时使用**tcdrain()来避免此问题。您的tcdrain()**示例在IMO中是不必要的。

**tcdrain()**中的扩展块可能会在以下情况下发生:(a)出现严重的硬件故障(实际上不值得恢复),或(b)流控制(即HW或SW握手)处于活动状态并阻止传输。

相关问题