嵌入式开发中,串口调试,串口输入输出必不可少,但是有时候会碰到这样的情况,从标准输入读数据时候,输入内容错了,
想输入退格键(或者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) |