Linux 奇偶校验的stty串行端口设置不持久
我有一个netcore应用程序,它打开串行端口,一旦检测到奇偶校验错误,就会在控制台上写入“奇偶校验错误”。它在Windows10中运行良好,但无法在Linux下运行 我的假设是操作系统没有将奇偶校验错误传递给netcore 要检查我运行的端口设置,请执行以下操作:Linux 奇偶校验的stty串行端口设置不持久,linux,serial-port,stty,9-bit-serial,Linux,Serial Port,Stty,9 Bit Serial,我有一个netcore应用程序,它打开串行端口,一旦检测到奇偶校验错误,就会在控制台上写入“奇偶校验错误”。它在Windows10中运行良好,但无法在Linux下运行 我的假设是操作系统没有将奇偶校验错误传递给netcore 要检查我运行的端口设置,请执行以下操作: stty -D /dev/ttyS0 -ignpar inpck 然后我跑: stty -D /dev/ttyS0 -a 并且设置似乎如预期的那样正确设置(-ignpar inpck) 然后我运行netcore 3应用程序,但
stty -D /dev/ttyS0 -ignpar inpck
然后我跑:
stty -D /dev/ttyS0 -a
并且设置似乎如预期的那样正确设置(-ignpar inpck)
然后我运行netcore 3应用程序,但未检测到奇偶校验错误
所以我跑了
stty -D /dev/ttyS0 -a
用于验证设置,但这些设置似乎已重置(-ignpar-inpck)
如何强制我的应用程序在启用inpck属性的情况下运行?有没有办法使inpck在默认情况下处于启用状态 谢谢 更新:netcore 3应用程序奇偶校验错误检测在windows 10中工作正常,但在linux下不工作。我的假设是:
- A) netcore运行时未将奇偶校验设置传递给驱动程序 (不太可能)
- B) 操作系统正在忽略这些指令
- stty命令只是shell使用termios API的一种方法。
应用程序预计将使用termios API根据具体情况(而不是依赖于启动时的预期配置)配置串行终端。
如果您使用的应用程序环境不允许访问termios API,则您可能使用了不适当的方法 你知道有哪款linux应用程序可以对奇偶校验错误做出明确的反应吗 以下C程序从串行终端读取行(即规范模式),并配置为检测标记(或1)作为具有8位字符帧的奇偶校验位
#define SERIALTERMINAL "/dev/ttyS0"
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>
int set_interface_attribs(int fd, int speed)
{
struct termios tty;
if (tcgetattr(fd, &tty) < 0) {
printf("Error from tcgetattr: %s\n", strerror(errno));
return -1;
}
cfsetospeed(&tty, (speed_t)speed);
cfsetispeed(&tty, (speed_t)speed);
tty.c_cflag |= CLOCAL | CREAD;
tty.c_cflag &= ~CSIZE;
tty.c_cflag |= CS8; /* 8-bit characters */
tty.c_cflag |= PARENB; /* enable parity */
tty.c_cflag &= ~PARODD; /* Even parity */
tty.c_cflag |= CMSPAR; /* force Even parity to SPACE */
tty.c_cflag &= ~CSTOPB; /* only need 1 stop bit */
tty.c_cflag &= ~CRTSCTS; /* no hardware flowcontrol */
tty.c_lflag |= ICANON | ISIG; /* canonical input */
tty.c_lflag &= ~(ECHO | ECHOE | ECHONL | IEXTEN);
tty.c_iflag &= ~IGNCR; /* preserve carriage return */
tty.c_iflag &= ~(INLCR | ICRNL | IUCLC | IMAXBEL);
tty.c_iflag &= ~(IXON | IXOFF | IXANY); /* no SW flowcontrol */
tty.c_iflag |= IGNBRK; /* ignore breaks */
tty.c_iflag &= ~ISTRIP;
tty.c_iflag &= ~IGNPAR; /* report error */
tty.c_iflag |= INPCK; /* test parity */
tty.c_iflag |= PARMRK; /* verbose parity err */
tty.c_oflag &= ~OPOST;
tty.c_cc[VEOL] = 0;
tty.c_cc[VEOL2] = 0;
tty.c_cc[VEOF] = 0x04;
if (tcsetattr(fd, TCSANOW, &tty) != 0) {
printf("Error from tcsetattr: %s\n", strerror(errno));
return -1;
}
return 0;
}
int main(void)
{
char *portname = SERIALTERMINAL;
int fd;
int wlen;
fd = open(portname, O_RDWR | O_NOCTTY | O_SYNC);
if (fd < 0) {
printf("Error opening %s: %s\n", portname, strerror(errno));
return -1;
}
/*baudrate 115200, 8 bits, Space for parity, 1 stop bit */
set_interface_attribs(fd, B115200);
/* simple output */
wlen = write(fd, "Hello!\n", 7);
if (wlen != 7) {
printf("Error from write: %d, %d\n", wlen, errno);
}
tcdrain(fd); /* delay for output */
/* simple canonical input, read lines */
do {
unsigned char buf[81];
unsigned char *p;
int rdlen;
rdlen = read(fd, buf, sizeof(buf) - 1);
if (rdlen > 0) {
buf[rdlen] = 0;
printf("Read %d:", rdlen);
/* first display as hex numbers then ASCII */
for (p = buf; rdlen-- > 0; p++) {
printf(" 0x%x", *p);
if (*p < ' ')
*p = '.'; /* replace any control chars */
}
printf("\n \"%s\"\n\n", buf);
} else if (rdlen < 0) {
printf("Error from read: %d: %s\n", rdlen, strerror(errno));
} else { /* rdlen == 0 */
printf("Nothing read. EOF?\n");
}
/* repeat read */
} while (1);
}
该串行端口似乎不能传输奇偶校验的8位数据(11位帧),但似乎能够读取奇偶校验的8位数据
串行数据由具有9位UART功能的SBC生成。使用示波器捕获帧,以确认8S1和8E1帧的长度为11位。(FTDI USB-to-RS232转换器在生成具有8位字符的所有奇偶校验配置时不可靠。)
当发送器配置为8位和奇偶校验空间(与程序匹配)时,PC程序读取“ABCDEFG\n”为: 数据读取正确
当发送器配置为8位偶数奇偶校验时,PC程序读取“ABCDEFG\n”为: 读取(正确)将三个带有标记而不是空格的字符标识为奇偶校验位。
带有“奇偶校验错误”的每个字符前面都有
0xFF 0x00
(即总共三个字节)的字节
请注意,当实际接收的数据为0xFF
(无奇偶校验错误)时,termios会将该数据扩展为两个字节的0xFF 0xFF
。因此,请注意,当下一个数据为0x00
时,这不是错误指示。低读数0xFF 0xFF 0x00
转换为实际数据0xFF 0x00
但是当实际接收的数据是带有奇偶校验错误的
0xFF
时,read返回0xFF 0x00 0xFF
(即没有与错误指示相结合的扩展)。stty命令只是shell使用termios API的一种方法。应用程序预计将使用termios API根据具体情况(而不是依赖于启动时的预期配置)配置串行终端。
如果您使用的应用程序环境不允许访问termios API,则您可能使用了不适当的方法 你知道有哪款linux应用程序可以对奇偶校验错误做出明确的反应吗 以下C程序从串行终端读取行(即规范模式),并配置为检测标记(或1)作为具有8位字符帧的奇偶校验位
#define SERIALTERMINAL "/dev/ttyS0"
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>
int set_interface_attribs(int fd, int speed)
{
struct termios tty;
if (tcgetattr(fd, &tty) < 0) {
printf("Error from tcgetattr: %s\n", strerror(errno));
return -1;
}
cfsetospeed(&tty, (speed_t)speed);
cfsetispeed(&tty, (speed_t)speed);
tty.c_cflag |= CLOCAL | CREAD;
tty.c_cflag &= ~CSIZE;
tty.c_cflag |= CS8; /* 8-bit characters */
tty.c_cflag |= PARENB; /* enable parity */
tty.c_cflag &= ~PARODD; /* Even parity */
tty.c_cflag |= CMSPAR; /* force Even parity to SPACE */
tty.c_cflag &= ~CSTOPB; /* only need 1 stop bit */
tty.c_cflag &= ~CRTSCTS; /* no hardware flowcontrol */
tty.c_lflag |= ICANON | ISIG; /* canonical input */
tty.c_lflag &= ~(ECHO | ECHOE | ECHONL | IEXTEN);
tty.c_iflag &= ~IGNCR; /* preserve carriage return */
tty.c_iflag &= ~(INLCR | ICRNL | IUCLC | IMAXBEL);
tty.c_iflag &= ~(IXON | IXOFF | IXANY); /* no SW flowcontrol */
tty.c_iflag |= IGNBRK; /* ignore breaks */
tty.c_iflag &= ~ISTRIP;
tty.c_iflag &= ~IGNPAR; /* report error */
tty.c_iflag |= INPCK; /* test parity */
tty.c_iflag |= PARMRK; /* verbose parity err */
tty.c_oflag &= ~OPOST;
tty.c_cc[VEOL] = 0;
tty.c_cc[VEOL2] = 0;
tty.c_cc[VEOF] = 0x04;
if (tcsetattr(fd, TCSANOW, &tty) != 0) {
printf("Error from tcsetattr: %s\n", strerror(errno));
return -1;
}
return 0;
}
int main(void)
{
char *portname = SERIALTERMINAL;
int fd;
int wlen;
fd = open(portname, O_RDWR | O_NOCTTY | O_SYNC);
if (fd < 0) {
printf("Error opening %s: %s\n", portname, strerror(errno));
return -1;
}
/*baudrate 115200, 8 bits, Space for parity, 1 stop bit */
set_interface_attribs(fd, B115200);
/* simple output */
wlen = write(fd, "Hello!\n", 7);
if (wlen != 7) {
printf("Error from write: %d, %d\n", wlen, errno);
}
tcdrain(fd); /* delay for output */
/* simple canonical input, read lines */
do {
unsigned char buf[81];
unsigned char *p;
int rdlen;
rdlen = read(fd, buf, sizeof(buf) - 1);
if (rdlen > 0) {
buf[rdlen] = 0;
printf("Read %d:", rdlen);
/* first display as hex numbers then ASCII */
for (p = buf; rdlen-- > 0; p++) {
printf(" 0x%x", *p);
if (*p < ' ')
*p = '.'; /* replace any control chars */
}
printf("\n \"%s\"\n\n", buf);
} else if (rdlen < 0) {
printf("Error from read: %d: %s\n", rdlen, strerror(errno));
} else { /* rdlen == 0 */
printf("Nothing read. EOF?\n");
}
/* repeat read */
} while (1);
}
该串行端口似乎不能传输奇偶校验的8位数据(11位帧),但似乎能够读取奇偶校验的8位数据
串行数据由具有9位UART功能的SBC生成。使用示波器捕获帧,以确认8S1和8E1帧的长度为11位。(FTDI USB-to-RS232转换器在生成具有8位字符的所有奇偶校验配置时不可靠。)
当发送器配置为8位和奇偶校验空间(与程序匹配)时,PC程序读取“ABCDEFG\n”为: 数据读取正确
当发送器配置为8位偶数奇偶校验时,PC程序读取“ABCDEFG\n”为: 读取(正确)将三个带有标记而不是空格的字符标识为奇偶校验位。
带有“奇偶校验错误”的每个字符前面都有
0xFF 0x00
(即总共三个字节)的字节
请注意,当实际接收的数据为0xFF
(无奇偶校验错误)时,termios会将该数据扩展为两个字节的0xFF 0xFF
。因此,请注意,当下一个数据为0x00
时,这不是错误指示。低读数0xFF 0xFF 0x00
转换为实际数据0xFF 0x00
但是,当实际接收的数据是带有奇偶校验错误的
0xFF
时,read返回0xFF 0x00 0xFF
(即,没有与错误指示相结合的扩展)。“我如何强制我的应用程序使用inpck fuse运行…”——它不是“fuse”,通常只可编程一次。termios手册页将INPCK及其种类称为“常量”、“标志”和“属性”。因此,请使用适当的术语,并选择这三种术语中的任意一种,而不是“fuse”。stty命令只是shell中利用termios API的一种方法。应用程序应使用termios API根据sit的确切要求配置串行终端
Read 8: 0x41 0x42 0x43 0x44 0x45 0x46 0x47 0xa
"ABCDEFG."
Read 14: 0x41 0x42 0xff 0x0 0x43 0x44 0xff 0x0 0x45 0xff 0x0 0x46 0x47 0xa
"AB�.CD�.E�.FG."