Linux 串口 一次性read接收不定长的数据(非阻塞,非延时) 程序分析

二话不说,直接上代码。

/*********************Copyright(c)************************************************************************
**          Guangzhou ZHIYUAN electronics Co.,LTD
**
**              http://www.embedtools.com
**
**-------File Info---------------------------------------------------------------------------------------
** File Name:               serial-test.c
** Latest modified Data:    2008-05-19
** Latest Version:          v1.1
** Description:             NONE
**
**--------------------------------------------------------------------------------------------------------
** Create By:               zhuguojun
** Create date:             2008-05-19
** Version:                 v1.1
** Descriptions:            epc-8000's long time test for serial 1,2,3,4
**
**--------------------------------------------------------------------------------------------------------
*********************************************************************************************************/
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#define DATA_LEN                0xFF                                    /* test data's len              */


//#define DEBUG                 1


/*********************************************************************************************************
** Function name:           openSerial
** Descriptions:            open serial port at raw mod
** input paramters:         iNum        serial port which can be value at: 1, 2, 3, 4
** output paramters:        NONE
** Return value:            file descriptor
** Create by:               zhuguojun
** Create Data:             2008-05-19
**--------------------------------------------------------------------------------------------------------
** Modified by:
** Modified date:
**--------------------------------------------------------------------------------------------------------
*********************************************************************************************************/
static int openSerial(char *cSerialName)
{
    int iFd;

    struct termios opt;

    iFd = open(cSerialName, O_RDWR|O_NOCTTY|O_NONBLOCK|O_NDELAY);
    if(iFd < 0) {
        perror(cSerialName);
        return -1;
    }

    tcgetattr(iFd, &opt);

    //cfsetispeed(&opt, B57600);
    //cfsetospeed(&opt, B57600);

     cfsetispeed(&opt, B115200);
     cfsetospeed(&opt, B115200);


    /*
     * raw mode
     */
    opt.c_lflag   &=   ~(ECHO   |   ICANON   |   IEXTEN   |   ISIG);
    opt.c_iflag   &=   ~(BRKINT   |   ICRNL   |   INPCK   |   ISTRIP   |   IXON);
    opt.c_oflag   &=   ~(OPOST);
    opt.c_cflag   &=   ~(CSIZE   |   PARENB);
    opt.c_cflag   |=   CS8;

    /*
     * 'DATA_LEN' bytes can be read by serial
     */
    opt.c_cc[VMIN]   =   DATA_LEN;
    opt.c_cc[VTIME]  =   150;

    if (tcsetattr(iFd,   TCSANOW,   &opt)<0) {
        return   -1;
    }


    return iFd;
}


//粘连的字符串最后保存在*p指向的地址所在的内存中
static int mystrcat(char *p,char *q)
{
    int ret = -1;
    char *pp = p;
    ret = (p != NULL) && (q != NULL);

    if(ret)
    {

        while(*pp != '\0')
        {
            pp++;
        }
        while(*q != '\0')
        {
            *(pp++) = *(q++);
        }
        *(pp) = '\0';
    }

    return ret;
}

//char read_buf[256] = {'\0'};
char read_nBytes[1024];


void Serial_Thread(void *threadarg)//serial_client 线程
{
	char read_buf[1024];

	char tmp[1024];
    static int len = 0;
    int readnum = 0;
	int fd, i;

	fd = openSerial("/dev/ttymxc1");
	tmp[0] = 'A';
	tmp[1] = 'T';
	tmp[2] = 'I';
	tmp[3] = '\n';
	write(fd,tmp,4);
	while (1) {
		   if((readnum = read(fd,read_nBytes,8))>0)
		   {
		       len += readnum;
		       if(readnum == 8)
		       {
		           read_nBytes[readnum] = '\0';
		           mystrcat(read_buf,read_nBytes);
		       }

		       if(readnum > 0 && readnum < 8)
		       {
		           read_nBytes[readnum] = '\0';
		           mystrcat(read_buf,read_nBytes);

		           printf("read_len:%d\n", len);
		           printf("read_buf:%s\n", read_buf);
		           len = 0;
		           bzero(read_buf,sizeof(read_buf));
		       }
		   }
	}
}

int main(void)
{

	int rc,fd;

	pthread_t Serial_thread;
	printf("using /dev/ttymxc1 for self-test\n\n");

	// 创建sockcet线程   一直检测数据的到来或者写入
	rc = pthread_create(&Serial_thread, NULL,(void *)Serial_Thread,NULL);
		if (rc)
			printf("ERROR; return code from pthread_create() is %d\n", rc);

	  while(1);

}


接收超过八的数据


Linux 串口 一次性read接收不定长的数据(非阻塞,非延时) 程序分析_第1张图片


接收小于8的数据

Linux 串口 一次性read接收不定长的数据(非阻塞,非延时) 程序分析_第2张图片


但是程序依然存在bug,就是当数据为8个字节的时候,就会出现数据一直叠加上去,解决办法就是read 的size设大一点



欢迎关注并加入物联网行业联盟,积累行业人脉和资源。


你可能感兴趣的:(Linux 串口 一次性read接收不定长的数据(非阻塞,非延时) 程序分析)