2018-08-01 15:39:25 zuoao123 阅读数 2551

背景

在我们的工作中,串口是一种比较常用的数据传输方式。在某些应用场景下,当程序启动并打开串口后,我们不希望读出串口打开之前的输入缓存数据(即内核驱动已接收但是并未被应用层读出的数据),因此需要对输入缓存数据进行清空(刷清、丢弃)操作。下面以Linux系统上串口编程为例进行说明:


测试环境

硬件环境:PC
操作系统:Ubuntu 14.04虚拟机


测试代码

  • 方法一
fd = open("devpath", O_RDWR|O_NOCTTY);
usleep(200000);
tcflush(fd, TCIFLUSH);    //清空输入缓存
tcflush(fd, TCOFLUSH);    //清空输出缓存
tcflush(fd, TCIOFLUSH);   //清空输入输出缓存
tcsetattr(m_ifd, TCSANOW, &strctNewTermios);
  • 方法二
fd = open("devpath", O_RDWR|O_NOCTTY);
usleep(200000);
ioctl(fd, TCFLSH, 0);    //清空输入缓存
ioctl(fd, TCFLSH, 1);    //清空输出缓存
ioctl(fd, TCFLSH, 2);    //清空输入输出缓存
tcsetattr(fd, TCSANOW, &strctNewTermios);

总结

  1. 必须在open和tcflush(或ioctl)操作间进行延时操作(具体时间未做验证),否则没有清空效果,原因未知,可能跟Linux内核版本有关
  2. 可自由选择只清空输入或只清空输出或两者都清空
  3. tcflush和ioctl两种方法均有效,注意ioctl的第二个参数是TCFLSH
2016-03-27 17:43:24 books_world 阅读数 1649


http://blog.chinaunix.net/uid-20564848-id-74763.html


tcflush(int fd, int queue_selector)   //对以写但未发出,或已接收但未读数据的flush.
discards data written to the object referred to by fd but not transmitted, or data received but not read, depending on the value of
       queue_selector:

       TCIFLUSH
              flushes data received but not read.

       TCOFLUSH
              flushes data written but not transmitted.

       TCIOFLUSH
              flushes both data received but not read, and data written but not transmitted.
              
tcgetattr(int fd, struct termios *termios_p)   //get串口termios结构
gets the parameters associated with the object referred by fd and stores them in the termios structure referenced by termios_p. This function may be invoked from a background process; however, the terminal attributes may be subsequently changed by a foreground process.

tcsetattr(int fd, int optional_actions, const struct termios *termios_p)   //设置串口termios结构
sets the parameters associated with the terminal (unless support is required from the underlying hardware that is not available) from the termios structure referred to by termios_p.   optional_actions specifies when the changes take effect:
TCSANOW
   the change occurs immediately.

TCSADRAIN
   the change occurs after all output written to fd has been transmitted. This function should be used when changing parameters that affect output.

TCSAFLUSH
   the change occurs after all output written to the object referred by fd has been transmitted, and all input that has been received but not read will be discarded before the change is made.

2014-04-11 18:41:55 yumishou 阅读数 512

(1)问题1:不知到 请求命令:07 12 41 01 52 f8 03的数据格式

解决:unsigned  char  通常定义#define uchar unsigned char

(2)打印unsigned char类型数据

解决: printf( "%02X", (unsigned char)c );  


(3)

#include "osc/OscOutboundPacketStream.h"
#include "ip/UdpSocket.h"

#include<stdio.h>    
#include<stdlib.h>   
#include<string.h>   
#include<sys/types.h>
#include<sys/stat.h> 
#include<fcntl.h>    
#include<unistd.h>   
#include<termios.h>  
#include<unistd.h>   
#include<errno.h>    
#include <sys/un.h>  
#include <signal.h>  
#include <sys/wait.h>
#include <netdb.h>   


#define uchar unsigned char

#define ADDRESS "10.3.4.115"
#define PORT 7000

#define OUTPUT_BUFFER_SIZE 1024

