可靠串口通信協(xié)議

本文描述了基于串口進(jìn)行數(shù)據(jù)幀通信的協(xié)議設(shè)計(jì)和實(shí)現(xiàn)方法。

數(shù)據(jù)幀格式


| 前導(dǎo)碼 | 頭部 | 數(shù)據(jù) | 校驗(yàn) |

  • 前導(dǎo)碼: 用于幀同步,通知接收端數(shù)據(jù)幀開(kāi)始
  • 頭部: 幀描述信息,包括長(zhǎng)度,幀ID,ACK,版本號(hào)等
  • 數(shù)據(jù): 有效載荷
  • 校驗(yàn): 對(duì)頭部和數(shù)據(jù)部分的CRC校驗(yàn)

發(fā)送端


數(shù)據(jù)結(jié)構(gòu):

  • 一個(gè)固定長(zhǎng)度的發(fā)送隊(duì)列,例如10個(gè)數(shù)據(jù)幀的鏈表
  • 重傳定時(shí)器,取值為一個(gè)數(shù)據(jù)幀的傳輸時(shí)延

執(zhí)行循環(huán):

  1. 如果隊(duì)列有空閑空間,取上層應(yīng)用緩存中的數(shù)據(jù)幀發(fā)送,否則
  2. 如果重傳定時(shí)器超時(shí),取發(fā)送隊(duì)列中最老的數(shù)據(jù)幀發(fā)送
  3. 如果沒(méi)有數(shù)據(jù)幀可以發(fā)送,取消重傳定時(shí)器,否則,
  4. 重置重傳定時(shí)器
  5. 發(fā)送前導(dǎo)碼
  6. 發(fā)送數(shù)據(jù)幀
  7. 發(fā)送校驗(yàn)碼
  8. 如果接收到成功答復(fù),從隊(duì)列中去除該數(shù)據(jù)幀。如果該幀不是隊(duì)列中最老的幀,說(shuō)明發(fā)生幀丟失,立刻觸發(fā)重傳機(jī)制
  9. 如果接收到失敗答復(fù),從隊(duì)列中重傳該數(shù)據(jù)幀,并重置重傳定時(shí)器

設(shè)計(jì)說(shuō)明:

  • 發(fā)送隊(duì)列的目的是為了提高發(fā)送速度,不需要嚴(yán)格順序化發(fā)送數(shù)據(jù)包。
  • 可以將每個(gè)隊(duì)列看作一條數(shù)據(jù)流,頭部加入流ID后可以支持多條數(shù)據(jù)流,這時(shí)需要一個(gè)調(diào)度器進(jìn)行流量調(diào)整

接收端


數(shù)據(jù)結(jié)構(gòu):

  • 一個(gè)固定長(zhǎng)度的發(fā)送隊(duì)列,例如10個(gè)數(shù)據(jù)幀的鏈表
  • 最后接收的幀ID

執(zhí)行循環(huán):

  1. 接收前導(dǎo)碼,并丟棄無(wú)效數(shù)據(jù),直到發(fā)現(xiàn)有效前導(dǎo)碼。如果一直沒(méi)有發(fā)現(xiàn)前導(dǎo)碼,返回失敗答復(fù)。
  2. 接收頭部,解析長(zhǎng)度信息,并做有效性驗(yàn)證,如果驗(yàn)證無(wú)效,返回失敗答復(fù)。如果在頭部中發(fā)現(xiàn)前導(dǎo)碼,則認(rèn)為是新的數(shù)據(jù)幀開(kāi)始,重新開(kāi)始接收頭部。
  3. 接收數(shù)據(jù),接收CRC,并作有效性驗(yàn)證,如果驗(yàn)證無(wú)效,返回失敗答復(fù)。如果在數(shù)據(jù)和CRC中發(fā)現(xiàn)前導(dǎo)碼,則認(rèn)為是新的數(shù)據(jù)幀開(kāi)始,重新開(kāi)始接收頭部。
  4. 數(shù)據(jù)幀接收完畢,返回成功答復(fù)。
  5. 嘗試將數(shù)據(jù)幀加入接收隊(duì)列,如果發(fā)現(xiàn)重復(fù)幀,直接丟棄,否則按幀ID進(jìn)行順序插入。如果該幀是最后一次成功接收的下一幀,則通知應(yīng)用層獲取數(shù)據(jù),數(shù)據(jù)取走后,更新最后接收幀ID。
  6. 如果接收隊(duì)列已滿,則通知發(fā)送端停止發(fā)送,知道有足夠空閑空間再通知發(fā)送端重傳。

