1. 程式人生 > >英偉達tk1板的串列埠資料收發出錯問題

英偉達tk1板的串列埠資料收發出錯問題

最近在做一個專案,需要用到英偉達的tk1板做開發,其中利用到了tk1上的串列埠做開發。

其中遇到了一個隱藏的bug,在用tk1板傳輸資料時,tk1的驅動會把部分資料如連續的多格0或者0x11這類資料吃掉,到串列埠上讀的時候發現有遠比我要傳送的資料要少。

因為一開始做的時候,就知道串列埠資料錯亂是正常的,所以自己也在每一條訊息後面加了校驗。所以當這個問題出現的時候,我是沒有意識到問題會出現在串列埠驅動上面。

因為我們的tk1板為了適應產品,自己畫的電路板。所以也沒有第一時間定位是硬體問題還是驅動問題。後來在板上外接了usb轉串列埠,並且在上面復現了直連串口出現的問題後,才能肯定不是硬體問題。但是當時還沒有對這個bug的產生條件有充分的認識,只想著為了實現功能上的可靠性傳輸,我就自己仿製tcp協議棧編寫了一個低版本的可靠串列埠通訊協議,花了我一個星期做這個事情,只要有一次的資料傳輸對了就可以保證整個通訊的完整性。結果在完成了大部分之後,上板上跑起來,才發現一個重要的問題出現了,一次有效的資料包都沒有出現,一出現都是錯亂的,我開始針對這個問題嘗試進行修改,將一個報文複製三次拼接在一起傳送,結果三次接收的報文出現問題的地方是一致的,都是在連續的四個位元組的0後面的資料就亂了。彷彿抓到規律的我針對這一個現象進行了修正,既然連續的0有問題,而我的自定義協議中又要有0,那麼在組成資料包之後,傳送之前將每一個位元組都和一個定值進行異或操作,接收的時候也同樣進行異或操作,那麼在傳送的時候出現連續的0的可能性就大大的降低了,實際測試的時候發現通過率大大增加了,但是關鍵在於,沒通過的一定也通不過,同樣的也有問題,後來我又想了一下,將資料原來abcd的,我每個位元組擴充到原本的三倍,即aaabbbcccddd這樣,然後對第二個相同的數做一組異或,對第三個相同的數做另外一組異或,保證了即使傳輸同樣的位元組,出現的可能性更加低了,加上三次中兩次相同極為正確的校驗,效果強了很多,實際上測試也是這樣的,可是吃位元組的事情還在發生,我都快對這個驅動失望了。因為又發現了對與0x11這種資料都有大概率被吃掉。導致aaabbbcccddd會變化成為aabbbcccddd,一旦錯位,立馬gg了。最後發現對於可見字元編碼如a-zA-Z0-9的變異特效能少,於是我最終在校驗的基礎上添加了一成base64編碼的方式,這個問題總算被規避掉了,遇到不對的直接重發就好了