7E头解析的那些事儿(帧格式分析实例)

本文详细介绍如何从包含0x7E和0x7D的串行数据帧中,根据特定帧格式提取有效协议信息。通过实例演示了数据转换规则,并提供了hdlc_send和hdlc_rcv_frm函数的实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

击上方“一口Linux”,选择“星标公众号

干货福利,第一时间送达!

e2fd10065cfe4a86cc8a47acd97776fa.gif

0. 前言

作为一名嵌入式工程师,经常需要通过UART与外设打交道,而对于串行总线来说,往往我们必须要进行帧同步。通常的做法是把信令包含在2个0x7E的中间。

除此之外还有HDLC、PPP等协议也会到有此应用场景。

那么如何从这些数据帧中提取有效数据呢?

本文通过一个简单的实例给大家详细讲述如何从帧中提取有效的协议信令。

1. 帧格式要求

首先我们明确下帧提取的一些要求:

  • (1)把信息字段中出现的每一个0x7E字节转变为2字节序列(0x7D,0x5E)。

  • (2)若信息字段中出现一个0x7D的字节(即出现了和转义字符一样的比特组合),则把转义字符0x7D转变为2字节序列(0x7D,0x5D)。

    a13fc49cde86f9ea263d14338804417a.png

举例:一个PPP帧的数据部分:

7D 5E FE 27 7D 5D 7D 5D 65 7D 5E

那么实际上真正的数据是

7E FE 27 7D 7D 65

转换图解:7fff76fa26f64896b9d25a7dd9ef2708.png同样的,如果要发送数据,则反过来。

2. 设计

  1. 底层传上来的每一短帧长度不固定

  2. 底层传上来的每一短帧7e头位置不固定,可能有可能没有,可能有1个7e也可能有2个7e

  3. 默认每一帧数据最多2个7e

比如:我们从底层收上来的原始数据帧格式如下:4f377912aa5cc21b70b24d78ad265e9f.png那么我们要能够提取两个7e之间的协议数据帧,同时还原帧中的所有的7e。

很显然我们希望最终解析后结果如下:

7e 0f 0e 30 27 1c 00 27 1c 01 27 1c 02 7e 00 29 7e 
7e 11 73 7e 
7e 00 27 1c 01 27 1c 02 7e 00 29 7e

帧解析详细设计流程图

ba77c975deba8bb7943c5460861d4037.png

3.代码

不上代码的就是耍流氓

首先看下如果下发数据帧,如何将所有的7e和7d做替换:函数hdlc_send(char * data,UINT8 len)实现如下:

ea98eefbac6a046b1b99095116648767.png

int hdlc_rcv_frm(UINT8 *data,int len)实现如下

32ae472f29bfd27f2c0650fecbb07c98.png测试代码如下:

int main()
{
 int len;
 
 char data1[6]={0x7e,0xf,0xe,0x30,0x27,0x1c}; 
 char data2[6]={0x0,0x27,0x1c,0x1,0x27,0x1c};
 char data3[8]={0x2,0x7d,0x5e,0x0,0x29,0x7e,0x0,0x7e};
 char data4[6]={0x11,0x73,0x7e,0x30,0x27,0x7e}; 
 char data5[6]={0x0,0x27,0x1c,0x1,0x27,0x1c};
 char data6[6]={0x2,0x7d,0x5e,0x0,0x29,0x7e}; 

#if 0
 printf("************测试hdlc_send()******************\n");

 len = hdlc_send(data1,6);

 printf("********************end**********************\n\n");
#endif
 printf("\n************测试hdlc_rcv_frm()******************\n");
 hdlc_rcv_frm(data1,6);
 hdlc_rcv_frm(data2,6);
 hdlc_rcv_frm(data3,8);
 
 hdlc_rcv_frm(data4,6);
 hdlc_rcv_frm(data5,6);
 hdlc_rcv_frm(data6,6);
 printf("********************end**************************\n");
}

运行结果如下:

5aae7b6577d1d54ad9c2671cbf0eab4e.png

注意

本代码仍然有一些bug,暂时没有修改,所以实际项目慎用。小心数组越界啊!

完整代码链接:

链接:https://pan.baidu.com/s/1rPEDC3erLpPRH0OnkfNH_A

提取码:wzxq

end

一口Linux 

关注,回复【1024】海量Linux资料赠送

精彩文章合集

ARM

粉丝问答

所有原创

linux入门

计算机网络

Linux驱动

嵌入式驱动工程师学习路线

Linux嵌入式所有知识点-思维导图

点击“阅读原文”查看更多分享,欢迎点分享、收藏、点赞、在看

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值