Chinaunix首页 | 论坛 | 博客
  • 博客访问: 222453
  • 博文数量: 22
  • 博客积分: 847
  • 博客等级: 准尉
  • 技术积分: 325
  • 用 户 组: 普通用户
  • 注册时间: 2010-11-02 11:08
文章存档

2012年(9)

2011年(8)

2010年(5)

我的朋友

分类: LINUX

2011-08-22 16:47:11

项目描述: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,直到所有的无符号数据都读完为止。

 

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