zhuan 串列埠成幀協議

2021-07-10 08:30:16 字數 2492 閱讀 3618

串列埠成幀協議

串列埠接收中的問題

在電子系統中,最簡單、最廣泛的通訊方式無疑是串列埠了,幾乎所有與模組相關的產品,差不多都有串列埠的操作方式,如串列埠藍芽模組、串列埠wifi模組、串列埠zigbee模組、串列埠語音模組等。不僅是這樣,在嵌入式開發中,很多時侯除錯離不開串列埠,韌體公升級離不開串列埠,可見搞電子的人如果不能很好的操作串列埠,那就真是說不過去了。

串列埠的應用場合非常多,但是有乙個殘酷的現實擺在我們面前,那就是通訊問題。我們知道串列埠傳送資料時是面向位元組的,接收方接收資料時也是面向位元組的,而在實際應用中,收發資料往往都是面向幀的,這樣往往會對接收方接收資料造成一定的困難。舉個例子吧,乙個微控制器系統通過串列埠往pc機傳送一幀100位元組資料,但是pc機在呼叫系統api來接收資料時,往往不能一次性接收完100位元組,可能第一次接收5位元組,第二接收10位元組……,雖然最後都能收到100位元組。如果微控制器傳送兩幀資料,並且這兩幀資料之間的時間間隔非常短,那pc就無法區別出兩幀資料的邊界了。初入行的人或許會想到一些諸如增加標誌位、判斷時間等方法來解決這個問題,但不夠嚴謹的。所以我們有必要設計乙個相對可靠一點的串列埠成幀的方法來解決接收難題。

也許搞技術的人,或多或少都聽說過網路通訊的osi模型,標準的osi模型有7層之多,像串列埠這種簡單的通訊,並不需要這麼多層的實現,但是至少要實現鏈路層,才能解決資料組幀問題。很多人之所以在接收串列埠資料時出現困難就是因為從物理層接收資料之後,直接提交給應用層,這樣應用層必然是面向位元組的,通訊方式是如下形式:

物理層 –>> 應用層

在這裡,我們要做的是在物理層與應用層之間插入乙個鏈路層,也即osi模型的第二層,本文要描述的就是這個鏈路層的協議,通訊方式會變成如下形式:

物理層 –>> 鏈路層 –>> 應用層

由於大部分人都習慣於直接操作串列埠,所以鏈路層只需要實現最基本的組幀功能即可,沒有必要搞的那麼複雜。這裡鏈路層的功能負責將物理層的位元組資料,按照一定規則封裝成幀,然後提交給應用層,這樣應用層接收的便是完整的一幀資料,而不是零零散散的位元組資料。

那麼鏈路層使用什麼樣的方法來進行封裝會比較好呢,這裡可以效仿網路通訊協議中一些知名協議的做法,比如slip、ppp協議等,這些協議的鏈路層都是通過轉義的方法來組幀。因此,我們的串列埠成幀協議也是使用轉義的方法,但是要說明一點,這裡只提供一種組幀的方法,任何可靠性的問題如檢測、糾錯等必須由上層來實現。

串列埠成幀鏈路層組幀規則如下:

1、首先我們要定義三個特殊字元:幀起始標誌sof,用0x7d表示;幀結束標誌eof,用0x7e表示、轉義標誌esc表示0x7f。資料幀封裝格式如下表所示:

串列埠鏈路層幀格式

網域名稱稱 描述

sof 幀起始標誌,固定為0x7d,sof是start of frame的英文編寫

data 要傳輸的資料,串列埠資料建議在512位元組以內為宜。

eof 幀結束標誌,固定為0x7e,eof是end of frame的英文縮寫

2、由資料幀的封裝格式中可以看出,0x7d和0x7e是幀的起始和末尾標誌,那要是data中要傳輸0x7d和0x7e怎麼辦呢,這就需要進行轉義了,我們定義了乙個轉義字元esc,用0x7f 表示。當傳送資料時,需要將資料域中的0x7d用0x7f 、0x00兩字元替代、這就是所謂的轉義,同樣的,傳送方將資料中的0x7e轉義為0x7f、0x01,將0x7f轉義成0x7f、0x02。對於接收方可以按照這樣的規則對資料進行還原。轉義字元表總結如下:

0x7d –>> 0x7f、0x00

0x7e –>> 0x7f、0x01

0x7f –>> 0x7f、0x02

以上兩點就是鏈路層的規則,規則雖然簡單,但是對於組幀卻非常有用,而且不會產生歧義。

樣例一:

應用層傳送資料:0x55 0x66 0x88 0x99

資料經過鏈路層之後,實際傳送資料:0x7d 0x55 0x66 0x88 0x99 0x7e

從這裡可以看出,接收方根據起始標誌0x7d和末尾標誌0x7e很容易提取出實際資料0x55 0x66 0x88 0x99

樣例二

應用層傳送資料:0x55 0x7d 0x88 0x99

資料鏈路層傳送資料:0x7d 0x55 0x7f 0x00 0x88 0x99 0x7e

這裡可以看出,應用層傳送資料中是包含了起始標誌0x7d,但是在鏈路層就被轉義成了0x7f、0x00,接收方連續收到0x7f、0x00就能還原為0x7d。

樣例三

應用層傳送資料:0x55 0x7f 0x00 0x99

資料鏈路層傳送資料:0x7d 0x55 0x7f 0x02 0x00 0x99 0x7e

從上面三個例子中可以看出,傳送的資料幀的資料域中是不可能出現0x7d和0x7e這兩個字元的,因為鏈路層已經對它進行了轉義,所以接收方一旦接收到0x7d就可以斷定這是一幀的開始,接收到0x7e就表示一幀的結束,而0x7d與0x7e之間的資料就是傳送方的資料內容,接收方需要在鏈路層將被轉義的字元還原,然後再提交給應用層。

這麼一來,就解決了資料成幀的問題。串列埠之間的通訊由面向位元組通訊變成了面向幀的通訊,也就是說應用層資料不再是以位元組為單位,而是以幀為單位。好比微控制器傳送一幀100位元組的資料給pc,pc應用程式接收的便是一幀100位元組的資料了。

linux 串列埠 拼幀處理

串列埠每次read資料可能不是完整的資料,參照網上的 寫了拼幀的 include include include include include include include int speed arr int name arr brief set serial port bitrate para...

becon幀 wifi Wi Fi協議幀結構詳解1

要想理解wi fi的真正工作原理,除了了解前面我寫的wi fi網路結構,網路連線過程,還需要詳細了解wi fi的幀結構。wi fi幀的分類 wi fi的幀從大類上分為三類 1.資料幀 資料幀,顧名思義,就是我們在聯網中要傳輸的資料,就好比公路運輸中要運輸的貨物。2.控制幀 功能 控制幀通常與資料幀搭...

TCP IP協議 各層協議幀格式

一 1 osi與tcp ip對應 tcp ip各層功能 鏈路層 包括作業系統的裝置驅動程式和計算機的網絡卡,提供底層傳輸服務。網路層 為資料選擇路由,在眾多計算機和網路裝置組成的網路中選擇一條傳輸路線進行傳輸。傳輸層 提供兩台主機端對端的通訊服務,進行傳輸控制。應用層 複製應用程式的特定處理。3 協...