設(shè)計(jì)說(shuō)明:

  • 接收隊(duì)列的目的跟發(fā)送隊(duì)列類(lèi)似,另外提供基于幀ID的排序功能
  • 在整個(gè)接收過(guò)程中持續(xù)檢測(cè)前導(dǎo)碼,避免丟棄有效數(shù)據(jù)幀
  • 接收端對(duì)發(fā)送端進(jìn)行抑制,防止上層應(yīng)用接收數(shù)據(jù)不及時(shí)導(dǎo)致發(fā)送端無(wú)效重傳

ACK幀格式


單向數(shù)據(jù)流簡(jiǎn)化設(shè)計(jì)

接收端發(fā)送返回幀時(shí),通信角色發(fā)生調(diào)換,原來(lái)的接收端變?yōu)榘l(fā)送端,原來(lái)的發(fā)送端變?yōu)榻邮斩恕榱撕?jiǎn)化這個(gè)階段的協(xié)議設(shè)計(jì),避免重復(fù)執(zhí)行上述流程,可以將ACK幀按照最簡(jiǎn)單形式設(shè)計(jì),比如僅用1個(gè)字節(jié)來(lái)表示:

|一字節(jié)返回碼|

返回碼取值:

  • 0:表示接收端緩存已滿,停止發(fā)送
  • -128:表示接收端緩存有空閑,發(fā)送端可以繼續(xù)發(fā)送
  • +N: 表示成功接收到幀ID為N的數(shù)據(jù)幀,取值范圍 [1, 127]
  • -N: 表示幀ID為N的數(shù)據(jù)幀接收失敗,取值范圍 [-1, -127]

進(jìn)一步說(shuō)明:

  • 沒(méi)有前導(dǎo)碼,單個(gè)字節(jié)表述所有信息
  • 有效幀ID為 [1, 127],超過(guò)127后幀ID會(huì)回繞為1。因此發(fā)送和接收端在127邊界處要保證前面的數(shù)據(jù)幀完全傳輸成功后再進(jìn)行回繞處理。

雙向數(shù)據(jù)流設(shè)計(jì)

在雙工模式下,無(wú)法進(jìn)行上述簡(jiǎn)化處理,通信兩端互為發(fā)送端和接收端,此時(shí)ACK可以作為獨(dú)立數(shù)據(jù)幀發(fā)送,也可以?shī)A在有效數(shù)據(jù)幀頭部發(fā)送。

前導(dǎo)碼


如果前導(dǎo)碼在有效數(shù)據(jù)幀中出現(xiàn),那么會(huì)被誤認(rèn)為是新的數(shù)據(jù)幀開(kāi)始,從而導(dǎo)致新的數(shù)據(jù)幀以外校驗(yàn)失敗而丟棄,這在一定程度上浪費(fèi)帶寬資源。因此要求前導(dǎo)碼具有唯一性,不允許出現(xiàn)在數(shù)據(jù)幀中。一種做法是在發(fā)送端對(duì)數(shù)據(jù)幀進(jìn)行替換處理,將數(shù)值與前導(dǎo)碼相同的數(shù)據(jù)進(jìn)行格式變換。比如前導(dǎo)碼為01010101,那么如果可以將該數(shù)值擴(kuò)展為01010101 01010101,在接收端進(jìn)行反向操作,將01010101 010101替換為01010101。這會(huì)增加協(xié)議處理的消耗,但是提高了帶寬利用率,減少了無(wú)效重傳的消耗。可以在真實(shí)的環(huán)境中進(jìn)行測(cè)試這種機(jī)制的效果如何。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 國(guó)家電網(wǎng)公司企業(yè)標(biāo)準(zhǔn)(Q/GDW)- 面向?qū)ο蟮挠秒娦畔?shù)據(jù)交換協(xié)議 - 報(bào)批稿:20170802 前言: 排版 ...
    庭說(shuō)閱讀 12,355評(píng)論 6 13
  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,539評(píng)論 19 139
  • 實(shí)時(shí)消息協(xié)議---流的分塊 版權(quán)聲明: 版權(quán)(c)2009 Adobe系統(tǒng)有限公司。全權(quán)所有。 摘要: 本備忘錄描...
    一個(gè)人zy閱讀 2,063評(píng)論 0 9
  • 因?yàn)榭戳诉@部電影,突然心生一絲恐懼。恐懼自己從來(lái)都不曾真正感受這個(gè)世界,我不想總是自欺欺人,所以我寫(xiě)下這些話,只是...
    f的角落閱讀 602評(píng)論 0 1
  • 書(shū),怎么讀?通讀與精讀方法 閱讀是基本的學(xué)習(xí)方式之一,掌握正確的閱讀思考方法非常重要。 第一種,通讀:一年三百本以...
    Sam2013閱讀 440評(píng)論 0 0

友情鏈接更多精彩內(nèi)容