侧边栏切换

Linux串口接收丢失0x11,0x13和0x0D字符的问题

最后编辑于: 2022-12-07 22:42  |  分类: linux  |  标签: 串口   |  浏览数: 969  |  评论数: 0


0. 遇到问题

做嵌入式开发少不了要用到串口, Linux下的嵌入式应用层开发也一样, 也要经常用到串口设备.

这不, 前一段我就在linux下折腾程序, 调试发现串口接收原始二进制数据总是莫名的数据丢失或数据错误, (第1版用的都是ASCII码传输, 倒没有发现这样的现象). 经过仔细分析, 感觉这现象发生 好像只和被丢失的数据字节本身有关, 和其周围的数据模式无关. 于是一狠心把0x00~0xFF所有数据都试了一遍(改个测试程序也不是很花时间), 一定要把它搞透透. 结果发现也只有3个数会有问题:

再定睛一看, 感觉这3个数 不像是随随便便 冒出来的.

0x0D大家都知道就是大名鼎鼎的回车 \r, 它被篡改成的0x0A就是经常和它一起的兄弟换行 \n.

0x110x13虽然不知道是个什么玩意, 但在ASCII表里也是靠前的, 控制字符之类的东西. 后来查到一个是 ^Q VSTART字符 一个是 ^S VSTOP字符, 好像是什么 起动/停止输出控制 用的, 估计是上古时代拨号上网modem控制之类的产物.

它们仨都是有名堂的, 说不定某个技术细节调整一下就能解决, 果不其然, 用它们仨作关键字去搜索, 一下就搜到了答案.

1. 找到答案

只要在串口设备初始化时, c_iflag属性的设置修改一下即可.

c_iflag是关于接收的属性设置, 至于属性值设置成什么号, 我找到了一个权威答案,

APUE这本书里的18章11节中, 第666页有个名为 tty_raw() 的示例函数,

其作用是将串口从终端模式改为原始模式(linux下串口设备默认是终端模式).

此函数中对c_iflag属性的设置, 我们照抄它就行:

buf.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);

至于这样设置的意义, 见下图, 我就不赘述了.

2. 回到最初的问题

再回到我们的最初, 这些选项里, 那些是解决我们的问题的呢?

应该是下面2个:

(另外, 看到也有人说可以干脆把c_iflag和c_oflag属性都设置成0的, 我没有试过, 不知是否可行.)


上一篇: linux生成和使用动态链接库和静态链接库的makefile编写

下一篇: linux与bsd之间的10个不同之处