通信協(xié)議文本化到底有多重要?老司機(jī)來告訴你
劉慈欣在其封神之作《三體》里描述過三體人的交流方式:倆人就這么站著不說話,四目相交,天雷引著地火,腦電波你來我往。沒有時延,不用等待,頃刻間便心與心相印,魂與魂深交,想來就十分美好。
本文引用地址:http://www.ex-cimer.com/article/202004/412589.htm相比之下,人類通過“語言”把隱晦的思考隱藏在幽微的心底,審時度勢,鼓舌如簧,說言不由衷的話,撒漫不經(jīng)心的謊。
大劉在《三體》里,將此視為地球人類對三體人的一大優(yōu)勢。上兵伐謀,兵不厭詐,在宇宙這座黑暗森林中,只有善于隱藏和偽裝,才能更好地生存。
是的,語言是一門隱藏真實的藝術(shù)。
其實,它不只在人類世界如此,在電子設(shè)備之間依然如斯。在電子設(shè)備之間,它有一個專業(yè)性的稱謂:通信協(xié)議。
一
電子工程師對“通信協(xié)議”這個詞匯耳熟能詳,如數(shù)家珍。平時掛在嘴邊的就有USB、RS232、CAN、LIN、ModBus、RS485、SPI、I2C、Zigbee、紅外、藍(lán)牙、WiFi......
“通信協(xié)議”也許是一個定義模糊的詞匯,因為,嚴(yán)格說起來,上面列舉的都是通信標(biāo)準(zhǔn),或有線或無線,或廣域或局域,或遠(yuǎn)程或短距,而且它們大多只是定義了物理層、鏈路層協(xié)議,當(dāng)然有的還包含了傳輸層和會話層。
但是筆者今天想要跟大家探討的則是基于這些通信鏈路之上的應(yīng)用層協(xié)議。
應(yīng)用層協(xié)議和終端應(yīng)用密切相關(guān),就拿筆者比較熟悉的藍(lán)牙來說,針對車載免提有HFP協(xié)議,針對電話本傳輸有PBAP協(xié)議,針對耳機(jī)有A2DP、AVRCP協(xié)議......
除了這些針對特定場景具體應(yīng)用制定了貼心協(xié)議的通信標(biāo)準(zhǔn)之外,有很多場合是需要工程師自己制定應(yīng)用協(xié)議的,比如今天筆者要跟大家分享的測試工裝上位機(jī)和下位機(jī)之間的通信協(xié)議。
二
一把鑰匙一把鎖,一桿鋼筆一只筆帽,倚天劍得配個劍鞘,量產(chǎn)產(chǎn)品肯定需要測試工裝一套。
測試工裝咱就不多費筆墨了,總之就是上位機(jī)和下位機(jī)之間用串口或者USB,然后用類似于下面的老套通信協(xié)議互發(fā)報文:
報文頭(設(shè)為0x55+0xaa)+id(報文的ID)+data_len(數(shù)據(jù)長度)+data+checksum
大家伙對這種樣式的通信協(xié)議肯定是熟得不能再熟了,以至于可能熟視無睹,根本沒有意識到這里有哪些不對勁。
想想看,如果這種通信協(xié)議下的報文流出了問題,我們想搭眼看看哪里出了錯,是很難一看就看出個所以然的。
報文背后的信息就好像蒙了一層面紗,猶抱琵琶半遮面,千呼萬喚不出來。
我們需要把協(xié)議文檔翻出來,一條一條地比照才能知道這里的id到底對應(yīng)的是哪一條具體的測試項,這里的數(shù)據(jù)到底表示什么意思。
不過好在,我們只要嚴(yán)格地按照報文格式封裝和解析這些報文,并保證報文的消費(解析)速度高過生產(chǎn)(接收)速度,干完這些dirty work之后我們就不需要關(guān)心它是不是那么朦朧難辨了。
畢竟,最終執(zhí)行這些協(xié)議的都是計算機(jī)和電子設(shè)備,而這正是它們的強(qiáng)項。
所以,直到現(xiàn)在,我依然能夠想起幾年前采用這種方式做測試工裝時的那種心情:
九月里,平淡無聊,一切都好,只缺煩惱。
直到有一天,我和報文里的內(nèi)容打起了交道。
三
本來,時光悠悠,歲月靜好,一切的一切都充滿了幸福的味道。
小張按照上文那種報文格式把某個測試項的請求發(fā)下來,我啟動具體的測試,把測試數(shù)據(jù)發(fā)給他,他按照測試項的具體功能邏輯,通過測試數(shù)據(jù)判斷測試是否通過。
時間滴滴答答,客戶端(上位機(jī))和服務(wù)器(下位機(jī))的請求和響應(yīng)也沒有出過岔。
可是不知怎的,許是我改了改程序,又或者小張動了動代碼,那天下午出現(xiàn)了本該測試通過的測試項失敗的情況。
于是乎,秋高氣爽,艷陽高照,我和小張打起了嘴炮。
頂著沖冠的怒發(fā),小張污我有的報文會漏發(fā),我不留情面地說他的水平不到家,不知道用個buffer把接收的報文先緩存一下下。
為了證明報文不會漏發(fā),我用工裝上多余的串口接上電腦上的串口助手,兩個串口的數(shù)據(jù)同時發(fā),在串口助手的界面上把數(shù)據(jù)給他抓了一下。
然后,我倆對著電腦看了一會兒,各位看官呢,就一會兒,我們哥倆就懵圈啦!
那么多0x55 0xaa,誰知道后面那個id和數(shù)據(jù)表示的啥意思呀。面對這樣蒙著面紗的數(shù)據(jù),誰看誰懵圈吧!
無法自證清白的我茫然地看著界面里的數(shù)據(jù)排得密密麻麻,一時間覺得無法招架。側(cè)過頭來,瞥見了小張無意識中張開的大嘴巴,‘真像是一個大傻瓜’。再轉(zhuǎn)過頭來,看了不大會兒數(shù)據(jù)又覺得眼花。
眼花是必然的,因為這里的數(shù)據(jù)報文本來就不具備可讀性嘛。
聚成了是一團(tuán)火,反正它能很好地干活,但是散開了則是滿天星,對著你一閃一閃亮晶晶,讓你找起問題來火冒金星。
它又如浮萍在水,如淡云在天,只要勁風(fēng)拂來,便是個萍亂云散的境地。
其實說到底,想自然地解讀這種不具備可讀性的通信協(xié)議是不是有些傻?
荒謬的感覺越來越盛,對通信協(xié)議的追問也越來越深入,然后我自然而言地提出了一個關(guān)鍵性的問題:通信協(xié)議可不可以具備可讀性?當(dāng)然可以,藍(lán)牙的應(yīng)用協(xié)議(profile)不就是可讀的嗎?怎么賦予它可讀性?文本化!
就這樣,一個呼吸之間,腦海里問題剛剛浮現(xiàn),答案就出現(xiàn)在眼前,猶如天外飛仙。
我突然感到很佩服自己。
禪門大德開導(dǎo)座下弟子時,經(jīng)常說一句:‘脫了衣服去!’通信協(xié)議文本化,何嘗不是脫掉了衣服,揭開了它的面紗?!
我把從心底瞬間涌上來的情緒,壓縮成一句話,最終把它一字一頓地說了出來:
萬物皆有靈,只需喚起它們的靈性。
話音甫落,小張的嘴巴張得更大了。
四
在兩個電子設(shè)備之間采用文本式進(jìn)行通信,仿佛它們就脫離了無情種智,進(jìn)入了有情眾生的世界。
向小張普及了這個思想之后,我旋即制定了一個可統(tǒng)一各個測試項的通信協(xié)議。
上位機(jī)發(fā)起測試請求,報文內(nèi)容為“TestReq XXXrn”,其中的XXX代表具體的測試項,比如要測試信號強(qiáng)度,XXX=RSSI,比如要測試1號繼電器,XXX=RELAY1......
下位機(jī)返回測試結(jié)果,測試成功時報文內(nèi)容為“TestResult XXX OKrn”,測試失敗時報文內(nèi)容為“TestResult XXX ERRrn”,這里的XXX就是上述所謂測試項名稱。
具體解析時也很簡單,先通過換行符rn把一條獨立的報文提取出來,然后把報文頭“TestReq ”或者“TestResult ”查找出來,然后就定位到了XXX的位置,把它讀取出來即可。
封裝報文和解析報文也都變得無比地簡單,因為C語言有字符串函數(shù)支持上面這一系列操作!
這樣一來,在通信鏈路上傳輸?shù)臄?shù)據(jù)都是可讀的,而且報文通過換行符進(jìn)行間隔,是不是漏發(fā),是不是報文中間的數(shù)據(jù)發(fā)生了錯誤,都一目了然了。
后來,在文本化通信的幫助下,小張的問題也找到了。
原來,測試工裝上位機(jī)軟件設(shè)計時,對每個測試條目都加了超時限制,當(dāng)它的計算機(jī)上打開很多軟件時,測試工裝上位機(jī)軟件的實時性就變差了,有的時候就自動觸發(fā)了超時,標(biāo)記為測試失敗。
恩,小張這個設(shè)計思路當(dāng)然有一定的問題,但是這不是本文要探究的主題:)
五
央視主持人大賽里有一期節(jié)目,里面有一個擂臺題目是“做新聞是內(nèi)容重要還是形式重要”。雙方唇槍舌戰(zhàn),鼓舌如簧,紛紛站在自己抽簽抽到的立場上引經(jīng)據(jù)典,這邊說內(nèi)容重要,那邊說形式重要。我當(dāng)時看得那個著急啊,這些單純的讀書人啊,難道你們不知道,內(nèi)容很重要,形式也很重要嘛!
就像本文討論的通信協(xié)議一樣,采用具有可讀性的文本形式既能很好地滿足雙方交互,又能明明白白地顯示給在一旁監(jiān)控它運行的工程師,一箭雙雕,豈不美哉!
評論