项目描述:s3c2440开发板上运行linux,通过uart串口连接cdma模块。2440通过串口发送和接受at命令,来与远程主机进行tcp连接通讯。通讯中有无符号字节的传输
问题:2440通过串口来进行无符号数据(即不是普通的ascii字符)传输的过程中,是不能允许特殊字符产生影响的。但在串口终端读写过程中,如果没有进行相关的配置,则总有一些特殊字符会产生特殊的效果。比如'\0x15'表示的NAK能够删除前一行的内容,又比如'\0x04'表示文件尾,它能够让输入识别当前为一行并read返回,而'0x04'本身则read不到。诸如总总。
解决方法:linux中包含了比较完整的串口终端配置的信息,可以灵活的对串口进行配置。我们熟知的串口有两种模式:1、规范输入模式( ICANON设置时)2、非规范输入模式。
当串口处于规范输入模式,每次的read读都是以一行为单位的。当read到'\n','\r','\4'时都会返回。其中换行和回车符是能够被系统接收到得,但是'\4'则直接丢弃,系统无法read到。
而串口处于非规范输入的情况下,则是以两个值来定义read读的方式的。他们是cc[VMIN],cc[VTIME]。针对VMIN、VTIME不同的值,来组合确定read的功能。
在实际应用中,由于规范模式输入会让程序变得简单明了,易于编写,是经常用到的模式。而且在此项目中,cdma模块中用到得at指令也是符合规范模式的使用特点的。因此在这里串口应该选择此种模式。即设置ICANON。
那么对于那些特殊的字符会产生特殊的处理的问题如何解决呢?即如何才能不能特殊字符产生效果,而只是做为实际的输出呢。
我们可以通过设置termios结构中的c_cc数组中的相关变量为_POSIX_VDISABLE,通过这个选项来屏蔽掉相关字符的特殊处理。具体代码如下所示:
int init_attr(void) { int retval=0; if((retval=tcgetattr(fd_s1,&option))<0) { perror("get attr failed!"); return retval; } // 1 stop bit ; 8 data bit ; NO check
option.c_cflag &= ~PARENB; option.c_iflag &= ~INPCK; option.c_cflag &= ~CSTOPB; option.c_cflag &= ~CSIZE; option.c_cflag |= CS8;
option.c_oflag &= ~(BSDLY|CRDLY|FFDLY|NLDLY|OFDEL|OFILL|OLCUC|ONLRET|ONOCR|OPOST|OCRNL|ONLCR); option.c_lflag &= ~(FLUSHO|ECHOKE|PENDIN|TOSTOP|XCASE|ECHO|ECHOK|ECHONL|ISIG|IEXTEN|ECHOE); option.c_lflag |= ICANON; option.c_iflag &= ~(IXON|IXOFF|IXANY|IGNCR|ICRNL|INLCR|BRKINT|IGNPAR|IMAXBEL|IUCLC|PARMRK|IGNBRK|INPCK|ISTRIP); option.c_cc[VKILL]= _POSIX_VDISABLE; option.c_cc[VERASE] = _POSIX_VDISABLE; option.c_cc[VEOL] = _POSIX_VDISABLE; option.c_cc[VEOL2] = _POSIX_VDISABLE; option.c_cc[VEOF] = _POSIX_VDISABLE; option.c_cc[VWERASE] = _POSIX_VDISABLE; option.c_cc[VREPRINT] = _POSIX_VDISABLE;
cfsetispeed(&option,B115200); cfsetospeed(&option,B115200);
if ((retval=tcsetattr(fd_s1,TCSANOW,&option)) < 0) { perror("set attr failed!"); return retval; } return 0; }
|
通过上述的设置之后,串口终端将不再对'\0X04','\0X15','0X7E'等特殊字符进行处理了,而只会在遇到EOF('\0x04')、回车('\0x0d')、换行('\0x0a')的时候返回了。并且串口将不再吞没'\0x04'等字符。程序可以对欲接收的字节数和实际接收到得字节数进行比较,判断是否还需要接着read,直到所有的无符号数据都读完为止。
阅读(5214) | 评论(0) | 转发(0) |