https://github.com/latelee/serialport_linux.git
如题,在使用开源库latelee大佬的开源库时,发现串口配置为even校验位时缺少最高位,即1111 1111变为0111 1111.
在read处胡乱加了一通打印,发现是read上来就不对。
后经过定位,发现问题在ISTRIP这个参数,该参数Strip off eighth bit功能为去除字符的第8个比特。这里不太明白为何要使用这个参数来做偶校验。
/* parity bits */
switch (parity)
{
case 'N':
case 'n':
opt.c_iflag &= ~INPCK;
opt.c_cflag &= ~PARENB;
break;
case 'O':
case 'o':
opt.c_iflag |= (INPCK|ISTRIP); /*enable parity check, strip parity bits*/
opt.c_cflag |= (PARODD | PARENB);
break;
case 'E':
case 'e':
opt.c_iflag |= (INPCK|ISTRIP); /*enable parity check, strip parity bits*/
opt.c_cflag |= PARENB;
opt.c_cflag &= ~PARODD;
break;
default:
error_msg("Unsupported parity bits.");
}
关掉关掉~
switch (parity)
{
case 'N':
case 'n':
// opt.c_iflag &= ~INPCK;
opt.c_cflag &= ~PARENB;
break;
case 'O':
case 'o':
// opt.c_iflag |= (INPCK|ISTRIP); /*enable parity check, strip parity bits*/
opt.c_iflag |= (INPCK); /*enable parity check, strip parity bits*/
opt.c_cflag |= (PARODD | PARENB);
break;
case 'E':
case 'e':
// opt.c_iflag |= (INPCK|ISTRIP); /*enable parity check, strip parity bits*/
opt.c_iflag |= (INPCK); /*enable parity check, strip parity bits*/
opt.c_cflag |= PARENB;
opt.c_cflag &= ~PARODD;
break;
default:
error_msg("Unsupported parity bits.");
}
咦,还是缺最高位,而且none校验也出问题了。再次阅读代码发现,这些配置是保存下去的,每次通过tcgetattr(fd, &opt)获取上来的,那就把这个参数还回去。。
case 'E':
case 'e':
opt.c_iflag &= ~ISTRIP;
// opt.c_iflag |= (INPCK|ISTRIP); /*enable parity check, strip parity bits*/
opt.c_iflag |= (INPCK); /*enable parity check, strip parity bits*/
opt.c_cflag |= PARENB;
opt.c_cflag &= ~PARODD;
break;
正常了,解决~
总结,read上来缺最高位,检查下termios结构体里c_iflag成员 的ISTRIP参数。其他奇奇怪怪但有规律的通信问题同理,查阅termios.h 的man手册即可。