如何阻塞直到WiringPi完成发送串行数据UART的时间?

问题描述

设备描述(有关上下文,如果您对电子设备不满意,请跳过它):

对于简单的设备,通过半双工UART(TX和RX位于同一条线上)进行通信,方法如下:

  • 一个引脚(写模式)指示UART是发送还是接收(1:TX,0:RX)
  • 一个引脚写入导线(TX)。
  • 从导线(RX)读取一个引脚。

write-mode处于TX(写)状态时,RX引脚处于高阻态,TX处于发送状态。 write-mode处于RX(读取)状态时,TX引脚处于高阻状态,RX处于接收状态。

这仅是出于背景考虑,我不希望在这里出现电子问题/答案。

wiringpi示例:

为此,我有以下示例:

#include <wiringpi.h>
#include <wiringSerial.h>

int main()
{
    wiringpiSetup ();
    auto fd = serialOpen ("/dev/ttyAMA0",115200);
    
    pinMode(0,OUTPUT);
    
    for(size_t i=0; i<10; ++i)
    {
        digitalWrite(0,HIGH);
        serialPutchar(fd,'\x55');
        digitalWrite(0,LOW);
        delay(1000);
    }

    serialClose(fd);
}

使用示波器,我可以清楚地看到 write-mode引脚在UART端发送数据之前被重置。

很显然,我尝试添加一些“延迟”或空循环来进行调整,但这在μs时间内是不可靠的(由于OS上计时器的通常精度)。

问题:

如何同步,以便write-mode引脚在发送UART字节后立即复位? (不超过约150μs)。

解决方法

我看到两种实现方法:

1。我目前无法测试,但看来您可以使用

 void serialFlush (int fd) ;

根据文档“这会丢弃接收到的所有数据,或等待向下发送给定设备的文档”,请参见http://wiringpi.com/reference/serial-library/

(编辑:重新阅读该句子后,很明显它确实还会刷新要写入的数据,因此该选项不可用...)

  1. 使用tcdrain()(https://linux.die.net/man/3/tcdrain),在其中传递serialOpen()返回的 fd
,

在文件描述符上设置阻止。

如何在许多地方找到如何将文件描述符操作恢复为阻止模式。您可以使用来自this answer的代码并执行以下操作:

set_blocking_mode(fd,1);
serialPutchar(fd,'\x55');

之后,write() inside serialPutchar将被阻止。请注意,fd为opened with O_NONBLOCK in serialOpen()