int set_opt(int fd,int nSpeed, int nBits, char nEvent, int nStop)
{
	struct termios newtio,oldtio;
	if  ( tcgetattr( fd,&oldtio)  !=  0) { 
		perror("SetupSerial 1");
		return -1;
	}
	bzero( &newtio, sizeof( newtio ) );
	newtio.c_cflag  |=  CLOCAL | CREAD;
	newtio.c_cflag &= ~CSIZE;

	switch( nBits )
	{
	case 7:
		newtio.c_cflag |= CS7;
		break;
	case 8:
		newtio.c_cflag |= CS8;
		break;
	}

	switch( nEvent )
	{
	case 'O':
		newtio.c_cflag |= PARENB;
		newtio.c_cflag |= PARODD;
		newtio.c_iflag |= (INPCK | ISTRIP);
		break;
	case 'E': 
		newtio.c_iflag |= (INPCK | ISTRIP);
		newtio.c_cflag |= PARENB;
		newtio.c_cflag &= ~PARODD;
		break;
	case 'N':  
		newtio.c_cflag &= ~PARENB;
		break;
	}

	switch( nSpeed )
	{
	case 2400:
		cfsetispeed(&newtio, B2400);
		cfsetospeed(&newtio, B2400);
		break;
	case 4800:
		cfsetispeed(&newtio, B4800);
		cfsetospeed(&newtio, B4800);
		break;
	case 9600:
		cfsetispeed(&newtio, B9600);
		cfsetospeed(&newtio, B9600);
		break;
	case 115200:
		cfsetispeed(&newtio, B115200);
		cfsetospeed(&newtio, B115200);
		break;
	case 460800:
		cfsetispeed(&newtio, B460800);
		cfsetospeed(&newtio, B460800);
		break;
	default:
		cfsetispeed(&newtio, B9600);
		cfsetospeed(&newtio, B9600);
		break;
	}
	if( nStop == 1 )
		newtio.c_cflag &=  ~CSTOPB;
	else if ( nStop == 2 )
	newtio.c_cflag |=  CSTOPB;
	newtio.c_cc[VTIME]  = 0;
	newtio.c_cc[VMIN] = 0;
	tcflush(fd,TCIFLUSH);
	if((tcsetattr(fd,TCSANOW,&newtio))!=0)
	{
		perror("com set error");
		return -1;
	}
//	printf("set done!\n\r");
	return 0;
}


