串行编程:测量字符之间的时间

Nic*_*eld 3 c serial-port modbus timing

我正在 Linux 中通过串行线路发送/接收数据,我想找到字符之间的延迟。

Modbus 使用 3.5 个字符的延迟来检测消息帧边界。如果超过 1.5 个字符的延迟,则消息帧被声明为不完整的。

我正在用 C 编写一个快速程序,它基本上是

fd = open(MODEMDEVICE, O_RDWR | O_NOCTTY | O_NONBLOCK);
// setup newtio
....
tcsetattr(fd, TCSANOW, &newtio);
for(;;) {
    res = read(fs, buf, 1);
    if (res > 0) {
        // store time in milliseconds?
        //do stuff
    }
}
Run Code Online (Sandbox Code Playgroud)

有什么方法可以测量这里的时间吗?或者我是否需要以不同的方式查看从串行线路中检索数据?

我还尝试连接到 SIGIO 以在有数据时获取信号,但我似乎一次获取 8 个字节的数据。

(是的,我知道存在一些 modbus 库,但我想在其他应用程序中使用它)

小智 6

简单的答案是......你不能(不是不​​编写你自己的串行驱动程序)!

如果您正在编写 MODBUS主站,则有一些希望:您可以通过等待任何时间(提供超过 3.5 个字符)而不接收任何内容来检测从站响应的结束(select(2) 可以在这里帮助您),或者通过在阅读时即时解析响应(第二种方法浪费的时间少得多)。在收到对前一个请求的响应后,您还必须小心等待至少3.5 个字符时间,然后才能开始传输新请求。“至少”在这里有效!多等也无所谓。等待少了。

如果您正在编写 MODBUS从站,那么您就不走运了。您根本无法从用户空间 Linux可靠地做到这一点。您必须编写自己的串行驱动程序。

顺便说一句,这不是 Linux 的错。这是由于 MODBUS 的成帧方法令人难以置信的愚蠢。

  • +1 表示“MODBUS 框架方法的愚蠢程度令人难以置信”。 (2认同)

Tim*_*oft 5

MODbus 就像许多旧协议一样,非常讨厌现代硬件。

您一次获得 8 个字节的原因是:您的 PC 在硬件中具有(至少)16 字节的用于接收和发送的串行 FIFO。大多数是 64 字节或更大。

可以告诉 uart 设备超时并在多个字符时间后发出接收到的中断

触发电平是可调的,但低电平驱动程序可以“智能”地设置它。尝试使用setserial的低延迟模式)如果必须的话,您可以修改串行驱动程序中的代码。谷歌它(成人内容警告)它不漂亮。

所以例程是伪代码

int实际=读取(数据包,超时1.5个字符)

查看实际接收的字节数

如果少于一个数据包,则有问题,丢弃。

不是很好。