博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
COBSforToN一种用于串行通讯的高效编码算法
阅读量:6246 次
发布时间:2019-06-22

本文共 1971 字,大约阅读时间需要 6 分钟。

  hot3.png

        一般用串口进行数据通讯时,我们会在发送端(master)把传输的数据流按照一定的规则划分成数据帧进行传输,接收端(client)根据约定好的规则将接收的数据流分帧解析执行。传统的方式主要有两种:

        1、首先将传输的数据转化成ASCII码形式(这样实际传输的数值范围被锁定在0x30~0x7a之间),然后在数据的前后加上特定的字节数据(比如0x02'STX',0x03'ETX'),形成一帧数据。这样可以保证帧头帧尾的标志字节不会和实际数据内容重合,分帧解析变得非常容易,只要找到相应的帧头、帧尾即可。这种方式有个弊端,把数据转化成ASCII时,转化后的数据长度是转化前的2倍,效率非常低下,这对于实时性要求高(比如485总线通讯中有多个从机的时候)的应用,有时无法满足要求。

        2、通过控制发送字节的时间间隔进行分帧,modbus中也叫RTU模式。发送端精准控制每个字节的发送时间,一般两个字节之间的发送间隔为一个传送字节时间(具体跟波特率有关), 帧与帧之间的时间间隔要>=5个字符时间,接收端不断的判断下一个字节数据的到达时间,如果时间超过间隔时间则判定一帧数据结束。该方式实时性较高,但是需要精确的计算发送时间,有可能出现无法识别的情况。

102151_KWbi_1789387.png

 

 

        COBSforN(Consistent Overhead Byte Stuffing,恒定开销的字节填充)是一种固定开销的字节填充算法。字节填充用于处理那些包含了特殊或保留字符的字符序列编码,通过一定的算法在原有的字符序列长度+1 生成编码后的字符序列,新的序列将不会包含之前序列中出现的特殊或者保留的字符。其具体算法思想以及研究见 ,以下举两个例子:             

Example Unencoded data (hex) Encoded with COBS (hex)
1 00 01 01 00
2 00 00 01 01 01 00
3 11 22 00 33 03 11 22 02 33 00
4 11 22 33 44 05 11 22 33 44 00
5 11 00 00 00 02 11 01 01 01 00
6 01 02 ... FE FF 01 02 ... FE 00

        算法源码如下:

        1、编码

/* * StuffData byte stuffs “length” bytes of * data at the location pointed to by “ptr”, * writing the output to the location pointed * to by “dst”. */#define FinishBlock(X) (*code_ptr = (X), \						code_ptr = dst++, \						code = 0x01 )void StuffData(const unsigned char *ptr, unsigned long length,		unsigned char *dst){	const unsigned char *end = ptr + length;	unsigned char *code_ptr = dst++;	unsigned char code = 0x01;	while (ptr < end)	{		if (*ptr == 0)			FinishBlock(code);		else		{			*dst++ = *ptr;			code++;			if (code == 0xFF)				FinishBlock(code);		}		ptr++;	}	FinishBlock(code);}

        2、解码

/* * UnStuffData decodes “length” bytes of * data at the location pointed to by “ptr”, * writing the output to the location pointed * to by “dst”. */void UnStuffData(const unsigned char *ptr, unsigned long length,		unsigned char *dst){	const unsigned char *end = ptr + length;	while (ptr < end)	{		int i, code = *ptr++;		for (i = 1; i < code; i++)			*dst++ = *ptr++;		if (code < 0xFF)			*dst++ = 0;	}}

 

转载于:https://my.oschina.net/Cw6PKk/blog/750067

你可能感兴趣的文章
jstat (JVM统计监测工具)
查看>>
git 免密码push,pull
查看>>
js懒加载
查看>>
计算某时间是年中第几周。
查看>>
【论文阅读】A mixed-scale dense convolutional neural network for image analysis
查看>>
用正则表达式匹配网址URL中最后一个反斜杠/后面的内容
查看>>
Define custom @Required-style annotation in Spring
查看>>
General: Know How to Use InetAddress
查看>>
php 克隆和引用类
查看>>
Linux编程之变量
查看>>
weblogic的下载安装及myeclipse的配置
查看>>
android 第一次运行应用的引导界面
查看>>
我的vimrc配置
查看>>
Java运行原理及内存分析
查看>>
构建之法阅读笔记03
查看>>
C#进程监控
查看>>
Vijos1404 遭遇战 最短路,dijkstra,堆
查看>>
svn解决与优化帮助
查看>>
SQL update select结合语句详解及应用
查看>>
[转]阿里要走102年,阿里的工程师能走多远呢?
查看>>