我正在使用 select 调用使用串行端口 RS232 与外部子系统通信(相同的协议(protocol)已作为 Qt 线程提供和实现)。我们没有外部系统的硬件,因此我们使用 .Net 2.0 和 C# 开发了内部模拟器来模拟底层子系统硬件的行为。有 5 个不同的子系统与我们的应用程序通信。子系统的每个接口(interface)都作为 Qt 线程实现。由于这不是实时应用程序,并且当我们使用模拟器进行通信时我们没有实际的硬件,因此所有系统都会找到 24 小时左右,之后通信会断断续续,最终所有通信都会中断,但是当我在不关闭我的应用程序的情况下重新启动模拟器机器时,一切都会好起来的。为什么会这样?
我的猜测是,由于 .Net/C# 不是实时框架,而且在模拟器运行 24 小时后,数据发送速率开始变慢,串口堵塞;重新启动会刷新所有内容,因此一切都会恢复正常。这只是一个猜测。如果有人有更好的意见,请分享。请注意,模拟器是由不同的 .Net 团队制作的。
注意:每个协议(protocol)都有不同的数据速率,1 Hz、5 Hz、10 Hz。
有一个系统即使在模拟器重启后也不会恢复通信。这个系统的端口配置是
SetPortConfiguration()
{
tcgetattr(Fd,&mOldtio);
mNewtio.c_cflag = B4800 | CS8 | CLOCAL | CREAD | CRTSCTS;
mNewtio.c_iflag = 0; //setting the input flag to icrnl causes a blank frame to be displayed after every frame.
mNewtio.c_oflag = 0;
mNewtio.c_lflag =ICANON;
mNewtio.c_cflag &=~PARENB;
mNewtio.c_cflag &= ~CSTOPB;
//mNewtio.c_cflag &= ~HUPCL; //added on 24/3/09
mNewtio.c_cc[VEOL]=0; //setting VEOL to '\r' or '\n' causes a blank frame to be displayed after every frame.
mNewtio.c_cc[VKILL] = 0; /* @ */
mNewtio.c_cc[VSTART] = 0; /* Ctrl-q */
mNewtio.c_cc[VSTOP] = 0; /* Ctrl-s */
mNewtio.c_cc[VMIN]=0;
mNewtio.c_cc[VTIME]=0;
tcflush(Fd, TCIFLUSH);
tcflow(Fd,TCION);
tcsetattr(Fd,TCSANOW,&mNewtio);
}
还有一个重置端口的功能:
ResetPort()
{
tcflush(Fd, TCIFLUSH); //flush all data received but not read
tcflow(Fd,TCIOFF); //transmits a STOP character, which stops the terminal device from transmitting data to the system
tcsetattr(Fd, TCSANOW, &mOldtio);//set the old terminal settings
ClosePort(); //close port
OpenPort(mStrPortNo); //open the port specified by port number and in read mode
SetPortConfiguration();
}
如果通信中断,我会调用 ResetPort 函数关闭并重新打开端口。这解决了所有情况下的问题,除了一个系统说 XYZ。 XYZ 系统以 NMEA 格式发送数据,每个数据包都是以回车符、换行符组合结尾的数据字符串。
任何关于可能是什么问题的想法?
最佳答案
“.Net 实时”位是一个转移注意力的问题。串行端口太慢了,8086 可以控制它们。任何现代 CPU 都可能有空闲的周期,即使在 115200 波特率下也是如此。即使没有,RS232 缓冲区的深度通常以毫秒而不是小时来衡量。
串行端口的“堵塞”将物理类比推得太远了。
很难确定是什么导致了您的问题,因为您实际上并没有告诉我们那是什么。 “崩溃”不是我们能解决的。字节丢失、写入超时 - 这是我们可以解决的具体行为。
关于c++ - Linux串口通信异常?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1135392/