终端的规范模式和非规范模式

我觉得最容易出错的,是设置 c_lflag 中的 ICANON 标志
网上经常有人会问为什么设置好的串口接收数据不正常,经常就是这里没有设好。

如果标记 ICANON 则激活终端模式(cononical mode, 也叫授权模式),这种模式下,需要设置 c_cc 数组来进行一些终端配置。

通常的串口传输数据,不需要终端模式,因此置 c_lflag &=~ICANON ,使其进入非终端模式 (non-canonical mode)
这时候控制串口数据接收的方式,就要靠 c_cc 数组的 [VMIN] 和 [VTIME] 了


我们使用的终端就是这种规范模式(canonical mode)的,需要用户输入了回车,才会去执行这一行命令。
如果自己要做一个类似的东西,就需要用上ICANON, 这时候如果输入 Ctrl-C 这类的特殊键,系统会根据对c_cc的控制,决定是否将其当作普通字符发出还是进行某些特殊操作。

规范模式

   当 c_lflag 中的 ICANON 标志置位时,则按照规范模式对终端输入数据进行处理。此时输入字符被装配成行,进程以字符行的形式读取。当一行字符输入后,终端驱动会立刻返回。行的定界符有 NL、EOL、EOL2 和 EOF。其中除最后一个EOF将(文件结束)将被处理程序删除外,其余四个字符将被作为一行的最后一个字符返回给调用程序。
   在规范模式下,终端输入的以下字符将被处理: ERASE、KILL、EOF、REPRINT、WERASE和EOL2.
   ERASE 是擦除字符。在规范模式下,当 copy_to_cooked()函数遇到该输入字符时会删除缓冲队列中最后一个字符。若队列中最后一个字符是上一行的字符(NL),则不作任务处理。此后该字符被忽略,不放到缓冲队列中。
   KILL 是删除字符。它删除队列中最后一行字符。此后该字符被忽略掉。
   EOF 是文件结束符。在 copy_to_cooked()函数中该字符以及行结束字符EOL和EOL2都将被当作回车符来处理。在读操作函数遇到该字符将立即返回。EOF字符不会放入队列中而是被忽略。
REPRINT和WERASE是扩展规范模式下识别的字符。REPRINT会让所有未读的输入被输出。而WERASE用于擦除单词(跳过空白字符)。在linux0.11中,程序忽略了对这两个字符的识别处理。

非规范模式
   如果ICANON处于复位状态,则终端程序工作在非规范模式下。此时终端程序不对上述字符进行处理,而是将它们当作普通字符处理。输入数据也没有行的概念。
   终端程序何时返回读进程是由MIN和TIME的值确定。这两个变量是c_cc[]数组中的变量。通过修改它们即可改变在非规范模式下进行读字符的处理方式。
   MIN指明读操作最少需要读取的字符数;TIME指定等待读取字符的超时值(计算单位是 1/10秒)。
根据它们的值可分四种情况来说明。
1. MIN>0, TIME>0
   此时TIME是字符超时定时值,在接收到第一个字符后才起作用。在超时之前,若先接收到了MIN个字符,则读操作立该返回。若在收到MIN个字符之前超时了,则读操作返回已经接收的字符数。
此时起码能返回一个字符。因此在接收到一个字符之前secondary空,则读进程序将被阴塞。
2. MIN>0, TIME=0

此时只有在收到到MIN个字符时读操作才返回。否则就无限期等特。
3. MIN=0, TIME>0
   此时TIME是一个读操作超时定时值。当收到一个字符或者已超时,则读操作就立该返回,如果是超时返回,则读操作返回0个字符。
4. MIN=0, TIME=0
   在这种设置下,如果队列中有数据可以读取,则读操作读取需要的字符数。否则立该返回0个字符数

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值