Linux下串口操作之数据拼接
串口操作中,特别以非阻塞的方式读取和发送数据,做好进程之间的同步很重要。有时我们会发现这样一个问题,在进行read操作时,一次read不能获得一个完整的数据帧,这就好比你买了一个电脑,送货的先把显示器送到你家,再把机箱送到,你会发现还少键盘鼠标什么的,又要过几天才送,这会让你急死。很不幸,在串口操作的时候,接受数据很可能就是这样分批收货的,但是幸运的是,接受数据的动作很快,别忘了计算机就是靠速度这一点,抛开这个,啥都不是。
很自然的,我们就会进行数据的拼接,将一堆零散的数据拼接成一个个有用的数据帧,哈哈,变废为宝。说多了让人很烦,举个例子吧。
假如我们定义的数据帧是以'$'开头,以‘#’结尾的。
首先定义了两个字符数组:
//一个缓冲数组,用来存放每一次读到的数据
char read_data[256]={0};
//存放一个完整的数据帧,以便处理
char read_buf[256]={0};
再看看凭借数据的函数是怎么样实现的:
//得到了一个完整的数据帧
void get_complete_frame()
{
char read_tmp[256]={0};
int return_flag=0;
int i;
//存放读取到的字节数
while(1)
{
if(read(fd, read_tmp, sizeof(read_tmp))>0)
{
//数据帧的拼接
printf("read_tmp: %s\n",read_tmp);
for( i=0;i<strlen(read_tmp);i++)
{
if(read_tmp[i]=='$')
{
memset(read_data,0,sizeof(read_data));
char tmp[5]={0};
tmp[0]=read_tmp[i];
strcat(read_data,tmp);
}
else if(read_tmp[i]=='#')
{
char tmp[5]={0};
tmp[0]=read_tmp[i];
strcat(read_data,tmp);
return_flag=1;
memset(read_buf,0,sizeof(read_buf));
//遇到帧尾,将read_data帧拷贝到read_buf中,以便处理
memcpy(read_buf,read_data,sizeof(read_data));
}
else
{
char tmp[5]={0};
tmp[0]=read_tmp[i];
strcat(read_data,tmp);
}
}
//有了一个完整的数据帧就返回处理
if(return_flag==1)
return;
}
else//读不到数据就返回,以便检查对方是否断线
return;
usleep(100000);
}
}
从上面的代码中,我们可以看到,每一次从串口读取数据,将读到的数据放在read_tmp中。对这个数组进行逐个地字符分析,遇到帧头标志就清空缓冲数组read_data中,保证了缓冲数组中的数组都是以‘$’开头的;如果遇到了帧尾,哈,我们现在遇到有了一个完整的帧啦,可以去处理帧咯,将数据帧拷贝到read_buf中,程序直接对read_buf进行处理,处理之前别忘了帧尾后面的字符是新的一桢的开头部分,要把它们也保存下来。在程序中我们看到读不到数据就返回,如果不返回,这个函数就会一直运行,那么这样做的效果不就等价于阻塞操作了么,非阻塞就失去了其意义。
大概就这样吧。
Linux下串口操作之数据拼接的更多相关文章
- Linux下串口操作
一.Linux下访问串口 串口位置:/dev/tty** 在Linux系统中,串口设备是通过串口终端设备文件来访问的,也就是通过访问/dev/ttyS0./dev/ttyS1./dev/ttyS2./ ...
- Linux下串口編程遇到的接收数据错误及原因(0x0d,0x11接收错误)
摘要:Linux下串口编程遇到的接收数据错误及原因 来源:https://dotblogs.com.tw/k/2012/07/24/73572 近日在调试串口的时候发现,另一设备向我ARM板的串口发送 ...
- Linux下串口编程入门
简介: Linux操作系统从一开始就对串行口提供了很好的支持,本文就Linux下的串行口通讯编程进行简单的介绍. 串口简介 串行口是计算机一种常用的接口,具有连接线少,通讯简单,得到广泛的使用.常用 ...
- linux下串口通信与管理
linux下的串口与windows有一些区别,下面将介绍一下linux下串口通信管理 查看是否支持USB串口: #lsmod | grep usbserial 如果没有信息:sudo apt-get ...
- Linux下Rsync+sersync实现数据实时同步
inotify 的同步备份机制有着缺点,于是看了sersync同步,弥补了rsync的缺点.以下转自:http://www.osyunwei.com/archives/7447.html 前言: 一. ...
- Linux下Rsync+Inotify-tools实现数据实时同步
Linux下Rsync+Inotify-tools实现数据实时同步 注意:下面的三个案例都是rsync 每次都是全量的同步(这就坑爹了),而且 file列表是循环形式触发rsync ,等于有10个文件 ...
- Linux下mongodb安装及数据导入导出教程
Linux下mongodb安装及数据导入导出教程 #查看linux发行版本 cat /etc/issue #查看linux内核版本号 uname -r 一.Linux下mongodb安装的一般步骤 1 ...
- linux下串口的阻塞和非阻塞操作
有两个可以进行控制串口阻塞性(同时控制read和write):一个是在打开串口的时候,open函数是否带O_NDELAY:第二个是可以在打开串口之后通过fcntl()函数进行控制. 阻塞的定义: 对于 ...
- Linux下串口编制【转】
串行口是计算机一种常用的接口,具有连接线少,通讯简单,得到广泛的使用.常用的串口是RS-232-C接口(又称EIA RS-232-C)它是在1970年由美国电子工业协会(EIA)联合贝尔系统.调制解调 ...
随机推荐
- php模块组成
php总共有三个模块:内核.ZEND引擎.扩展. 内核是用来处理请求.文件流.错误处理等操作的: ZEND引擎是将源文件转换成机器语言,然后在虚拟机上运行: 扩展层是一组函数.类库和流,php使用它们 ...
- Hibernate-数据库更新操作
/* Session接口下操作存在以下问题: 数据更新操作: 1.更新的时候必须要有主键; 2.若只更新部分字段内容,则未设置的字段将被设置为Null(全表更新) 3.update()没有返回值,即不 ...
- 【原】MySQL实用SQL积累
[文档简述] 本文档用来记录一些常用的SQL语句,以达到快速查询的目的. [常用SQL] 1.mysql数据库中获取某个表的所有字段名 select COLUMN_NAME from informat ...
- mysql内核 innodb存储引警(卷1)配书 用VS 2003 编绎 mysql-3.23.49 源代码
作者网址:http://www.innomysql.net/ 1.旧版 mysql-3.23.49-win-src.zip 下载 (***络下载配书源代码) 或者 作者网盘 http://pa ...
- Windows Phone Silverlight 8.1 apps
The Windows Phone Silverlight 8.1 app model gives Windows Phone 8 developers access to some of the n ...
- Moq的一些基本用法
本篇体验Moq的一些基本用法.首先通过NuGet安装Moq.包括: 模拟方法的返回值 模拟方法后执行回调函数 模拟方法依次返回多个值 模拟第二次调用方法返回异常 直接返回被模拟方法的原始返回值 模拟泛 ...
- Python中函数的参数传递与可变长参数
转自旭东的博客原文 Python中函数的参数传递与可变长参数 Python中传递参数有以下几种类型: (1)像C++一样的默认缺省函数 (2)根据参数名传参数 (3)可变长度参数 示例如下: (1)默 ...
- Android实例剖析笔记(一)
摘要:用实例讲解Andriod的开发过程 开卷语 俗话说,“熟读唐诗三百首,不会作诗也会吟”.最近收集了很多Android的示例代码,从这些代码的阅读和实验中学习到很多知识,从而产生写这个系列的打算, ...
- Android SDK目录及版本号区别
来自:http://www.2cto.com/kf/201604/496917.html 今天又有人问Tools,Build-Tools,Platform-tools有什么区别,是干嘛的? 现在对SD ...
- Entityframework:“System.Data.Entity.Internal.AppConfig”的类型初始值设定项引发异常。
<configSections> <!-- For more information on Entity Framework configuration, visit http:// ...