通过 termios 编程伪终端通信。奇偶校验位选项不起作用
Programming pseudo terminals communication by termios. Parity bit option doesn't works
我需要使用串行端口进行聊天。我通过 socat 模拟 pty:
socat -d -d PTY PTY
接下来我写了一个小demo。这就是我初始化 termios 结构的方式:
int tty_fd = open(argv[1], O_RDWR | O_NONBLOCK);
struct termios tio;
bzero(&tio, sizeof(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 and set bit per byte
tio.c_cflag |= CLOCAL | CREAD | CS8;
// NOTE: The following block overrides PARMRK and PARENB bits cleared by cfmakeraw.
tio.c_cflag |= PARENB; // Enable even 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
if (is_odd)
tio.c_cflag |= PARODD;
tcsetattr(tty_fd, TCSANOW, &tio);
接下来我的整个演示列表:
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <termios.h>
#include <string.h>
struct termios init(int);
int main(int argc,char** argv)
{
struct termios tio;
char c = 0;
int tty_fd = open(argv[1], O_RDWR | O_NONBLOCK);
tio = init(strcmp(argv[3], "odd"));
if (tcsetattr(tty_fd, TCSANOW, &tio) == -1)
{
printf("Failed to setup the port");
return -1;
}
if (strcmp(argv[2], "write") == 0)
{
while (c != 'q')
{
scanf("%c", &c);
write(tty_fd, &c, 1);
}
}
if (strcmp(argv[2], "read") == 0)
{
while (c != 'q')
{
if (read(tty_fd, &c, 1) > 0)
printf("%c", c);
}
}
close(tty_fd);
}
struct termios init(int is_odd)
{
struct termios tio;
bzero(&tio, sizeof(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 and set bit per byte
tio.c_cflag |= CLOCAL | CREAD | CS8;
// NOTE: The following block overrides PARMRK and PARENB bits cleared by cfmakeraw.
tio.c_cflag |= PARENB; // Enable even 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
if (is_odd == 0)
tio.c_cflag |= PARODD;
return tio;
}
当我以 reader 身份启动一个应用程序,并以相似的奇偶校验方式启动另一个应用程序时,一切正常。但是当我尝试测试奇偶校验位设置时,我以不同的奇偶校验位启动它们,一切正常。所有消息发送无误。
是因为使用了伪终端,而不是真正的 COM 端口吗?
或者也许我创建一个 pty 的方式?
我的搭档也尝试使用 python 进行类似的测试,也有类似的结果。我使用 Linux Mint 17.3。
感谢您的回放。
我已阅读 pty 的手册页,发现伪终端根本不支持 termios 的 c_cflag 标志。
我需要使用串行端口进行聊天。我通过 socat 模拟 pty:
socat -d -d PTY PTY
接下来我写了一个小demo。这就是我初始化 termios 结构的方式:
int tty_fd = open(argv[1], O_RDWR | O_NONBLOCK);
struct termios tio;
bzero(&tio, sizeof(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 and set bit per byte
tio.c_cflag |= CLOCAL | CREAD | CS8;
// NOTE: The following block overrides PARMRK and PARENB bits cleared by cfmakeraw.
tio.c_cflag |= PARENB; // Enable even 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
if (is_odd)
tio.c_cflag |= PARODD;
tcsetattr(tty_fd, TCSANOW, &tio);
接下来我的整个演示列表:
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <termios.h>
#include <string.h>
struct termios init(int);
int main(int argc,char** argv)
{
struct termios tio;
char c = 0;
int tty_fd = open(argv[1], O_RDWR | O_NONBLOCK);
tio = init(strcmp(argv[3], "odd"));
if (tcsetattr(tty_fd, TCSANOW, &tio) == -1)
{
printf("Failed to setup the port");
return -1;
}
if (strcmp(argv[2], "write") == 0)
{
while (c != 'q')
{
scanf("%c", &c);
write(tty_fd, &c, 1);
}
}
if (strcmp(argv[2], "read") == 0)
{
while (c != 'q')
{
if (read(tty_fd, &c, 1) > 0)
printf("%c", c);
}
}
close(tty_fd);
}
struct termios init(int is_odd)
{
struct termios tio;
bzero(&tio, sizeof(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 and set bit per byte
tio.c_cflag |= CLOCAL | CREAD | CS8;
// NOTE: The following block overrides PARMRK and PARENB bits cleared by cfmakeraw.
tio.c_cflag |= PARENB; // Enable even 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
if (is_odd == 0)
tio.c_cflag |= PARODD;
return tio;
}
当我以 reader 身份启动一个应用程序,并以相似的奇偶校验方式启动另一个应用程序时,一切正常。但是当我尝试测试奇偶校验位设置时,我以不同的奇偶校验位启动它们,一切正常。所有消息发送无误。
是因为使用了伪终端,而不是真正的 COM 端口吗?
或者也许我创建一个 pty 的方式?
我的搭档也尝试使用 python 进行类似的测试,也有类似的结果。我使用 Linux Mint 17.3。
感谢您的回放。
我已阅读 pty 的手册页,发现伪终端根本不支持 termios 的 c_cflag 标志。