Chinaunix首页 | 论坛 | 博客
  • 博客访问: 313687
  • 博文数量: 66
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 509
  • 用 户 组: 普通用户
  • 注册时间: 2015-04-29 13:56
文章分类
文章存档

2018年(2)

2017年(6)

2016年(34)

2015年(24)

我的朋友

分类: 嵌入式

2015-09-22 11:02:58

嵌入式开发中,串口调试,串口输入输出必不可少,但是有时候会碰到这样的情况,从标准输入读数据时候,输入内容错了,
想输入退格键(或者DEL键) 删掉之前错误的内容,但是会出现^H或者^?提示,而实际删除动作是有效的,出现这种问题是什么原因呢?

网上搜索了下,查到了一些 workaround的解决方案:
1. 比如,用backspace提示^H, 但是用ctrl+backspace就可以完成退格键删除功能
2. 比如,有的用SecureCRT, 设置下session options--> Mapped keys, backspace sends delete,,既可以使用 backspace退格键

但是这些方法,归根结底都是在 用工具来使用Terminal的Delete属性,真正在后面删除起作用的是,termio设置的属性。

termios 结构是在POSIX规范中定义的标准接口,它类似于系统V中的termio接口,通过设置termios类型的数据结构中的值和使用一小

组函数调用,你就可以对终端接口进行控制。

可以被调整来影响终端的值按照不同的模式被分为如下几组:

1.输入模式

2.输出模式

3.控制模式

4.本地模式

5.特殊控制模式

最小的termios结构的典型定义如下:

struct termios

{

           tcflag_t c_iflag;

           tcflag_t c_oflag;

           tcflag_t c_cflag;

           tcflag_t c_lflag;

           cc_t           c_cc[NCCS];

};

结构成员的名称与上面列出的5种参数类型相对应。


关于这个几个flag的设置,这里就不详细讨论,只说明下,如果通过配置c_lflag来实现backspace功能,配置后,就不需要上面提到的方法来做删除
1. 由于backspace ascii是0x8, 也对应这一个输入字符,如果需要让terminal 知道这个字符是用来删除前面一个字符,而不是输入字符,则需要配置
  c_lfag的 如下bit, ICANON:规范输入  ECHOE:字符ERASE擦除前一个字符 WERASE擦除前一个词,   c_lflag |= ICANON;   c_lflag |= ECHOE;
 做了上面配置后,输入backspace, 就不会再显示^H了,因为此时backspace作为删除键,不是输入了。

2.  设置c_cc[VERASE] = 0x8;  因为backspace ascii is 0x8, 这里就设置了 ERASE character 为backspace,
    如果我们想用DEL键作为删除键,可作如下设置即可
    c_cc[VERASE] = 0x7f, 也可设置位crtl+h

3. 做了上面2步设置后,退格键可以删除字符了,也不会显示^H, 但是标准输入会显示 每个删掉的字符
   还需要设置下ECHOPRT, c_lflag &= ~ECHOPRT; 这样设置后,就可以正常了删除字符了

这里还有一个问题,就是termios的变量都有很多位,我们也可以了解下每个bit的作用,由于Linux SHell的输入功能很强大,
可以先把SHell的 c_iflag, c_oflag, c_cflag, c_lfag值打出来,参考设置即可。

比如c_lflag的bit位从第0位到高位如下:
c_lflag:

IEXTN PENDIN TOSTOP NOFLSH FLUSHO ECHOPRT ECHOKE DEFECHO ECHOCTL ECHONL ECHOK ECHOE ECHO XCASE ICANON ISIG(第0位)

下面是一组测试shell的terminal属性的打印值
old_flags.c_iflag=500, old_flags.c_oflag=1805, old_flags.c_cflag=bf, old_flags.c_lflag=8a3b

阅读(1635) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~