我正在尝试从一个设备接收消息,该设备使用地址字节的标记奇偶校验和消息体的空间奇偶校验。该设备是多点串行总线的“主设备”。基于TymiOS MAN页面,我使用CMSPAR、PARENB、~PARDION、IMPCK、IGPAR和PARMRK。我希望每个地址字节上都有一个3字节的序列:'\377''\0'。不会发生的…我总是得到地址字节(和正文字节),但没有前导“\377”\0”字符。
我试图让PARMRK使用奇偶校验设置,以防CMSPAR不被支持。数据流中仍然没有3字节序列。我在用Ubuntu12.04LTS。
n.tTyaRealVePARIYITYROR()具有实现PARMRK的逻辑。8250_core.c具有标记奇偶校验错误的逻辑。dmesg grep ttys0显示serail8250:…是16550A。嗯…随后的消息显示00:0a:…是16550A。也许8250驱动程序实际上没有处理TTYS0?
有什么想法吗?即使你看不到我做错了什么,但已经被派到了工作岗位,对你的处境的评论也许会对我有所帮助。
更新:
我的Linux运行在一个vmware虚拟机上,所以我尝试了一个非vm配置,现在它工作了!如果有人知道,我还是想知道为什么在虚拟机中没有检测到奇偶校验错误。
这是我的配置代码:
struct termios tio;
bzero(&tio, sizeof(tio));
tcgetattr(fd, &tio);
// Frame bus runs at 38,400 BAUD
const int BAUD_Rate = B38400;
cfsetispeed(&tio, BAUD_Rate);
cfsetospeed(&tio, BAUD_Rate);
// Initialize to raw mode. PARMRK and PARENB will be over-ridden before calling tcsetattr()
cfmakeraw(&tio);
// Ignore modem lines and enable receiver
tio.c_cflag |= (CLOCAL | CREAD);
// No flow control
tio.c_cflag &= ~CRTSCTS; // No HW flow control
tio.c_iflag &= ~(IXON | IXOFF); // Set the input flags to disable in-band flow control
// Set bits per byte
tio.c_cflag &= ~CSIZE;
tio.c_cflag |= CS8;
// Use space parity to get 3-byte sequence (0xff 0x00 <address>) on address byte
tio.c_cflag |= CMSPAR; // Set "stick" parity (either mark or space)
tio.c_cflag &= ~PARODD; // Select space parity so that only address byte causes error
// NOTE: The following block overrides PARMRK and PARENB bits cleared by cfmakeraw.
tio.c_cflag |= PARENB; // Enable parity generation
tio.c_iflag |= INPCK; // Enable parity checking
tio.c_iflag |= PARMRK; // Enable in-band marking
tio.c_iflag &= ~IGNPAR; // Make sure input parity errors are not ignored
// Set it up now
if (tcsetattr(fd, TCSANOW, &tio) == -1)
{
cout << "Failed to setup the port: " << errno << endl;
return -1;
}
最佳答案
我也有类似的问题(但从另一个角度看):
串行协议的主协议应该发送带有奇偶校验标记的帧的第一个字节,其余的字节都带有奇偶校验空间,而从协议应该只响应奇偶校验空间。
许多串行通信驱动程序将忽略“CMSPAR”位而不返回错误,因此您可能认为已经设置奇偶校验标记/空间,而实际上已经选择奇偶校验奇偶/奇偶校验位。
我不得不用一个协议分析器来实现这一点。
所以我在发送之前检查了每个字节的数据,并在奇偶校验之间切换,以模拟所需的标记/空间校验。
大多数USB到串行适配器都需要类似的方法,因为它们不支持奇偶校验标记/空间。
例如,假设我们要发送以下数据:
01 03 07 0F 1F
第一个字节应使用奇偶校验标记发送,其余字节应使用奇偶校验空间发送
我们可以这样做:
Send 01 with odd parity (parity bit=1)
Send 03 with odd parity (parity bit=0)
Send 07 with even parity (parity bit=0)
Send 0F with odd parity (parity bit=0)
Send 1F with even parity (parity bit=0)
这样我们就能模拟出所需的结果。
这里的问题是,当您切换奇偶校验时,驱动程序正在执行大量耗时的检查,这可能会影响最终的数据传输速率。
我在一个嵌入式设备上使用了一个黑客版本的串行通信驱动程序,它可以通过省略对应用程序的一些不必要的检查(例如波特率更改)来快速切换奇偶校验。
如果你的字符间延迟是关键的,你可能需要一个不同的解决方案。
关于linux - PARMRK termios行为在Linux上不起作用,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/20132316/