串口读写,select 检测有数据时就接收,防止阻塞问题

Posted 慢伴拍的二叉树

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了串口读写,select 检测有数据时就接收,防止阻塞问题相关的知识,希望对你有一定的参考价值。

 

 

Makefile:

EXEC = uart_raw
OBJS = uart_raw.o
SRC  = uart_raw.c

#CC = arm-none-linux-gnueabi-gcc

CC = /home/hongzhunzhun/work/OpenWrt-SDK-sunxi-for-linux-x86_64-gcc-4.8-linaro_uClibc-0.9.33.2/staging_dir/toolchain-arm_cortex-a7+neon_gcc-4.8-linaro_uClibc-0.9.33.2_eabi/bin/arm-openwrt-linux-uclibcgnueabi-g++


CFLAGS += -O2 -Wall 
LDFLAGS += 

all:$(EXEC)

$(EXEC):$(OBJS)
	$(CC) $(LDFLAGS) -o $@ $(OBJS)

%.o:%.c
	$(CC) $(CFLAGS) -c $< -o $@

clean:
	@rm -vf $(EXEC) *.o *~

  

uart_raw.c:

  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 #include <unistd.h>
  4 #include <sys/types.h>
  5 #include <sys/stat.h>
  6 #include <fcntl.h>
  7 #include <termios.h>
  8 #include <errno.h>
  9 #include <limits.h>
 10 #include <unistd.h>
 11 #include <string.h>
 12 #include <signal.h>
 13 
 14 #define DEV_NAME "/dev/ttyS2"
 15 
 16 int testi=0;
 17 //不调用
 18 int recv_protocol(int uart_fd,char* buf, int n)
 19 {
 20     int rc, i;
 21     int count = 0;
 22     
 23         while(read(uart_fd, buf, n) >0)
 24         {
 25             printf("recv serial----rc is %d   testi is %d \\n  ",rc,testi);
 26             for(i = 0; i < n; i++)
 27                 printf(" %x ", buf[i]);
 28         }
 29         printf("no while !!!\\n");
 30         for(i = 0; i < n; i++)
 31                 printf(" %x ", buf[i]);
 32     
 33         printf("\\n");
 34     
 35     tcflush(uart_fd, TCIOFLUSH);
 36     return rc;
 37 }
 38 
 39 // 等待时间  串口描述符  读取的buff
 40 int Select_Tart_Read(struct timeval tv,int  uart_fd,char* buff)
 41 {
 42     
 43     memset(buff,0,sizeof(char)*8);
 44     fd_set rfds;
 45     int retval=0;
 46     int i;
 47     
 48     FD_ZERO(&rfds);
 49     FD_SET(uart_fd, &rfds);
 50     
 51     retval=select(uart_fd + 1, &rfds, NULL, NULL, &tv);
 52     if(retval<0)
 53     {  
 54         perror("select error\\n");  
 55     }
 56     else
 57     {  
 58         if( retval &&   FD_ISSET(uart_fd, &rfds)  )
 59         {
 60             testi++;
 61             printf("FD_ISSET!\\n");
 62             int rc=read(uart_fd, buff, 8);
 63             if(rc>0)
 64             {
 65                 printf("recv serial----rc is %d   testi is %d \\n  ",rc,testi);
 66                 for(i = 0; i < 8; i++)
 67                 printf(" %x ", buff[i]);
 68                 printf("\\n");
 69                 return rc;
 70             }
 71         }    
 72     }    
 73     return 0;
 74 }
 75 
 76 
 77 int monitor_routine( int  uart_fd)
 78 {
 79     int i;
 80     printf("in  monitor_routine\\n");
 81     
 82     char rebuff[8];//设置最大的数据长度为8个
 83     memset(rebuff,0,sizeof(char)*8);
 84     struct timeval tv;
 85     tv.tv_sec = 0;
 86     tv.tv_usec = 10000;
 87     int retval;
 88     unsigned char commbuff[8];//设置最大的数据长度为8个
 89     memset(commbuff,0,sizeof(unsigned char)*8);
 90     
 91     while(1)
 92     {
 93         //printf("retval is %d\\n",retval);
 94         if(Select_Tart_Read(tv,uart_fd,rebuff)>0)//
 95         {
 96             printf("in while Read!\\n");
 97             for(i = 0; i < 8; i++)
 98                 printf(" %x ", rebuff[i]);
 99             printf("\\n");
100         }
101     }
102     return 0;
103 }
104 
105 
106 int main(int argc, char *argv[])
107 {
108         int iFd, i;
109         int len;
110         unsigned char ucBuf[100];
111         struct termios opt;
112 
113         iFd = open(DEV_NAME, O_RDWR | O_NOCTTY);
114 
115         if(iFd < 0) {
116                 perror(DEV_NAME);
117                 printf(" open /dev/ttyS2 faurel!\\n");
118                 return -1;
119         }
120         else 
121             printf(" open /dev/ttyS2 !\\n");
122         tcgetattr(iFd, &opt);
123         cfsetispeed(&opt, B115200);
124         cfsetospeed(&opt, B115200);
125 
126         if (tcgetattr(iFd,   &opt)<0) {
127                   return   -1;
128         }
129         opt.c_lflag    &= ~(ECHO | ICANON | IEXTEN | ISIG);
130         opt.c_iflag    &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
131         opt.c_oflag     &= ~(OPOST);
132         opt.c_cflag     &= ~(CSIZE | PARENB);
133         opt.c_cflag     |=  CS8;
134 
135         opt.c_cc[VMIN]     = 255;
136         opt.c_cc[VTIME]    = 150;
137 
138         if (tcsetattr(iFd,   TCSANOW,   &opt)<0) {
139                 return   -1;
140         }
141         tcflush(iFd,TCIOFLUSH);
142         
143         
144         for (i = 0; i < 100; i++){
145                 ucBuf[i] = 0xff - i;
146         }
147         
148         
149         char buff[6];
150         buff[0]=0x05;buff[1]=0x05;buff[2]=0x05;buff[3]=0x05;buff[4]=0x05;buff[5]=0x05;
151         
152         
153         printf("buff is :\\n");
154         for(i=0;i<6;i++)
155             printf("0x%x ",buff[i]);
156         printf("\\n");
157         
158         printf("write buff!!!");
159         
160         len = write(iFd, buff, 6);
161         
162         if(len < 0) {
163              
164             printf(" write error ! \\n");
165             return -1;
166         }
167         
168         printf("in main monitor_routine\\n");
169         
170         monitor_routine(iFd);
171         
172         printf("\\n");
173 
174 
175 
176         close(iFd);
177         return 0;
178 }

 

 

测试:

 

以上是关于串口读写,select 检测有数据时就接收,防止阻塞问题的主要内容,如果未能解决你的问题,请参考以下文章

C#串口操作类,包括串口读写操作

linux读串口一直返回最后一包数据

Linux中多路串口Select监听方式

Java实现RS485串口通信,发送和接收数据进行解析

串口调试助手都能实现啥功能啊

VMware虚拟机的ubuntu系统可以检测到usb的串口,但不能接收数据