zoukankan      html  css  js  c++  java
  • 关于通信数据的接收缓存

      在嵌入式领域,数据通信是系统中必不可少的部分,对通信数据的收发处理方式无疑是影响系统稳定性的一大因素,在多年的嵌入式软件开发工作中,几乎每个项目都会接触到这一块,曾经以为很简单,但也正由于对它的轻视吃过不少亏。

      印象最深刻的一次是,开发试验阶段通讯收发十分正常,无任何问题,可正式上线之后,经过长时间的运行,就偶尔出现卡死,通信中断,板卡因通信问题而自动复位的现象,这种问题显然不是逻辑问题,因为它是偶然出现的,要解决也不容易再现,极其隐蔽,所以让人很是头疼,花了几个月时间才终于找到原因,现总结如下,以免将来再犯类似错误;

      一般通信不管是用什么物理方式,如RS232、485、CAN、网口等,都是将数据首先定义成意义明确的帧,每帧数据大体上都包含帧头、命令字、长度域、有效数据域、校验域、结束符等这几个部分,收发双方都遵循一个固定的帧格式。发送比较简单,将数据打包组成完整帧之后,往外发送就行了,但接收方则相对麻烦一点,因为有些时候是一次读一个字节,有时候一次可以读很多字节,以何种方式来接收并组包比较好呢,相信有经验的工程师肯定能想到,接收必须得要有缓存,即将数据先全部存到一个缓冲区中,接收并缓存的操作与解析组包处理的操作要独立分开,不能在一起操作,这是最重要的。

      接收缓存一般可以用环形缓冲区,即依次往缓存区中存放数据,缓冲区满之后又从头开始存放,定义两个指针分别记录存和取数据的地址,存的时候头指针往后移动,取的时候尾指针往后移,这样互不干扰,存取的时候只要记得判定指针极限大小就不会有问题,两个指针都是到头了就归零,永远取两指针之间的数据就是我们尚未处理的数据。

      通过尾指针取出数据,我们就可对其做帧格式的解析和判定,从而提取出有效数据,经长时间的验证,这种方式是比较稳定和可靠的。

      曾经让我栽过大跟头的是,在取数据时,有时候缓冲区已经有很多数据了,将其一一取出,去做格式解析,有可能这些数据长度是大于一帧的,这时必须在解析一帧之后,就停止取数据,否则缓冲区中数据就会丢失,造成不可知的问题。

  • 相关阅读:
    Django orm self 自关联表
    postgresql数据库导入导出
    celery在项目中的使用
    P3405 [USACO16DEC]Cities and States S 【map使用】
    P1030 求先序排列 【已知中序后序求先序】
    P1305 新二叉树 【寻找根节点进行先序遍历】
    P1229 遍历问题 【已知先序后序求中序种类】
    P1364 医院设置 【带权值的树的重心】
    P3884 [JLOI2009]二叉树问题 【离线tarjan或数的向上遍历】
    P1827 [USACO3.4]美国血统 American Heritage【树的遍历】
  • 原文地址:https://www.cnblogs.com/beyonne/p/7607719.html
Copyright © 2011-2022 走看看