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