精华内容
下载资源
问答
  • //Linux3.2.0之后版本select的超时参数会被更新,其余平台请注意该用法是否适用 while (1) { ret = select(fd+1, &rset, NULL, NULL, timeout); if (ret ) { if (errno == EINTR) continue; else return(-1); } if ...
    /*--01--*//*--02--*//*--03--*//*--04--*//*--05--*//*--06--*//*--07--*//*--08--*/
    /*******************************************************************************
     *@文件名:
     *@描  述:
     *@版  本:
     *@平  台:
     *@作  者:
     *@记  录:
    *******************************************************************************/
    
    /* Includes ------------------------------------------------------------------*/
    #include <serial_port.h>
    #include <stdint.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <errno.h>
    
    /* Private macro -------------------------------------------------------------*/
    
    /* Public fuctions -----------------------------------------------------------*/
    
    /* Private functions ---------------------------------------------------------*/
    static int interface_open(const char *port, speed_t baudrate);
    static int interface_read(int fd, void *vptr, size_t n, struct timeval *timeout);
    
    /* Private typedef -----------------------------------------------------------*/
    
    /* External variables --------------------------------------------------------*/
    
    /* Public variables ----------------------------------------------------------*/
    struct SerialPort_Interface SerialPort = {
        .open = interface_open,
        .read = interface_read,
    };
    
    /* Private variables ---------------------------------------------------------*/
    
    /* Private function prototypes -----------------------------------------------*/
    /*******************************************************************************
    *@功    能:
    *@备    注:
    *******************************************************************************/
    static int interface_open(const char *port, speed_t baudrate)
    {
        int fd;
        struct termios options;
    
        fd = open(port, O_RDWR|O_NOCTTY|O_NDELAY);
    
        if (fd == -1) {
            printf("can't open %s", port);
            return -1;
        }
    
        tcgetattr(fd, &options);
    
        cfsetispeed(&options, baudrate);
        cfsetospeed(&options, baudrate);
        options.c_cflag |= CLOCAL | CREAD;
        options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
        options.c_oflag &= ~OPOST;
        options.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP);
        options.c_iflag &= ~(IXON | IXOFF | IXANY);
    
        if (tcsetattr(fd, TCSANOW, &options) != 0) {
            printf("%s tcsetattr failed\n", port);
            close(fd);
            return -1;
        }
    
        return fd;
    }
    
    /*******************************************************************************
    *@功    能:
    *@备    注:
    *******************************************************************************/
    static int interface_read(int fd, void *vptr, size_t n, struct timeval *timeout)
    {
        int     ret;
        fd_set  rset;
    	char	*ptr;
    	size_t	nleft;
    	ssize_t	nread;
    
        FD_ZERO(&rset);
        FD_SET(fd, &rset);
    
    	ptr = (char *)vptr;
    	nleft = n;
        //Linux3.2.0之后版本select的超时参数会被更新,其余平台请注意该用法是否适用
        while (1) {
            ret = select(fd+1, &rset, NULL, NULL, timeout);
    
            if (ret <= 0) {
                if (errno == EINTR)
                    continue;
                else
                    return(-1);
            }
    
            if (FD_ISSET(fd, &rset)) {
                if ((nread = read(fd, ptr, nleft)) < 0)
                    continue;
                nleft -= nread;
                ptr   += nread;
                if (nleft > 0)
                    continue;
                else
                    return(0);
            }
    
            continue;
        }
    }
    
    /*******************************************************************************
    * End Of File         
    *******************************************************************************/
    
    /*--01--*//*--02--*//*--03--*//*--04--*//*--05--*//*--06--*//*--07--*//*--08--*/
    /*******************************************************************************
     *@文件名:
     *@描  述:
     *@版  本:
     *@平  台:
     *@作  者:
     *@记  录:
    *******************************************************************************/
    
    /* Define to prevent recursive inclusion -------------------------------------*/
    #ifndef __SERIAL_PORT_H
    #define __SERIAL_PORT_H
    
    /* Includes ------------------------------------------------------------------*/
    #include <termio.h>
    #include <stdlib.h>
    
    /* Macro ---------------------------------------------------------------------*/
    
    /* Exported types ------------------------------------------------------------*/
    struct SerialPort_Interface {
        int (*open)(const char *port, speed_t baudrate);
        int (*read)(int fd, void *vptr, size_t n, struct timeval *timeout);
    };
    
    /* Public variables ----------------------------------------------------------*/
    extern struct SerialPort_Interface SerialPort;
    
    /* Exported functions --------------------------------------------------------*/
    /* IO operation functions *****************************************************/
    
    
    #endif
    
    /*******************************************************************************
    * End Of File         
    *******************************************************************************/
    

     

    展开全文
  • Linux串口中的超时设置

    千次阅读 2017-11-03 14:31:04
    Linux串口中的超时设置

    在Linux下使用串口通信时,默认的阻塞模式是不实用的。而采用select或epoll机制的非阻塞模式,写代码有比较麻烦。幸好Linux的串口自己就带有超时机制。

    Linux下使用termios.h中的的接口进行串口设置。

    使用termios.h的接口进行超时设置,主要是配置 VTIME 和 VMIN 两个字段。其中VTIME指定了等待的时间(timeout=VTIME*100ms),VMIN指定了读取字符的最小数量。

    注意要使这两个字段生效,必须使串口工作于非标准模式。

    可以通过如下方式设置为RAW模式(非标准模式的一种,多用于通信):/* struct termio newtio; */

    newtio.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); /*Input*/

    newtio.c_oflag &= ~OPOST; /*Output*/

    VTIME和VMIN需配合使用,它们的组合关系如下:

    1、VTIME=0,VMIN=0:此时即使读取不到任何数据,函数read也会返回,返回值是0。

    2、VTIME=0,VMIN>0:read调用一直阻塞,直到读到VMIN个字符后立即返回。

    3、VTIME>0,VMIN=0:read调用读到数据则立即返回,否则将为每个字符最多等待 VTIME*100ms 时间。

    4、VTIME>0,VMIN>0:read调用将保持阻塞直到读取到第一个字符,读到了第一个字符之后开始计时,此后若时间到了 VTIME*100ms 或者时间未到但已读够了VMIN个字符则会返回。

    若在时间未到之前又读到了一个字符(但此时读到的总数仍不够VMIN)则计时重新开始(即每个字符都有VTIME*100ms的超时时间)。

    展开全文
  • linux串口超时时间设置

    千次阅读 2017-02-08 17:30:56
    ... 那么可能需要关注的是VMIN和VTIME这两个选项。 VMIN 最少读取字符数 VTIME 超时时间 (100ms最小单位) 这两个参数只有当设置为阻塞模式时才有效,有以下几种可能值: 1 VMIN> 0 && VTIME>

    comport[port].opt.c_cc[VTIME] = 0;
    comport[port].opt.c_cc[VMIN] = 0;
    那么可能需要关注的是VMIN和VTIME这两个选项。
    VMIN 最少读取字符数
    VTIME 超时时间 (100ms最小单位)
    这两个参数只有当设置为阻塞模式时才有效,有以下几种可能值:
    1 VMIN> 0 && VTIME> 0
    VMIN为最少读取的字符数,当读取到一个字符后,会启动一个定时器,在定时器超时事前,如果已经读取到了VMIN个字符,则read返回VMIN个字符。如果在接收到VMIN个字符之前,定时器已经超时,则read返回已读取到的字符,注意这个定时器会在每次读取到一个字符后重新启用,即重新开始计时,而且是读取到第一个字节后才启用,也就是说超时的情况下,至少读取到一个字节数据。
    2 VMIN > 0 && VTIME== 0
    在只有读取到VMIN个字符时,read才返回,可能造成read被永久阻塞。
    3 VMIN == 0 && VTIME> 0
    和第一种情况稍有不同,在接收到一个字节时或者定时器超时时,read返回。如果是超时这种情况,read返回值是0。
    4 VMIN == 0 && VTIME== 0
    这种情况下read总是立即就返回,即不会被阻塞。

    展开全文
  • 在实际对串口设备操作时,一般都需要超时read,关于read的第三个参数意义总是忘记。 1:open /dev/ttySP0 获取fd 2:write(fd,***,)向fd写数据 3:fd返回响应数据,并使用select+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;
    }

    /

     

     

    展开全文
  • 串口编程经典应用场景:打开串口,阻塞模式,非超时返回,有数据返回,无数据死等。 简易代码为例: void* read_thread(void* param) { char szbuf[128]; int size = 0; while (running) { size = read(fd, ...
  • Linux串口编程老生常谈了,已经做过很多次,但有些细节没次都要翻遍百度才能找到答案,这里做笔记记录下1.首先先包含一些头文件,这里只做应用的方法介绍,具体头文件怎么回事,自个百度#include #include #include ...
  • 串口设置超时

    千次阅读 2015-05-20 23:03:59
    通常I/O操作都是有阻塞与非阻塞的两种方式。...其中"超时"这个概念其实是阻塞中的...在Linux串口的IO操作 本文将它分为三种状态: 阻塞状态 超时状态 非阻塞状态 这三种状态的转换组合有这么几种:
  • Linux串口编程

    2019-01-07 19:30:38
    开发板系统:Linux Ubuntu版本:Ubuntu14.04 ------------------------------------------- 串口2(Ubuntu) 串口1(A33) Ubuntu和A33都运行uart_test程序(见附件)。   一、串口设置 最基本的串口设置...
  • Linux 串口编程

    2017-09-05 17:54:03
    Linux 串口编程  在linux下编写终端程序时,有规范模式 ,非规范模式(原始模式特殊的非规范模式)之分。不用于终端,而是在串口这种使用情况下,一般设置为原始模式(非规范的一种特殊情况)。但用read()函数...
  • Linux 串口

    2019-07-16 16:52:47
    Linux 系统中,串口属于终端 I/O 操作。终端 I/O 有两种不同的工作模式: 规范模式(canonical mode)。在这种模式中,对终端输入以行为单位进行处理。对于每个读请求,终端驱动程序最多返回一行。 非规范...
  • linux串口

    2015-01-26 14:15:32
    这几天,由于长春门检系统项目的需要,涉及到了读卡器信息的串口读取,所以在Linux串口信息的读取有了一点心得体会。 1.  打开串口   与其他的关于设备编程的方法一样,在Linux下,操作、控制串口也是通过...
  • linux串口编程

    2017-01-06 17:35:43
    串口可以说是嵌入式 Linux 系统必备的外设,系统终端通常都是串口。除了终端功能之外,实际应用中,Linux 系统也经常通过串口完成与其它设备的通信和数据传递。 Linux串口表现为设备文件。 Linux串口设备文件...
  • Linux串口应用编程

    2020-08-03 09:35:32
    Linux下,除了网络设备,其余的都是文件的形式,串口设备也一样在/dev下。 打开串口: 示例:fd = open("/dev/ttyUSB0",O_RDWR|O_NOCTTY|O_NDELAY); 在打开串口时,除了需要用到 O_RDWR (可读写)选项标志外, O_...
  • linux串口编程 非规范模式 read()问题  在linux下编写终端程序时,有规范模式 ,非规范模式(原始模式特殊的非规范模式)之分。不用于终端,而是在串 口这种使用情况下,一般设置为原始模式(非规范的一种...
  • CLOCAL和CREAD是c_cflag成员中与速率相关的标志,在串口编程中,这两个标志一定要有效,以确保程序在突发的作业控制或挂起时,不会成为端口的占有都,同时串口的接收驱动会自动读入数据。设置方法如下: termios_...
  • linux串口操作

    2020-03-06 10:45:51
    man termios:http://www.man7.org/linux/man-pages/man4/tty_ioctl.4.html 串行口是计算机一种常用的接口,具有连接线少,通讯简单,得到广泛的使用。常用的串口是RS-232-C接口(又称EIA RS-232-C)它是在1970年由...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 3,149
精华内容 1,259
关键字:

linux串口read超时

linux 订阅