PARMRK termios行为无法在Linux上运行

时间:2013-11-21 21:30:21

标签: linux serial-port vmware termios parity

我正在尝试从使用标记奇偶校验的设备接收消息体的地址字节和空间奇偶校验的消息。该器件是多点串行总线的“主”。基于termios手册页,我使用的是CMSPAR,PARENB,~PARODD,INPCK,~IGNPAR和PARMRK。我期望在每个地址字节上得到一个3字节的序列:'\ 377''\ 0'。它不会发生...我总是得到地址字节(和正文字节),但没有前导'\ 377''\ 0'字符。

我试图让PARMRK使用奇数和偶数奇偶校验设置,以防CMSPAR不受支持。数据流中仍然没有3字节序列。我正在使用Ubuntu 12.04 LTS。

n_tty.c:n_tty_receive_parity_error()具有实现PARMRK的逻辑。 8250_core.c具有标记奇偶校验错误的逻辑。 dmesg | grep ttyS0显示serail8250:...是16550A。嗯...随后的消息显示00:0a:...是16550A。也许8250驱动程序实际上并没有处理ttyS0?

有什么想法吗?即使你没有看到我做错了但是让PARMAR工作,关于你的情况的评论可能对我有所帮助。

更新: 我的Linux在VMware VM中运行,因此我尝试了非VM配置,现在它可以工作了!我知道有人知道,我仍然想知道为什么在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;
}

1 个答案:

答案 0 :(得分:0)

我遇到了类似的问题(但是从另一方面来看):

串行协议的主设备应该发送带有奇偶校验标记的帧的第1个字节,其余部分用奇偶校验空间发送,而从设备只响应奇偶校验空间。

许多串行通信驱动程序将忽略&#34; CMSPAR&#34;没有返回错误的位,所以您可能认为您已设置奇偶校验标记/空格,而您实际上已经选择奇偶校验奇数/偶数。

我不得不使用协议分析器来实现这一点。

所以我在发送之前检查每个字节的数据并在奇数/偶数奇偶校验之间切换,以便模拟我需要的标记/空间奇偶校验。

大多数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)

这样我们就可以模拟所需的结果。

这里的问题是,当您切换奇偶校验时,驱动程序正在执行大量耗时的检查,这会影响最终的数据传输速率。

我在嵌入式设备上使用了一个黑客版本的串行通信驱动程序,可以通过省略对应用程序的一些不必要的检查(例如波特率更改)来非常快速地切换奇偶校验。

如果你的字符间延迟很重要,你可能需要一个不同的解决方案。