串口通讯模式相关字段含义

0.设置原始模式函数:

当串口通讯设置成原始模式时,会变成纯二进制传输流。

cfmakeraw(&tty);

// 与下方代码等价
///@see https://www.man7.org/linux/man-pages/man3/cfmakeraw.3.html

       termios_p->c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP
                           | INLCR | IGNCR | ICRNL | IXON);
           termios_p->c_oflag &= ~OPOST;
           termios_p->c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
           termios_p->c_cflag &= ~(CSIZE | PARENB);
           termios_p->c_cflag |= CS8;

man 文档地址

以下为逐个参数的解释

1. 输入模式标志 (c_iflag) - 控制输入数据的预处理

termios_p->c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON);

这行代码禁用了以下所有输入处理功能:

  • IGNBRKIgnore Break Condition。忽略 BREAK 条件(一种特殊的长时中断信号,用于表示通信协议中的事件)。禁用后,BREAK 条件会被当作一个 \0 字符读取。
  • BRKINTBreak Interrupt。如果 IGNBRK 未设置,收到 BREAK 条件会产生一个 SIGINT 信号(就像在终端按下 Ctrl+C)。这里也禁用了。
  • PARMRKParity Mark。禁用对奇偶校验错误的特殊标记。如果启用,有奇偶校验错的字节会被特殊标记(\377 \0 <byte>\377 <byte>),而不是直接传递错误字节。
  • ISTRIPStrip off 8th bit。将输入的字符高位(第8位)截断,只保留7位。禁用后,可以接收8位数据(0-255),这对于传输二进制数据至关重要。
  • INLCRMap NL to CR。将接收到的换行符 NL (\n, 0x0A) 转换为回车符 CR (\r, 0x0D)。禁用后,不会进行转换。
  • IGNCRIgnore CR。忽略接收到的回车符 CR (\r)。禁用后,CR 字符会被正常接收。
  • ICRNLMap CR to NL。将接收到的回车符 CR (\r) 转换为换行符 NL (\n)。这是许多终端模拟器的常见设置,但在原始模式下必须禁用,以保证 \r\n 都能被正确区分和接收。
  • IXONEnable XON/XOFF flow control。启用软件流控制。禁用后,主机将不会监听来自设备的 XON (Ctrl+Q, 0x11) 和 XOFF (Ctrl+S, 0x13) 字符来暂停/继续数据流。这通常是为了避免这些控制字符干扰二进制数据流。

2. 输出模式标志 (c_oflag) - 控制输出数据的后处理

termios_p->c_oflag &= ~OPOST;

  • OPOSTEnable Output Processing。这是最关键的输出处理开关。
    • 启用时:会根据其他标志(如 ONLCR - 将 \n 输出为 \r\n)对输出数据进行处理。
    • 禁用时 (~OPOST)输出数据完全不做任何处理。应用程序调用 write() 写入什么字节,驱动就原封不动地向串口发送什么字节。

3. 本地模式标志 (c_lflag) - 控制终端的本地行为

termios_p->c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);

这行代码禁用了所有终端特性:

  • ECHOEcho input characters。回显输入字符。例如,在终端输入密码时需要禁用,在这里禁用是为了避免数据被意外回显干扰通信。
  • ECHONLEcho NL even if ECHO is off。即使 ECHO 关闭,也回显换行符。显然也不需要。
  • ICANONEnable canonical mode启用规范模式(也叫行模式)。这是最关键的一个标志。
    • 启用时:输入会按行缓冲,直到用户按下回车键,程序才能读到一整行数据。同时会启用行内编辑功能(如退格键)。
    • 禁用时 (~ICANON)启用非规范模式(原始模式)。程序可以立即读取到每一个输入的字符,无需等待回车。这是实现原始数据输入的基础。
  • ISIGEnable signals。启用信号。禁用后,收到 INTR (Ctrl+C), QUIT (Ctrl+\), SUSP (Ctrl+Z) 等特殊字符时,不会产生相应的 SIGINT, SIGQUIT, SIGTSTP 信号,这些字符会作为普通数据传递给应用程序。
  • IEXTENEnable implementation-defined functions。启用实现相关的特殊功能(如 Ctrl+V 字面输入下一个字符)。禁用后,这些功能失效。

4. 控制模式标志 (c_cflag) - 设置硬件参数

termios_p->c_cflag &= ~(CSIZE | PARENB);
termios_p->c_cflag |= CS8;

这两行代码共同设置了串口通信的数据位奇偶校验

  • c_cflag &= ~(CSIZE | PARENB);
    • ~CSIZE: 这是一个位掩码,用于清除当前设置的数据位大小。
    • ~PARENB禁用奇偶校验(Parity Enable)。不生成也不检查奇偶校验位。
  • c_cflag |= CS8;
    • CS8: 设置字符大小为 8 数据位。这是最常见的设置。其他选项还有 CS7 (7位), CS6 (6位), CS5 (5位)。

posted @ 2025-09-18 14:33  BlackSnow  阅读(13)  评论(0)    收藏  举报