新闻中心

EEPW首页 > 牛人业话 > 通信协议文本化到底有多重要?老司机来告诉你

通信协议文本化到底有多重要?老司机来告诉你

作者:小么哥时间:2020-04-29来源:电子产品世界收藏

刘慈欣在其封神之作《三体》里描述过三体人的交流方式:俩人就这么站着不说话,四目相交,天雷引着地火,脑电波你来我往。没有时延,不用等待,顷刻间便心与心相印,魂与魂深交,想来就十分美好。

本文引用地址:http://www.eepw.com.cn/article/202004/412589.htm

相比之下,人类通过“语言”把隐晦的思考隐藏在幽微的心底,审时度势,鼓舌如簧,说言不由衷的话,撒漫不经心的谎。

大刘在《三体》里,将此视为地球人类对三体人的一大优势。上兵伐谋,兵不厌诈,在宇宙这座黑暗森林中,只有善于隐藏和伪装,才能更好地生存。

是的,语言是一门隐藏真实的艺术。

其实,它不只在人类世界如此,在电子设备之间依然如斯。在电子设备之间,它有一个专业性的称谓:

电子工程师对“”这个词汇耳熟能详,如数家珍。平时挂在嘴边的就有USB、RS232、CAN、LIN、ModBus、RS485、SPI、I2C、Zigbee、红外、蓝牙、WiFi......

”也许是一个定义模糊的词汇,因为,严格说起来,上面列举的都是通信标准,或有线或无线,或广域或局域,或远程或短距,而且它们大多只是定义了物理层、链路层协议,当然有的还包含了传输层和会话层。

但是笔者今天想要跟大家探讨的则是基于这些通信链路之上的应用层协议。

应用层协议和终端应用密切相关,就拿笔者比较熟悉的蓝牙来说,针对车载免提有HFP协议,针对电话本传输有PBAP协议,针对耳机有A2DP、AVRCP协议......

除了这些针对特定场景具体应用制定了贴心协议的通信标准之外,有很多场合是需要工程师自己制定应用协议的,比如今天笔者要跟大家分享的测试工装上位机和下位机之间的通信协议。

一把钥匙一把锁,一杆钢笔一只笔帽,倚天剑得配个剑鞘,量产产品肯定需要测试工装一套。

测试工装咱就不多费笔墨了,总之就是上位机和下位机之间用串口或者USB,然后用类似于下面的老套通信协议互发报文:

报文头(设为0x55+0xaa)+id(报文的ID)+data_len(数据长度)+data+checksum

大家伙对这种样式的通信协议肯定是熟得不能再熟了,以至于可能熟视无睹,根本没有意识到这里有哪些不对劲。

想想看,如果这种通信协议下的报文流出了问题,我们想搭眼看看哪里出了错,是很难一看就看出个所以然的。

报文背后的信息就好像蒙了一层面纱,犹抱琵琶半遮面,千呼万唤不出来。

我们需要把协议文档翻出来,一条一条地比照才能知道这里的id到底对应的是哪一条具体的测试项,这里的数据到底表示什么意思。

不过好在,我们只要严格地按照报文格式封装和解析这些报文,并保证报文的消费(解析)速度高过生产(接收)速度,干完这些dirty work之后我们就不需要关心它是不是那么朦胧难辨了。

毕竟,最终执行这些协议的都是计算机和电子设备,而这正是它们的强项。

所以,直到现在,我依然能够想起几年前采用这种方式做测试工装时的那种心情:

九月里,平淡无聊,一切都好,只缺烦恼。

直到有一天,我和报文里的内容打起了交道。

本来,时光悠悠,岁月静好,一切的一切都充满了幸福的味道。

小张按照上文那种报文格式把某个测试项的请求发下来,我启动具体的测试,把测试数据发给他,他按照测试项的具体功能逻辑,通过测试数据判断测试是否通过。

时间滴滴答答,客户端(上位机)和服务器(下位机)的请求和响应也没有出过岔。

可是不知怎的,许是我改了改程序,又或者小张动了动代码,那天下午出现了本该测试通过的测试项失败的情况。

于是乎,秋高气爽,艳阳高照,我和小张打起了嘴炮。

