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)联合贝尔系统.调制解调 ...
随机推荐
- tyvj:1520 树的直径 spfa/树的直径
tyvj:1520 树的直径 Time Limit: 1 Sec Memory Limit: 131072KiBSubmit: 9619 Solved: 3287 题目连接 http://www. ...
- Push导航栏黑影问题
解决方法可以在自定义的 TabbarViewController里 viewDidLoad方法里 self.view.backgroundColor = [UIColor whiteColor]; 如 ...
- C#多线程编程之:lock使用注意事项
1.避免锁定public类型对象. 如果实例可以被公共访问,将出现lock(this)问题. 如有一个类MyClass,该类有一个Method方法通过lock(this)来实现互斥: 1 public ...
- SpringMVC怎么获取前台传来的数组
var tollerlist = new Array(); for(var k in objToller){ tollerlist.push(k); } $.ajax({ type:"pos ...
- IIS服务中五种身份验证
转载:http://os.51cto.com/art/201005/202380.htm 作为微软最经典的Web服务之一的IIS服务有大致上五种Web身份认证方法.身份认证时保障IIS服务安全的根本, ...
- C#托管堆对象实例包含什么
每个托管堆上的对象实例除了包含本身的值外,还包括:○ Type Object Ponter: 指向Type对象实例.如果是同类型的对象实例,就指向同一个Type对象实例.○ Sync Block In ...
- HTTP 协议中 Vary 的一些研究
经常抓包看 HTTP 请求的同学应该对 Vary 这个响应头字段并不陌生,它有什么用?用 PageSpeed 工具检查页面时,经常看到「Specify a Vary: Accept-Encoding ...
- 自定义圆形控件RoundImageView并认识一下attr
昨天我们学习了自定义带图片和文字的ImageTextButton,非常简单,我承诺给大家要讲一下用自定义属性的方式学习真正的实现自定义控件,在布局文件中使用属性的方式就需要用到attr.xml这个文件 ...
- Android之ConnectivityManager
在android平台中ConnectivityManager主要负责查询网络连接状态以及在连接状态有变化的时候发出通知.其主要的功能职责如下: 1. 监视网络状态,包括(Wi-Fi.GPRS.UMT ...
- SpringMVC @RequestBody 接收Json数组对象
@RequestMapping(value="/signIn",method=RequestMethod.POST) public int saveUser(@RequestBod ...