在 WiringPi 完成发送串行数据(UART)之前如何阻塞?

How to block until WiringPi finishes to sent serial data (UART)?

设备描述(对于上下文,如果您不喜欢电子设备,请跳过它):

对于一个简单的设备,通信是在半双工UART中完成的(TX和RX在同一根线上),方式如下:

write-mode处于TX(写入)时,RX管脚处于高阻态,TX处于发射状态。当 write-mode 处于 RX(读取)状态时,TX 引脚处于高阻抗状态并且 RX 接收。

这只是为了上下文,我不希望这里有电子 question/answers。

接线PI示例:

为了实现这一点,我有以下示例:

#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 之后)。

我看到了 2 种实现方法:

1.我现在无法对此进行测试,但您似乎可以使用

 void serialFlush (int fd) ;

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

(编辑:在re-reading那句话之后,很明显它确实会刷新要写入的数据,所以这个选项是out...)

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

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

如何将文件描述符操作恢复为阻塞模式,在很多地方都可以找到。您可以使用 this answer 中的代码并执行:

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

之后write() inside serialPutchar will be blocking. Note that fd is opened with O_NONBLOCK in serialOpen().