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 的成帧方法令人难以置信的愚蠢。
MODbus 就像许多旧协议一样,非常讨厌现代硬件。
您一次获得 8 个字节的原因是:您的 PC 在硬件中具有(至少)16 字节的用于接收和发送的串行 FIFO。大多数是 64 字节或更大。
可以告诉 uart 设备超时并在多个字符时间后发出接收到的中断。
触发电平是可调的,但低电平驱动程序可以“智能”地设置它。尝试使用setserial的低延迟模式)如果必须的话,您可以修改串行驱动程序中的代码。谷歌它(成人内容警告)它不漂亮。
所以例程是伪代码
int实际=读取(数据包,超时1.5个字符) 查看实际接收的字节数 如果少于一个数据包,则有问题,丢弃。
不是很好。