串口操作中,特别以非阻塞的方式读取和发送数据,做好进程之间的同步很重要。有时我们会发现这样一个问题,在进行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下串口操作之数据拼接的更多相关文章

  1. Linux下串口操作

    一.Linux下访问串口 串口位置:/dev/tty** 在Linux系统中,串口设备是通过串口终端设备文件来访问的,也就是通过访问/dev/ttyS0./dev/ttyS1./dev/ttyS2./ ...

  2. Linux下串口編程遇到的接收数据错误及原因(0x0d,0x11接收错误)

    摘要:Linux下串口编程遇到的接收数据错误及原因 来源:https://dotblogs.com.tw/k/2012/07/24/73572 近日在调试串口的时候发现,另一设备向我ARM板的串口发送 ...

  3. Linux下串口编程入门

    简介: Linux操作系统从一开始就对串行口提供了很好的支持,本文就Linux下的串行口通讯编程进行简单的介绍. 串口简介  串行口是计算机一种常用的接口,具有连接线少,通讯简单,得到广泛的使用.常用 ...

  4. linux下串口通信与管理

    linux下的串口与windows有一些区别,下面将介绍一下linux下串口通信管理 查看是否支持USB串口: #lsmod | grep usbserial 如果没有信息:sudo apt-get ...

  5. Linux下Rsync+sersync实现数据实时同步

    inotify 的同步备份机制有着缺点,于是看了sersync同步,弥补了rsync的缺点.以下转自:http://www.osyunwei.com/archives/7447.html 前言: 一. ...

  6. Linux下Rsync+Inotify-tools实现数据实时同步

    Linux下Rsync+Inotify-tools实现数据实时同步 注意:下面的三个案例都是rsync 每次都是全量的同步(这就坑爹了),而且 file列表是循环形式触发rsync ,等于有10个文件 ...

  7. Linux下mongodb安装及数据导入导出教程

    Linux下mongodb安装及数据导入导出教程 #查看linux发行版本 cat /etc/issue #查看linux内核版本号 uname -r 一.Linux下mongodb安装的一般步骤 1 ...

  8. linux下串口的阻塞和非阻塞操作

    有两个可以进行控制串口阻塞性(同时控制read和write):一个是在打开串口的时候,open函数是否带O_NDELAY:第二个是可以在打开串口之后通过fcntl()函数进行控制. 阻塞的定义: 对于 ...

  9. Linux下串口编制【转】

    串行口是计算机一种常用的接口,具有连接线少,通讯简单,得到广泛的使用.常用的串口是RS-232-C接口(又称EIA RS-232-C)它是在1970年由美国电子工业协会(EIA)联合贝尔系统.调制解调 ...

随机推荐

  1. 洛谷OJ P2356 弹珠游戏 维护前缀和

    题目描述 Description MedalPluS 和他的小伙伴 NOIRP 发掘了一个骨灰级别的游戏--超级弹珠. 游戏的内容是:在一个 n*n 的矩阵里,有若干个敌人,你的弹珠可以摧毁敌人,但只 ...

  2. SDWebImage支持WebP格式图片

    SDWebImage本身就已经支持了webp格式的图片 1.下载libwebp https://github.com/webmproject/libwebp 然后你需要先安装好有homebrew或者m ...

  3. Opencv配套的辅助工具Image Watch

    1.Image Watch 的下载链接. 2.OpenCV关于Image Watch的介绍页面链接. 3.OpenCV2.4 在线文档关于Image Watch的介绍文档. 4.更详细的信息参见I ...

  4. C# 高级编程9 第30章MEF C#可扩展编程之MEF第一章

    MEF(Managed Extensibility Framework)是一个用于创建可扩展的轻型应用程序的库 利用该库轻松地封装代码,避免生成脆弱的硬依赖项. 通过 MEF,不仅可以在应用程序内重用 ...

  5. tomcat-调整内存参数

    查看Tomcat的默认内存参数: <% /; /; /; out.println("max="+max); out.println("total="+to ...

  6. 使用jQuery异步传递含复杂属性及集合属性的Model到控制器方法

    Student类有集合属性Courses,如何把Student连同集合属性Courses传递给控制器方法?     public class Student     {         public ...

  7. DockManager如何停靠 z

    DockManager默认只能停靠在窗体上,如果想停靠在其他控件上,我们发现并没有选项可以选,可能目前大部分解决方法是新建一个用户控件文件,再在用户控件里面单独设计模块. 除了这种方法还有没有其他的呢 ...

  8. DevExpress SpreadSheet报表模板设置 z

    DevExpres SpreadSheetControl报表模板设置,这一个还是挺牛逼的,字段绑定直接在单元格里面设置公式(=Field("字段名")),当然直接拖更方便, 跟xt ...

  9. 【视频分享】Liger UI实战集智建筑project管理系统配商业代码(打印报表、角色式权限管理)

    QQ 2059055336 课程讲师:集思博智 课程分类:.net 适合人群:中级 课时数量:23课时 用到技术:Liger UI框架.AJAX.JSON数据格式的序列化与反序列化.角色的交叉权限管理 ...

  10. easyui input设置为disabled提交后获取不到属性值

    在做网站管理后台的用户修改功能时,由于当前用户修改个人信息时规定用户名不能修改,故使用了input标签的disabled属性,但是在提交数据后却发现用户名显示为空了.后 来一查才知道input设置为d ...