顶着冲冠的怒发,小张污我有的报文会漏发,我不留情面地说他的水平不到家,不知道用个buffer把接收的报文先缓存一下下。

为了证明报文不会漏发,我用工装上多余的串口接上电脑上的串口助手,两个串口的数据同时发,在串口助手的界面上把数据给他抓了一下。

然后,我俩对着电脑看了一会儿,各位看官呢,就一会儿,我们哥俩就懵圈啦!

那么多0x55 0xaa,谁知道后面那个id和数据表示的啥意思呀。面对这样蒙着面纱的数据,谁看谁懵圈吧!

无法自证清白的我茫然地看着界面里的数据排得密密麻麻,一时间觉得无法招架。侧过头来,瞥见了小张无意识中张开的大嘴巴,‘真像是一个大傻瓜’。再转过头来,看了不大会儿数据又觉得眼花。

眼花是必然的,因为这里的数据报文本来就不具备可读性嘛。

聚成了是一团火,反正它能很好地干活,但是散开了则是满天星,对着你一闪一闪亮晶晶,让你找起问题来火冒金星。

它又如浮萍在水,如淡云在天,只要劲风拂来,便是个萍乱云散的境地。

其实说到底,想自然地解读这种不具备可读性的通信协议是不是有些傻?

荒谬的感觉越来越盛,对通信协议的追问也越来越深入,然后我自然而言地提出了一个关键性的问题:通信协议可不可以具备可读性?当然可以,蓝牙的应用协议(profile)不就是可读的吗?怎么赋予它可读性?

就这样,一个呼吸之间,脑海里问题刚刚浮现,答案就出现在眼前,犹如天外飞仙。

我突然感到很佩服自己。

禅门大德开导座下弟子时,经常说一句:‘脱了衣服去!’通信协议,何尝不是脱掉了衣服,揭开了它的面纱?!

我把从心底瞬间涌上来的情绪,压缩成一句话,最终把它一字一顿地说了出来:

万物皆有灵,只需唤起它们的灵性。

话音甫落,小张的嘴巴张得更大了。

在两个电子设备之间采用文本式进行通信,仿佛它们就脱离了无情种智,进入了有情众生的世界。

向小张普及了这个思想之后,我旋即制定了一个可统一各个测试项的通信协议。

上位机发起测试请求,报文内容为“TestReq XXXrn”,其中的XXX代表具体的测试项,比如要测试信号强度,XXX=RSSI,比如要测试1号继电器,XXX=RELAY1......

下位机返回测试结果,测试成功时报文内容为“TestResult XXX OKrn”,测试失败时报文内容为“TestResult XXX ERRrn”,这里的XXX就是上述所谓测试项名称。

具体解析时也很简单,先通过换行符rn把一条独立的报文提取出来,然后把报文头“TestReq ”或者“TestResult ”查找出来,然后就定位到了XXX的位置,把它读取出来即可。

封装报文和解析报文也都变得无比地简单,因为C语言有字符串函数支持上面这一系列操作!

这样一来,在通信链路上传输的数据都是可读的,而且报文通过换行符进行间隔,是不是漏发,是不是报文中间的数据发生了错误,都一目了然了。

后来,在通信的帮助下,小张的问题也找到了。

原来,测试工装上位机软件设计时,对每个测试条目都加了超时限制,当它的计算机上打开很多软件时,测试工装上位机软件的实时性就变差了,有的时候就自动触发了超时,标记为测试失败。

恩,小张这个设计思路当然有一定的问题,但是这不是本文要探究的主题:)


央视主持人大赛里有一期节目,里面有一个擂台题目是“做新闻是内容重要还是形式重要”。双方唇枪舌战,鼓舌如簧,纷纷站在自己抽签抽到的立场上引经据典,这边说内容重要,那边说形式重要。我当时看得那个着急啊,这些单纯的读书人啊,难道你们不知道,内容很重要,形式也很重要嘛!

就像本文讨论的通信协议一样,采用具有可读性的文本形式既能很好地满足双方交互,又能明明白白地显示给在一旁监控它运行的工程师,一箭双雕,岂不美哉!



关键词: 通信协议 文本化

评论


相关推荐

技术专区

关闭