int main(int argc, char* argv[])
{
    (void) argc; // suppress unused parameter warnings
    (void) argv; // suppress unused parameter warnings
    
    int fd1,fd0,fd2,fd3,fd4,fd5,fd6,fd7,fd8,fd9,fd10,fd11,nread;
    int nset0,nset1,nset2,nset3,nset4,nset5,nset6,nset7,nset8,nset9,nset10,nset11;
		char buf[100];
		char buf1[1];
		uchar buff[512];
		bool backstat=false;
		
		int length_s=0;
		int length_re=0;
		int length_p=0;
		int retv=0;
		int i=0;
		int n=0;
		int m=0;
		int fd[32];
		
		
		uchar sbuf[]={0x06,0x32,0x44,0x00,0x8f,0x03};//停止命令
		uchar rebuf[]={0x07,0x12,0x41,0x01,0x52,0xf8,0x03};//请求命令
		uchar pbuf[]={0x0c,0x22,0x42,0x06,0x93,0x00,0x78,0x01,0xa6,0x00,0xd9,0x03};//防碰撞命令
		
		uchar stopbuf[6]; //停止返回     
		uchar idbuf[6];   //请求返回
		uchar reqbuf[6];  //防碰撞返回    
		uchar bbuf[512];
		 
		
		length_s=sizeof(sbuf);
		length_re=sizeof(rebuf);     
		length_p=sizeof(pbuf); 
		
		
		memset(stopbuf,0,sizeof(stopbuf));  
		memset(idbuf,0,sizeof(idbuf));
		memset(reqbuf,0,sizeof(reqbuf)); 
		memset(bbuf,0,sizeof(bbuf));  
		
		
		
		uchar testbuff[512];
		
		memset(testbuff,0,sizeof(testbuff));  
		memset(buff,0,sizeof(buff));     
  	  
  	/*************udp********************/
  	UdpTransmitSocket transmitSocket( IpEndpointName( ADDRESS, PORT ) );
  	  
  	//char buffer[OUTPUT_BUFFER_SIZE]; 
  	//char buffer1[OUTPUT_BUFFER_SIZE];     
  	//char buffer2[OUTPUT_BUFFER_SIZE];  
  		
 	
  	//osc::OutboundPacketStream p0( buffer, OUTPUT_BUFFER_SIZE );   
  	//osc::OutboundPacketStream p1( buffer1, OUTPUT_BUFFER_SIZE ); 
  	//osc::OutboundPacketStream p2( buffer2, OUTPUT_BUFFER_SIZE );
  		

  		
  	
  	/*  select函数      */                                       
  	int rtv;//存放返回值                                         
    fd_set rd;//读状态数据集(这个名字不好取,只可意会吧)       	
    struct timeval timeout;//超时设置参数结构体 
    /***********usb0******************/                      	
    /*********Open USB Device*******************/                                                             	
    fd0 = open( "/dev/ttyUSB0", O_RDWR);//打开USB转串口0       	
    if (fd0 == -1)                                               	
    	{                                                          	
    		exit(1);                                                 	
    		}    
    else
    	{
    		fd[0]=fd0;
    		}                                                    	
    //else                                                         	
    //	{                                                          	
    //		retv=write(fd0,sbuf,length_s); /* 接收数据 */            	
    //		}                                                        	
    //		                                                         	
    //		for (i=0;i<retv;i++)                                     	
    //		{                                                        	
    //			printf("%02X\n",(uchar)sbuf[i]);                       	
		//  }                                                      	                                                	
      printf("open  USB0 success!!\n"); 
                                                                     	 
	 fd1 = open( "/dev/ttyUSB1", O_RDWR);//打开USB转串口1         	 
	 if (fd1 == -1)                                               	 
	 	{                                                          	 
	 		exit(1);                                                 	 
	 		}     
	 	else
	 		{
	 			fd[1]=fd1;
	 			}  
	 		
	  printf("open  USB1 success!!\n");      
	                                                                	 
	 fd2 = open( "/dev/ttyUSB2", O_RDWR);//打开USB转串口2        	 
	 if (fd2 == -1)                                               	 
	 	{                                                          	 
	 		exit(1);                                                 	 
	 		}       
	 	else
	 		{
	 			fd[2]=fd2;
	 			}
	  printf("open  USB2 success!!\n");         
	  
	 fd3 = open( "/dev/ttyUSB3", O_RDWR);//打开USB转串口3    
	 if (fd3 == -1)                                           
		{                                                       
			exit(1);                                              
			}   
		else
			{
				fd[3]=fd3;
				}                                                  
	 printf("open  USB3 success!!\n");   
	 
	 
	 fd4 = open( "/dev/ttyUSB4", O_RDWR);//打开USB转串口4    
	 if (fd4 == -1)                                           
	 	{                                                       
	 		exit(1);                                              
	 		}    
	 	else
	 		{
	 			fd[4]=fd4;
	 			}                                                 
	  printf("open  USB4 success!!\n");                       
	                                                          
	 fd5 = open( "/dev/ttyUSB5", O_RDWR);//打开USB转串口5     
	 if (fd5 == -1)                                           
	 {                                                        
	 	exit(1);                                                
			}  
		else
			{
				fd[5]=fd5;
				}                                                       
		printf("open  USB5 success!!\n");                            
		
		
	 fd6 = open( "/dev/ttyUSB6", O_RDWR);//打开USB转串口6        
		if (fd6 == -1)                                               
			{                                                          	
				exit(1);                                                 	
				} 
		else
			{
				fd[6]=fd6; 
			}
			                                                       		                                                          
		 printf("open  USB6 success!!\n");                           
		                                                             
		fd7 = open( "/dev/ttyUSB7", O_RDWR);//打开USB转串口7       	
		if (fd7 == -1)                                               
			{                                                          	
				exit(1);                                                 	
				}  
		else
			{
				fd[7]=fd7;
				}                                                       
		 printf("open  USB7 success!!\n");                           
		                                                             
		fd8 = open( "/dev/ttyUSB8", O_RDWR);//打开USB转串口8        
		if (fd8 == -1)                                               
		{                                                            
			exit(1);                                                    
			}   
	  else
	  	{
	  		fd[8]=fd8;
	  		}                                                        
		printf("open  USB8 success!!\n");                            
		                                                             
		                                                             
		fd9 = open( "/dev/ttyUSB9", O_RDWR);//打开USB转串口4         
		if (fd9 == -1)                                               
			{                                                           
				exit(1);                                                                      
				}
		else
			{
				fd[9]=fd9;
				}	
			                                                           
		 printf("open  USB9 success!!\n");                             
		                                                               
		fd10 = open( "/dev/ttyUSB10", O_RDWR);//打开USB转串口5           
		if (fd10 == -1)                                                                     
   {                                                            
	 	exit(1);                                                     
   	} 
   	else
   		{
   			fd[10]=fd10;
   			}                                                                                                                     	
   printf("open  USB10 success!!\n");      
   
   	fd11 = open( "/dev/ttyUSB11", O_RDWR);//打开USB转串口5                                    
   	if (fd11 == -1)                                                    
    {                                                                  
    	exit(1);                                                         
    	}   
    else
    	{
    		fd[11]=fd11;
    		}                                                             
    printf("open  USB11 success!!\n");   
    
  /****************************************************************/
 
   /**********set usb serial*********************/
   nset0 = set_opt(fd0, 9600, 8, 'N', 1);//设置usb转串口0                      	
   if (nset0 == -1)                                             	
   	exit(1);                                                   	
   printf("SET  USB0 success!!");                       
    
   nset1 = set_opt(fd1, 9600, 8, 'N', 1);//设置usb转串口1
   if (nset1 == -1)                                     
   	exit(1);                                           
   printf("SET  USB1 success!!");      
    
   nset2 = set_opt(fd2, 9600, 8, 'N', 1);//设置usb转串口2 
   if (nset2 == -1)                                       
   	exit(1);                                                               
   printf("SET  USB2 success!!");                           
   
   nset3 = set_opt(fd3, 9600, 8, 'N', 1);//设置usb转串口3  
   if (nset3 == -1)                                        
   	exit(1);                                               
   printf("SET  USB3 success!!");                          
                                                           
   nset4 = set_opt(fd4, 9600, 8, 'N', 1);//设置usb转串口4  
   if (nset4 == -1)                                        
   	exit(1);                                               
   printf("SET  USB4 success!!");                          
                                                           
   nset5 = set_opt(fd5, 9600, 8, 'N', 1);//设置usb转串口5  
   if (nset5 == -1)                                        
   	exit(1);                                                
   printf("SET  USB5 success!!");                         
   
   nset6 = set_opt(fd6, 9600, 8, 'N', 1);//设置usb转串口6  
   if (nset6 == -1)                                        
   	exit(1);                                               
   printf("SET  USB6 success!!");                          
                                                           
   nset7 = set_opt(fd7, 9600, 8, 'N', 1);//设置usb转串口7  
   if (nset7 == -1)                                        
   	exit(1);                                               
   printf("SET  USB7 success!!");                          
                                                         
   nset8 = set_opt(fd8, 9600, 8, 'N', 1);//设置usb转串口8  
   if (nset8 == -1)                                        
   	exit(1);                                               
   printf("SET  USB8 success!!");                          
                                                           
   nset9 = set_opt(fd9, 9600, 8, 'N', 1);//设置usb转串口9  
   if (nset9 == -1)                                        
   	exit(1);                                               
   printf("SET  USB9 success!!");                          
                                                           
   nset10 = set_opt(fd10, 9600, 8, 'N', 1);//设置usb转串口10  
   if (nset10 == -1)                                        
   	exit(1);                                               
   printf("SET  USB10 success!!");                          
                                                           
   nset11 = set_opt(fd11, 9600, 8, 'N', 1);//设置usb转串口11  
   if (nset11 == -1)                                        
   	exit(1);                                               
   printf("SET  USB11 success!!");                          
   
  /****************************************************************/   
  while(1)
  {
  	for (n=0;n<12;n++)
  	{     
  		char buffer[OUTPUT_BUFFER_SIZE];     
  		osc::OutboundPacketStream p0( buffer, OUTPUT_BUFFER_SIZE );       
  		retv=write(fd[n],sbuf,length_s); /* 接收数据 */  
  		while(1)                                                                                                                                         
  		{                                                                                                                                            
  		  printf("I am in the while=%d\n",n);                                                                                                             
 			  FD_ZERO(&rd);                                                                                                                              
 			  FD_SET(fd[n],&rd);                                                                                                                                         
 			  while(FD_ISSET(fd[n],&rd))                                                                                                                    
 			  {                                                                                                                                          
 			    if(select(fd[n]+1,&rd,NULL,NULL,NULL) < 0)                                                                                                  
 			      perror("select error!\n");                                                                                                             
 			    else                                                                                                                                     
 			    {                                                                                                                                        
 			      while((nread = read(fd[n],buff,1))>0)                                                                                                     
 			      {                                                                                                                                      
 			        //printf("nread = %d\n",nread);                                                                                                        
 			        //int j=0;                                                                                                                           
 			        //printf("data =%02X\n",(uchar)buff[0]); //打印出串口返回的字符                                                                      
 			        if ((uchar)buff[0]==0x06 || (uchar)buff[0]==0x08 ||(uchar)buff[0]==0x0A)                                                             
 			        	{                                                                                                                                  
 			        		i=0;                                                                                                                             
 			        		bbuf[i]=buff[0];                                                                                                                 
 			        		i=i+1;                                                                                                                           
 			        		}                                                                                                                                
 			        	else if ((uchar)buff[0]==0x03)                                                                                                     
 			        		{                                                                                                                                
 			        			bbuf[i]=buff[0];                                                                                                               
 			        			i=i+1;                                                                                                                         
 			        			printf("i=%d\n",i);                                                                                                            
 			        			int j=0;                                                                                                                       
 			        			//while(j<i){printf("data =%02X",(uchar)bbuf[j++]);} //打印出接收到的返回值                                                      
 			        			//printf("\n");                                                                                                                  
 			        			//printf("bbuf[5] =%02X\n",(uchar)bbuf[5]);                                                                                    
 			        			switch ((uchar)bbuf[0])                                                                                                        
 			        			{                                                                                                                              
 			        				case 0x06:                                                                                                                   
 			        					{        
 			        						for(m=0;m<6;m++)
 			        						{
 			        							printf("recv=%02X\n",(uchar)bbuf[m]);
 			        							}   
 			        						printf("bbuf[2]=%02X\n",bbuf[2]); 
 			        			                                                                                                                
 			        						if ((uchar)bbuf[2]==0xFE || (uchar)bbuf[2]==0xFF)                                                                        
 			        							{      
 			        								printf("bbuf[2]=%02X\n",bbuf[2]);
 			        								memset(bbuf,0,sizeof(buff));  
 			        								printf("bbuf[3]=%02X\n",bbuf[2]);  
 			        								//memset(buffer,0x00,OUTPUT_BUFFER_SIZE);                                                                                                              
 			        								p0 << osc::BeginBundleImmediate                                                                                      
 			        						 			 << osc::BeginMessage( "/USB1" )                                                                                   
 			        						 			 << (int)bbuf[4] << (int)bbuf[5] << (int)bbuf[6]<< (int)bbuf[7] << osc::EndMessage                                 
 			        						 			 << osc::EndBundle;                                                                                                
 			        									 transmitSocket.Send( p0.Data(), p0.Size() ); 
 			        									 memset(bbuf,0,sizeof(buff));  
 			        									 //memset(buffer,0,OUTPUT_BUFFER_SIZE);   
 			        						    printf("bbuf[4]=%02X\n",bbuf[2]);                                                                   
 			        								backstat=true;                                                                                                       
 			        								break;                                                                                                               
 			        								}  
 			        					  printf("ddddddddddddddddd\n");                                                                                                                  
 			        						retv=write(fd[n],rebuf,length_re); /* 发送请求命令 */                                                                     
 			        						break;                                                                                                                   
 			        						}                                                                                                                        
 			        						                                                                                                                         
 			        				case 0x08:                                                                                                                   
 			        					{                                                                                                                          
 			        						retv=write(fd[n],pbuf,length_p); /* 发送防碰撞命令 */                                                                     
 			        						//for (i=0;i<retv;i++)                                                                                                   
 			        						//{                                                                                                                        
 			        						//	printf("%02X\n",(uchar)pbuf[i]);                                                                                       
 			        						//	}                                                                                                                      
 			        						break;                                                                                                                   
 			        						}                                                                                                                                                                                                          
 			        				case 0x0A:                                                                                                                   
 			        					{                                                                                                                          
 			        						printf("Ready print for ID %02X\n:",(uchar)bbuf[0]);                                                                     
 			        						//memset(buffer,0x00,OUTPUT_BUFFER_SIZE);                                                                                                                        
 			        						p0 << osc::BeginBundleImmediate                                                                                                   
 			        							 << osc::BeginMessage( "/USB0" )                                                                                                                                                                            
 			        							 << (int)bbuf[4] << (int)bbuf[5] << (int)bbuf[6]<< (int)bbuf[7] << osc::EndMessage                                     
 			        							 << osc::EndBundle;                                                                                                                                             
 			        						transmitSocket.Send( p0.Data(), p0.Size() ); 

 			        						printf("ID %02X\n:",(uchar)bbuf[0]);   
 			        						memset(bbuf,0,sizeof(buff));    
 			        						
 			        						//memset(buffer,0,OUTPUT_BUFFER_SIZE);                                                                            
 			        						backstat=true;                                                                                                           
 			        						break;                                                                                                                   
 			        						}                                                                                                                        
			        				default:                                                                                                                     
			        					{  
			        						printf("getin default");      
			        						//memset(buffer,0x00,OUTPUT_BUFFER_SIZE);                                                                                                                   
			        						p0 << osc::BeginBundleImmediate                                                                                          
															 << osc::BeginMessage( "/USBd" )                                                                                     
															 << (int)bbuf[4] << (int)bbuf[5] << (int)bbuf[6]<< (int)bbuf[7] << osc::EndMessage                                   
															 << osc::EndBundle;                                                                                                  
													transmitSocket.Send( p0.Data(), p0.Size() );  
													printf("ID %02X\n:",(uchar)bbuf[0]);  
													memset(bbuf,0,sizeof(buff));  
													  
													//memset(buffer,0,OUTPUT_BUFFER_SIZE);                                                                                                                       
 													break;                                               						                                                         
 			        						}                                                                                                                        
 			        					}                                                                                                                              
 			       			      i=0;                                                                                                                       
 			        			    memset(bbuf,0,sizeof(buff));  			        					                                                                     
 			        			    printf("backstat1111=%d\n:",backstat);       			        					                                                           
 			        					break;                                                                                                                     
 			        		}                                                                                                                                
 			        	  else                                                                                                                             
 			        	  	{                                                                                                                              
 			        	  		bbuf[i]=buff[0];                                                                                                             
 			        	  		i=i+1;                                                                                                                       
 			        	  		}	        					                                                                                                         
 			      }                                                                                                                                      
 			      printf("backstat2222=%d\n:",backstat);                                                                                                     
 			      if (backstat)                                                                                                                          
 			      	{                                                                                                                                    
 			      		break; 			      		                                                                                                             
 			      		}                                                                                                                                  
 			    }                                                                                                                                        
 			    printf("backstat3333=%d\n:",backstat);                                                                                                       
 			    if (backstat)                                                                                                                                                                                                        
 			    	{                                                                                                                                      
 			    		//backstat=false;                                                                                                                    
 			    		break;                                                                                                                               
 			    		}                                                                                                                                    
 			  }                                                                                                                                          
 				  if (backstat)                                                                                                                            
 				  	{                                                                                                                                      
 				  		backstat=false;                                                                                                                      
 				  		break;                                                                                                                               
 				  		}			                                                                                                                               
 				}
 				printf("n=%d\n",n);
 			}                                                
  	}                                                               	   
printf("breakout");                                                                                                                                                                                                                     
close(fd0); 
close(fd1);   
close(fd2);   
close(fd3);
close(fd4);
close(fd5);
close(fd6);
close(fd7);
close(fd8);
close(fd9);
close(fd10);
close(fd11);                                                                                                    
return 0;                                                                                                           
}



