串口读写,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 [email protected] $(OBJS)

%.o:%.c
	$(CC) $(CFLAGS) -c $< -o [email protected]

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 }

测试:

时间: 2024-12-25 11:24:21

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

串口收发数据时字符、十六进制、二进制格式详细区分

在使用串口调试助手时发送和接收数据都是以字节 (Byte) 为单位,并且可以选择字符.十六进制.二进制三种收发格式 ,那么这三种格式究竟怎样区分呢? 首先我们来明确一个概念 :串口收发数据的单位 '' 字节 (Byte) '' ,   1Byte = 8 bits , 串口收发数据格式一般为  1bit起始位(一般为0) + 8bits 数据位(一字节) +1bit校验位(可有可无) +1bit结束位(一般为1) 下面逐一区分三种收发格式: (1) 十六进制:   由于1位十六进制数位宽为 4b

检查已终止。收集事实数据时检测到错误

数据类型 SQL2005 数据容量 470 MB 故障类型 服务器断电导致数据库系统表异常.消息 8921,级别 16,状态 1,第 1 行 检查已终止.收集事实数据时检测到错误.可能是 tempdb 空间用尽或某个系统表不一致.请检查前面的错误消息. 修复结果 文件发来后 手工纠正系统表后,数据库其他表恢复顺利,但是gl_doc表损坏及其严重,没有软件可以获取到表数据,分析原因是该表 分配信息丢失. 手工从残余记录分析到分配信息后 重新提取完成恢复. 整个数据库完全被用友直接使用,完全OK.

linux串口编程 select

1.串口的阻塞和非阻塞 阻塞的定义: 对于read,block指当串口输入缓冲区没有数据的时候,read函数将会阻塞在这里,一直到串口输入缓冲区中有数据可读取,read读到了需要的字节数之后,返回值为读到的字节数,然后整个程序才继续运行下去:(收) 对于write,block指当串口输出缓冲区满,或剩下的空间小于将要写入的字节数,则write将阻塞,一直到串口输出缓冲区中剩下的空间大于等于将要写入的字节数,执行写入操作,返回写入的字节数,然后整个程序才继续运行下去.(发) 非阻塞的定义: 对于r

[WinAPI] 串口读写

1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <windows.h> 4 5 HANDLE hComm; 6 OVERLAPPED m_ov; 7 COMSTAT comstat; 8 DWORD m_dwCommEvents; 9 10 //如果在调用CreateFile创建句柄时指 11 //定了FILE_FLAG_OVERLAPPED标志,那么调用ReadFile和WriteFile对该句柄进 12 /

honeywell 1500/1300条码枪的串口读写类

此类用于honeywell 1500/1300条码枪的串口读写,可实现控制条码枪扫描,并从条码枪中取得扫描的数据.使用条码枪的串口模式有以下几个好处: (1)避免因文本框失去焦点而导致录入失败. (2)可与自动化设备配合. /*---------------------------------------------------------------- // 文件名:BarcodeScanner.cs // 文件功能描述:条码扫描枪类.用于控制条码枪进行扫描. // // 创建标识:leo 2

串口发送模块——1字节数据发送

此次试验旨在通过串口试验,讲述FPGA的硬件设计思想和通用设计流程.串口是电子设计中非常常见,可以说掌握了串口数据收发,就明白了最基本的时序操作.串口的数据收发过程有其固定的数据格式.下面是本次实验使用的数据格式,在满足串口格式规范前提下是可变的: 空闲状态下为高电平,当发送数据时,先发送低电平起始位,后从低位开始逐位发送有效数据比特,数据位位数由双方约定,此处设定为8位.可在数据位后添加数据校验位,但这不是必须的.发送完后发送高电平停止位并持续空闲状态直至下一次发送.虽然本次实验没有用到,但这

DB2导入数据时乱码问题

1.由于导入import导入数据时乱码,一直找不到解决办法,于是就用load导入 LOAD后,发现某些表检查挂起( 原因码为 "1",所以不允许操作 SQLSTATE=57016 ) 解决办法:set integrity for xxxxxx immediate checked 2.表锁定(原因码为7) 解决办法:reorg table xxxx 3.去重 select distinct a.column from table1 as a inner join table2 as b

默认情况下,不使用of子句表示在select所有的数据表中加锁(转)

Select …forupdate语句是我们经常使用手工加锁语句.通常情况下,select语句是不会对数据加锁,妨碍影响其他的DML和DDL操作.同时,在多版本一致读机制的支持下,select语句也不会被其他类型语句所阻碍. 借助for update子句,我们可以在应用程序的层面手工实现数据加锁保护操作.本篇我们就来介绍一下这个子句的用法和功能. 下面是采自Oracle官方文档<SQLLanguage Reference>中关于for update子句的说明:(请双击点开图片查看) 从for

Linux内核中网络数据包的接收-第二部分 select/poll/epoll

和前面文章的第一部分一样,这些文字是为了帮别人或者自己理清思路的,而不是所谓的源码分析,想分析源码的,还是直接debug源码最好,看任何文档以及书都是下策.因此这类帮人理清思路的文章尽可能的记成流水的方式,尽可能的简单明了. Linux 2.6+内核的wakeup callback机制 Linux 内核通过睡眠队列来组织所有等待某个事件的task,而wakeup机制则可以异步唤醒整个睡眠队列上的task,每一个睡眠队列上的节点都拥有一个 callback,wakeup逻辑在唤醒睡眠队列时,会遍历