之前对struct termios结构体的几个字段一直困惑,主要不知道它的作用,内核对应的struct ktermios结构体如下

struct ktermios {tcflag_t c_iflag;       /* input mode flags */tcflag_t c_oflag;     /* output mode flags */tcflag_t c_cflag;        /* control mode flags */tcflag_t c_lflag;       /* local mode flags */cc_t c_cc[NCCS];      /* control characters */cc_t c_line;            /* line discipline (== c_cc[19]) */speed_t c_ispeed;      /* input speed */speed_t c_ospeed;      /* output speed */
};

其中的tcflag_t c_cflag字段是控制字段,包括奇偶校验、停止位...,应用层在调用tcsetattr()函数时最终调用串口驱动nuc970_serial.c的驱动函数,如下

static void
nuc970serial_set_termios(struct uart_port *port, struct ktermios *termios,struct ktermios *old)
{struct uart_nuc970_port *up = (struct uart_nuc970_port *)port;unsigned int lcr = 0;unsigned long flags;unsigned int baud, quot;switch (termios->c_cflag & CSIZE) {case CS5:lcr = 0;break;case CS6:lcr |= 1;break;case CS7:lcr |= 2;break;default:case CS8:lcr |= 3;break;}if (termios->c_cflag & CSTOPB)lcr |= NSB;if (termios->c_cflag & PARENB)lcr |= PBE;if (!(termios->c_cflag & PARODD))lcr |= EPE;if (termios->c_cflag & CMSPAR)lcr |= SPE;baud = uart_get_baud_rate(port, termios, old,port->uartclk / 16 / 0xffff,port->uartclk / 16);quot = nuc970serial_get_divisor(port, baud);/** Ok, we're now changing the port state.  Do it with* interrupts disabled.*/spin_lock_irqsave(&up->port.lock, flags);up->port.read_status_mask = RX_OVER_IF /*| UART_LSR_THRE | UART_LSR_DR*/;if (termios->c_iflag & INPCK)up->port.read_status_mask |= FEF | PEF;if (termios->c_iflag & (BRKINT | PARMRK))up->port.read_status_mask |= BIF;/** Characteres to ignore*/up->port.ignore_status_mask = 0;if (termios->c_iflag & IGNPAR)up->port.ignore_status_mask |= FEF | PEF;if (termios->c_iflag & IGNBRK) {up->port.ignore_status_mask |= BIF;/** If we're ignoring parity and break indicators,* ignore overruns too (for real raw support).*/if (termios->c_iflag & IGNPAR)up->port.ignore_status_mask |= RX_OVER_IF;}if (termios->c_cflag & CRTSCTS)up->mcr |= UART_MCR_AFE;elseup->mcr &= ~UART_MCR_AFE;nuc970serial_set_mctrl(&up->port, up->port.mctrl);serial_out(up, UART_REG_BAUD, quot | 0x30000000);serial_out(up, UART_REG_LCR, lcr);     spin_unlock_irqrestore(&up->port.lock, flags);}

可以看到在上面有对termios->c_cflag字段进行判断,最终转换为up->port.ignore_status_mask屏蔽字,关于该屏蔽字的功能,主要解决串口驱动在接收到数据时,出现奇偶校验错误的判断,可以看下如下的串口驱动的接收函数

