首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >不持久的奇偶校验的stty串口设置

不持久的奇偶校验的stty串口设置
EN

Stack Overflow用户
提问于 2019-07-25 02:13:09
回答 1查看 3.1K关注 0票数 1

我有一个netcore应用程序,它打开串口,一旦检测到奇偶校验错误,就会在控制台上写入“奇偶校验错误”。它在Windows 10中运行良好,但在Linux下无法工作。

我的假设是,操作系统没有将奇偶校验错误传递给netcore。

用于检查我运行的端口设置:

代码语言:javascript
复制
stty -D /dev/ttyS0 -ignpar inpck

然后我跑:

代码语言:javascript
复制
stty -D /dev/ttyS0 -a 

并且这些设置似乎按照预期正确设置(-ignpar inpck)。

然后我运行我的netcore 3应用程序,但是没有检测到奇偶校验错误。

所以我跑了

代码语言:javascript
复制
stty -D /dev/ttyS0 -a 

用于验证设置,但这些设置似乎被重置(-ignpar -inpck)

如何在启用inpck属性的情况下强制应用程序运行?

默认情况下是否有使inpck启用的方法?

谢谢。

更新: netcore 3应用程序奇偶校验检测在windows 10中运行良好,但在linux下不工作。我的假设是:

  • ( A) netcore运行时没有将奇偶校验设置传递给驱动程序(不太可能)
  • ( B)操作系统无视指令。
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-08-02 01:08:49

stty命令只是shell中利用termios的一种方法。

预计应用程序将使用termios将串行终端配置为特定情况的需求(而不是在启动时依赖预期的配置)。

如果您使用的应用程序环境不允许访问termios,那么您可能使用了不适当的方法。

你知道有什么linux应用可以显式地对奇偶校验错误做出反应吗?

下面的C程序从串行终端读取行(即规范模式),并被配置为检测带有8位字符帧的奇偶校验位标记(或1)。

代码语言:javascript
复制
#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);
}

这个程序是在一个旧的Linux (Ubuntu14.04.2LTS) PC上执行的,它有一个内置的16550 A串口。

代码语言:javascript
复制
[    2.656593] 00:08: ttyS0 at I/O 0x3f8 (irq = 4, base_baud = 115200) is a 16550A

这个串行端口似乎无法传输8位的奇偶校验(11位帧),但似乎能够读取8位的奇偶校验。

串行数据是从具有9位能力的UART的SBC生成的.用示波器捕获帧以确定8S1和8E1帧长为11位。

( FTDI USB到An 232转换器在生成所有8位字符的奇偶配置时不可靠。)

当发送方配置为8位,空间配置为奇偶校验(与程序匹配)时,PC程序将"ABCDEFG\n“读为:

代码语言:javascript
复制
Read 8: 0x41 0x42 0x43 0x44 0x45 0x46 0x47 0xa
    "ABCDEFG."

数据被正确读取。

当发送方配置为8位和偶数奇偶校验时,PC程序将"ABCDEFG\n“读为:

代码语言:javascript
复制
Read 14: 0x41 0x42 0xff 0x0 0x43 0x44 0xff 0x0 0x45 0xff 0x0 0x46 0x47 0xa
    "AB�.CD�.E�.FG."

读取(正确)标识三个字符的标记,而不是空格作为奇偶校验位。

每个带有“奇偶校验错误”的字符前面都是0xFF 0x00字节(即总共三个字节)。

注意,当实际接收到的数据是0xFF (没有奇偶校验错误)时,termios将将该数据扩展到0xFF 0xFF的两个字节。所以请注意,当下一个数据是0x00时,这不是错误指示。IOW读取0xFF 0xFF 0x00将转换为实际数据0xFF 0x00

但是,当实际接收到的数据为带有奇偶校验错误的0xFF时,read返回0xFF 0x00 0xFF (即不存在与错误指示相结合的扩展)。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57193363

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档