一直在使用stm32型別的mcu進行設計。今天遇到了乙個很奇怪的問題,有幸讓我管中窺豹,了解了一些bxcan中的處理機制————前記
更多這兩天趕專案,需要完成乙個需求,將接收到的資料進行歸類存放到不同的記憶體位置中。並且需要一定程度的資訊互動(總傳輸資訊的10%左右)。而且使用了較為靈活的資料處理方式,這個不(shi)便(ge)細(tian)表(keng)。
當然,雖然這個較為靈活的資料處理方式花了我90%左右的時間進行處理,但是索性還是完成了。有了較為穩妥的實現方式,而且也點通了另一項技能:c#,但是過程十分艱辛。
好了,扯回正題,專案昨天完成一期,順利交付。今天我在進行原本程式的公升級過程中意外的發現了當前傳輸網路(can)竟然詭異的出現了不應該出現的應答幀。
當前環境下,裝置和上位機互動過程中只會有兩個標準幀進行傳輸,而在pcan-basic裡面卻出現了第三個不應該出現的,前面專案完成的幀傳輸中的應答幀。這個應答幀為擴充套件幀格式,且看幀的資料場說明其已經進入了正常的返回邏輯。也就是說,在裝置和上位機互動過程**現了第二個上位機與裝置進行互動!
電子產品遵循著唯物主義精神,不可能有什麼未知的裝置進行互動,所以我果斷猜想是否是當前傳輸的can幀格式出現了一些問題?
本著這個猜想,我在程式中加入了一些反饋訊號,以觀察現有的程式邏輯是否出現了錯誤。而經過了一番仔細的檢查之後發現,並沒有什麼接收邏輯上面的錯誤,這又讓我十分驚異。也讓問題陷入了乙個僵局。
現在已經確定了接收邏輯沒有任何問題,而為何會接收到這種沒有任何傳送可能的can幀呢?我仔細分析了一下:can匯流排邏輯錯誤;bxcan出現功能性錯誤;上位機傳送失誤;控制端還有不明裝置正在傳送資料只是我忘記了。
can匯流排可以正常完成傳輸–>儲存的邏輯,說明其沒有錯誤,而且因為上位機開發過早,出現故障的id當初沒有寫入,所以也不可能是上位機的隱式傳送。控制端經過嚴密排查,確認沒有任何可能傳送額外can幀的軟體或者裝置,且pcanbasic也沒有檢測到可能傳送的意外的can幀。剩下的就是bxcan出現功能性錯誤了,這個十分難以驗證,不過我還是想試試。
為了證明我的猜想的正確性,我在接收can中斷函式中增加了關於當前can幀郵箱資料的列印輸出,以觀察當前can幀是否出現了異常。經過分析列印的can幀發現,的確在某個時刻,會出現接收到乙個不應該出現的can幀的情況,而且那次的can幀內容也會出現一些偏差。但是那一幀的標準幀id是正確的。這也就側面的證明了bxcan確實算是罪魁禍首!
找到了問題自然也就很快有了解決的辦法,我在每次處理完can資料之後有就會將郵箱直接清空,就不會出現這種奇怪的現象了。
memset
(canrxmessage,
0x00
,sizeof
(canrxmessage));
/* 直接清空當前can接收郵箱 */
這樣就可以了,建議盡快清空以免出現問題。
解決了問題,為了證明自己是攻城獅而不是碼農民工,我仔細的想了一下這個問題的原因。
也許在設計bxcan之初,設計者沒有想到當乙個can網路中竟然會出現兩種不一樣幀格式的情況(事實上這個真的也不科學,但是還是會有這種極端情況的,畢竟現場不是實驗室)。在當前接收模組中使用了並行解碼直接將接收到的can幀解碼為標準幀與擴充套件幀的兩種格式,然後直接傳送中斷請求請求上層接收。這樣帶來的好處是響應時間大大加快(硬體判斷幀格式十分複雜),而代價則為在開啟了標準幀過濾和擴充套件幀過濾之後極易出現識別錯誤。所以這種錯誤出現的場景很小:短時間內大量標準幀資料接收,接收裝置需要同時開啟標準幀和擴充套件幀,接收資料幾乎全為標準幀。
因為在大量隨機資料的傳輸過程中,極有可能因為編碼格式的不同導致標準幀id + 資料 == 擴充套件幀id的碰撞出現。且在樣本容量很大的情況下出現碰撞的機率會很高(測試10w的can幀出現了100+次),雖然幾乎不可能出現碰撞資料正好為正確資料,但是在整車上會有數以千記的can裝置,難免出現一定概率的問題。而經過及時的清理,則出現錯誤can幀的情況大大減小(測試10w的can幀出現了0次)。
以上僅為猜測,沒有硬體電路支撐,如有錯誤請求賜教。言語攻擊直接pass。
記一次Android Studio編譯異常
最近電腦總是藍屏,所以重灌了一次win7系統,然後重新安裝android studio,然後發現在build的時候一直報乙個錯誤 a failure occurred while executing com.android.build.gradle.tasks.mergeresources file...
記一次xxljob異常排查
我們使用開源的xxljob封裝了乙個job服務作為平台的job元件。有乙個專案組生產上總是隔些天就會有一次異常發生,排程失敗,且沒什麼報錯資訊。jobadmin 執行器服務都是三颱伺服器集群部署,且資料庫是三颱集群讀寫分離部署。後排查發現如下 失敗的那次任務時間點上排程時,執行器服務列表是空的,導致...
記一次keepalived的異常問題
背景 2019一月份我對我們專案的開發環境及測試環境,做了一次資料庫災備及高可用方案,mysql採用的是主主複製 keepalived機制 虛擬ip採用的是 225 mongodb採用的是複製集模式。問題 從1月20號上測試環境至3月27都沒出現任何問題。結果3月28日早上,相繼有人告訴我,虛擬ip...