fflush(stdout)当然是清空stdout的缓冲区了
你可以试试下面的代码
int i;
for (i=0;i<10;i++)
{
  printf("%d",i);
  // fflush(stdout);
sleep(1);
}

再去掉注释试试就知道了

 

(4)编程之美

  ////////////
      \\  - -  //
     (  @ @  )
--oOOo--(_)--oOOo-------
   http://mes-adresses.eu
--------Ooooo-----------
              (   )
     ooooO    )
     (   )    (_/
      \ (
       \_)


(5)读/写串口是程序不能向下运行串口没有连接设备

(6)osc 所属的p中的缓存无法更新,把p放在while循环里面进行定义

 

2019-04-13 14:20:29 as3522 阅读数 5

Linux串口编程——清空输入输出缓存

背景

在我们的工作中,串口是一种比较常用的数据传输方式。在某些应用场景下,当程序启动并打开串口后,我们不希望读出串口打开之前的输入缓存数据(即内核驱动已接收但是并未被应用层读出的数据),因此需要对输入缓存数据进行清空(刷清、丢弃)操作。下面以Linux系统上串口编程为例进行说明:

测试环境
硬件环境:PC
操作系统:Ubuntu 14.04虚拟机

测试代码

#include <termios.h>
#include <unistd.h>

方法一

fd = open("devpath", O_RDWR|O_NOCTTY);
usleep(200000);
tcflush(fd, TCIFLUSH);    //清空输入缓存
tcflush(fd, TCOFLUSH);    //清空输出缓存
tcflush(fd, TCIOFLUSH);   //清空输入输出缓存
tcsetattr(m_ifd, TCSANOW, &strctNewTermios);

方法二

fd = open("devpath", O_RDWR|O_NOCTTY);
usleep(200000);
ioctl(fd, TCFLSH, 0);    //清空输入缓存
ioctl(fd, TCFLSH, 1);    //清空输出缓存
ioctl(fd, TCFLSH, 2);    //清空输入输出缓存
tcsetattr(fd, TCSANOW, &strctNewTermios);

总结

必须在open和tcflush(或ioctl)操作间进行延时操作(具体时间未做验证),否则没有清空效果,原因未知,可能跟Linux内核版本有关
可自由选择只清空输入或只清空输出或两者都清空
tcflush和ioctl两种方法均有效,注意ioctl的第二个参数是TCFLSH


原文

2015-04-10 11:08:40 luoyouren 阅读数 15308


http://blog.chinaunix.net/uid-20564848-id-74763.html


tcflush(int fd, int queue_selector)   //对以写但未发出,或已接收但未读数据的flush.
discards data written to the object referred to by fd but not transmitted, or data received but not read, depending on the value of
       queue_selector:

       TCIFLUSH
              flushes data received but not read.

       TCOFLUSH
              flushes data written but not transmitted.

       TCIOFLUSH
              flushes both data received but not read, and data written but not transmitted.
              
tcgetattr(int fd, struct termios *termios_p)   //get串口termios结构
gets the parameters associated with the object referred by fd and stores them in the termios structure referenced by termios_p. This function may be invoked from a background process; however, the terminal attributes may be subsequently changed by a foreground process.

tcsetattr(int fd, int optional_actions, const struct termios *termios_p)   //设置串口termios结构
sets the parameters associated with the terminal (unless support is required from the underlying hardware that is not available) from the termios structure referred to by termios_p.   optional_actions specifies when the changes take effect:
TCSANOW
   the change occurs immediately.

TCSADRAIN
   the change occurs after all output written to fd has been transmitted. This function should be used when changing parameters that affect output.

TCSAFLUSH
   the change occurs after all output written to the object referred by fd has been transmitted, and all input that has been received but not read will be discarded before the change is made.

BSS段清零的原因

阅读数 568

没有更多推荐了,返回首页