static void
receive_chars(struct uart_nuc970_port *up)
{unsigned char ch;unsigned int fsr;int max_count = 256;char flag;do {ch = (unsigned char)serial_in(up, UART_REG_RBR);fsr = serial_in(up, UART_REG_FSR);flag = TTY_NORMAL;up->port.icount.rx++;if (unlikely(fsr & (BIF | FEF | PEF | RX_OVER_IF))) {if (fsr & BIF) {serial_out(up, UART_REG_FSR, BIF);up->port.icount.brk++;if (uart_handle_break(&up->port))continue;}if (fsr & FEF) {serial_out(up, UART_REG_FSR, FEF);up->port.icount.parity++;}if (fsr & PEF) {serial_out(up, UART_REG_FSR, PEF);up->port.icount.frame++;}if (fsr & RX_OVER_IF) {serial_out(up, UART_REG_FSR, RX_OVER_IF);up->port.icount.overrun++;}// FIXME: check port->read_status_mask to determin report flagsif (fsr & BIF)flag = TTY_BREAK;if (fsr & PEF)flag = TTY_PARITY;if (fsr & FEF)flag = TTY_FRAME;}if (uart_handle_sysrq_char(&up->port, ch))continue;uart_insert_char(&up->port, fsr, RX_OVER_IF, ch, flag);} while (!(fsr & RX_EMPTY) && (max_count-- > 0));spin_lock(&up->port.lock);tty_flip_buffer_push(&up->port.state->port); spin_unlock(&up->port.lock);
}

通过如下函数进行奇偶校验

uart_insert_char(&up->port, fsr, RX_OVER_IF, ch, flag);
void uart_insert_char(struct uart_port *port, unsigned int status,unsigned int overrun, unsigned int ch, unsigned int flag)
{struct tty_port *tport = &port->state->port;if ((status & port->ignore_status_mask & ~overrun) == 0)if (tty_insert_flip_char(tport, ch, flag) == 0)++port->icount.buf_overrun;/** Overrun is special.  Since it's reported immediately,* it doesn't affect the current character.*/if (status & ~port->ignore_status_mask & overrun)if (tty_insert_flip_char(tport, 0, TTY_OVERRUN) == 0)++port->icount.buf_overrun;
}

在该函数内部,可以看到前面初始化的成员ignore_status_mask。

关于linux下UART串口编程的困惑相关推荐

  1. C——Linux下的串口编程

    原 C--Linux下的串口编程 2017年06月06日 19:30:50 C_Aya 阅读数:11537 <span class="tags-box artic-tag-box&qu ...

  2. 串口通信协议和Linux下的串口编程

    一.串口通信介绍: 串口通信(Serial Communications)的概念非常简单,串口按位(bit)发送和接收字节,尽管比按位字节(byte)的并行通信慢,但是串口可以使用一根线发送数据的同时 ...

  3. linux下的串口编程

    本文转自:http://www.cnblogs.com/jason-lu/articles/3173988.html 做人个人学习使用,绝无侵权之意.如果侵权,请尽快联系,谢谢. Linux下串口编程 ...

  4. Linux 下的串口编程(一)

    Linux下串口编程要知道的那些事 --------------------------------------------------------- Author   :tiger-john<

  5. Linux下c++串口编程

    1 NX串口管理 参见https://blog.csdn.net/weixin_42447868/article/details/109051005?spm=1001.2014.3001.5506 2 ...

  6. Linux基础(7)--串口编程

    串口编程 1. 流程分析 2. 开机启动程序 3. 打开串口 4. 串口初始化 5. 串口发送 6. 串口接收 1. 流程分析 Linux下的串口编程流程主要有四个部分,即打开串口,初始化串口,发送和 ...

  7. Linux应用之串口编程

    /声明:本人只是见到这篇文章对我帮助很大才转载的,但是这个完整的程序里面本来有语法错误的,现在让我改过来了/ Author :tiger-john WebSite :blog.csdn.net/tig ...

  8. Linux下的C编程实战

    Linux下的C编程实战(一) ――开发平台搭建 1.引言 Linux操作系统在服务器领域的应用和普及已经有较长的历史,这源于它的开源特点以及其超越Windows的安全性和稳定性.而近年来, Linu ...

  9. Linux下的C编程实战(转载)

    http://www.cnblogs.com/alexusli/archive/2008/10/24/1318736.html Linux下的C编程实战(转载) (转自)http://www.cnbl ...

最新文章

  1. 【spring】spel表达式
  2. 珍藏版:3万字详解mRNA疫苗
  3. shell脚本的规范
  4. JQuery Tab菜单的实现
  5. 最新 Linux安装项目环境 mysql 完整教程 100%可行.附带所有教程
  6. 数据同步云端本地_如何从云端删除Windows 8的同步数据
  7. 常用软件包和环境配置(机器学习)
  8. 如何用纯 CSS 创作一只卡通鹦鹉
  9. Android的JNI【实战教程】3⃣️--Java调用C代码
  10. 怎么才能免费下载CSDN资源啊
  11. web of science,SSCI索引,带你入门!
  12. 搭建ASP环境-win7安装IIS并运行ASP程序
  13. 软硬件交互 - 扫码枪
  14. php开发中控考勤机,中控考勤机
  15. echart柱状图堆列实现百分比显示
  16. ASO时,选词应该如何做?aso关键词如何选词
  17. 语音识别—声学模型训练(Viterbi-EM)
  18. 蓝牙电话/耳机和蓝牙音乐profile
  19. Armv8架构虚拟化
  20. 管理 POP3 和 IMAP4 服务

热门文章

  1. Receptive field 感受野 原理+计算+图解+空洞卷积hole
  2. 关于买鸡的问题,5文钱可以买一只公鸡,3文钱可以买一只母鸡,1文钱可以买3只雏鸡.现在用100文钱买100只鸡,那么各有公鸡、母鸡、雏鸡多少只?
  3. IntelliJ IDEA 15 MAC破解版
  4. java依赖倒转原则_设计原则之--依赖倒转原则
  5. 如何制作动态图片gif
  6. 顺丰android架构师,顺丰数据库运维架构.pdf
  7. 若有恒,何必三更眠五更起;最无益,莫过一日曝十日寒
  8. Windows bat脚本获取administrator权限
  9. 从D语言看C++ Template语法
  10. 虚拟机监视器(VMM)