好记性不如烂笔头(linux的串口超时read的参数意义)

在实际对串口设备操作时,一般都需要超时read,关于read的第三个参数意义总是忘记。

 

1:open /dev/ttySP0 获取fd

 

2:write(fd,***,)向fd写数据

 

3:fd返回响应数据,并使用select+read进行超时读取未知、不定长度的数据:

read函数参数有三:int fd,char * p,int nbyte,前两个好理解,

最后一个nbyte指:如果缓存中有大于nbyte个数据那么只返回nbyte个数据,剩余的数据下次再去读时才能读到,

如果缓存中只有少于nbyte个数据,那么这时就要配合打开串口时的一个配置参数“options.c_cc[VTIME] ” 来看了,不足nbyte个时,串口驱动只会等待options.c_cc[VTIME](单位百毫秒)这么长时间,到时间通知read同样返回,并且读取少于nbyte的实际数量的数据,而不会去等到select的超时,才返回,这么看来,串口配置也是自带的似乎是"硬超时"。

 

//read样例

//

int serial_read(int fd,char * p,int desire_get_len,int time_out_ms)
{
    int nfds;
    int nread = 0 ;
    char read_temp[256];
    fd_set readfds;
    struct timeval tv;

    tv.tv_sec = time_out_ms/1000;
    tv.tv_usec = time_out_ms%1000;
    FD_ZERO(&readfds);
    FD_SET(fd,&readfds);
    bzero(read_temp,sizeof(read_temp));
    nfds = select(fd+1,&readfds,NULL,NULL,&tv);

    if(nfds == 0) 
    {
        printf("timeout!\r\n");
        return 0;
    }
    else
    {
        nread = read(fd,read_temp,desire_get_len);//即使不满desire_get_len,也会返回实际读取到的数据量
        if(nread<=0)
        {
            printf("read get problem!\r\n");
        }
    }
    memcpy(p,read_temp,nread);
    return nread;  
}

///

//

//串口配置样例

int usart_ttyS0_init(char * uart_name,char * uart_rate)
{
    int fd1=0;


    struct termios options;    //usart par struct
    fd1 = open(uart_name, O_RDWR|O_NOCTTY);
    //printf("open result is %d\n",fd1);
    //logmsg(INFO_NAME,"open result is %d\r\n",fd1);


    tcgetattr(fd1, &options);        //获取opt指针。

    cfsetispeed(&options, B9600);    //set bps in
    cfsetospeed(&options, B9600);    //set bps out
  
    options.c_cflag |= (CLOCAL | CREAD);    //enable date receiver
    options.c_cflag &= ~PARENB;      //没有校验
    options.c_cflag &= ~CRTSCTS;     //没有数据流
    options.c_cflag &= ~CSTOPB;   //关闭两位停止位,就是一位停止位
    options.c_cflag &= ~CSIZE;    //设置数据位宽时打开掩码
    options.c_cflag |= CS8;       //8位数据位


    //关闭ICRNL IXON 防止0x0d 0x11 0x13的过滤
    options.c_iflag &=~(IXON | IXOFF | IXANY); 
    options.c_iflag &= ~ (INLCR | ICRNL | IGNCR);
    options.c_oflag &= ~(ONLCR | OCRNL);
    options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);    
    //options.c_oflag &= ~OPOST;term.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);


    //options.c_oflag  &= ~OPOST;
    options.c_oflag &= ~OPOST;   //使用原始数据


     //只有阻塞时,下面两个才有效,且针对读。
    options.c_cc[VMIN]  = 50;  //最小字节数(读)   4800  50  5     这个傻意思忘记了
    options.c_cc[VTIME] = 5;     //等待时间,单位百毫秒(读)  115200 50 1


    tcsetattr(fd1, TCSANOW, &options); //写入options


    return fd1;
}

/

 

 

你可能感兴趣的:(好记性不如烂笔头)