【发布时间】:2016-09-18 13:46:04
【问题描述】:
我需要使用串口进行聊天。我通过 socat 模拟 pty:
socat -d -d PTY PTY
接下来我写了一个小演示。这就是我初始化 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;
}
当我启动一个应用程序作为读取器,另一个作为具有相似奇偶校验的写入器时,一切正常。但是当我尝试测试奇偶校验位设置时,我以不同的方式启动它们,一切正常。所有消息都发送没有任何错误。
那是因为使用了伪终端,而不是真正的 COM 端口吗?
或者也许是我创建 pty 的方式?
我的伙伴也尝试使用 python 进行类似的测试,结果也类似。我使用 Linux Mint 17.3。
感谢您的重播。
【问题讨论】:
-
除了可能没有为驱动程序实现奇偶校验(因此被忽略)之外,
init((strcmp(argv[3], "odd") == 1);行是不正确的。init(strcmp(argv[3], "odd") != 0);可能是你想要的 -
不,如果参数相等,strcmp 返回零。
-
我知道。但是,正如您在代码中所假设的那样,在任何其他情况下都不能保证完全返回
1。 -
哦,对不起。发布此内容时,我没有看到。
-
你一定来自Java世界。
标签: c serial-port termios socat