在將CAN數(shù)據(jù)導(dǎo)入應(yīng)用程序時發(fā)生丟失CAN幀的情況,通常是由于應(yīng)用程序花費太多時間處理某一報文,應(yīng)用程序暫停等待用戶交互,或者應(yīng)用程序正在等待共享系統(tǒng)資源,如數(shù)據(jù)文件等等。不管什么原因,應(yīng)用程序開發(fā)人員應(yīng)該計劃檢測這些丟棄的報文,以防止在由應(yīng)用程序行為導(dǎo)致錯誤時搜索系統(tǒng)問題。
為了檢測這個問題,CANlib提供了三種方法來檢查接收緩沖區(qū)狀態(tài)和確定CAN幀是否已經(jīng)丟棄:
?1.
用于確定CAN幀是否已被丟棄的第一種方法是監(jiān)視由canRead函數(shù)返回的標(biāo)志參數(shù)。標(biāo)志參數(shù)包含兩個位,它們表示在此函數(shù)調(diào)用和和當(dāng)前調(diào)用返回的最后一個報文之間是否發(fā)生軟件或硬件溢出。這些位被定義為用于硬件溢出的canMSGERR_HW_OVERRUN和用于軟件溢出的canMSGERR_SW_OVERRUN。你也可以使用canMSGERR_OVERRUN掩碼同時檢查這兩種情況。因此,當(dāng)應(yīng)用程序檢查到這些位集中的一個時,應(yīng)用程序就會獲知在當(dāng)前CAN幀和接收的前一個CAN幀之間丟棄了報文。
要了解在使用軟件的情況下如何顯示,可以假設(shè)一個接收緩沖區(qū),它可容納10幀(當(dāng)然,CANlib中的實際默認(rèn)接收緩沖區(qū)大小遠(yuǎn)大于10)。硬件已接收到10個CAN幀并將其放入可填入的緩沖區(qū)。

硬件接收到另一個CAN幀,但接收緩沖區(qū)已滿,因此該幀未添加到緩沖區(qū)。

硬件接收到第12個CAN幀,覆蓋未添加到緩沖區(qū)的幀。

應(yīng)用程序調(diào)用canRead刪除第一個接收的CAN幀,并為要添加到接收緩沖區(qū)的第12幀留下點。

第1到10的CAN幀在由canRead檢索時不會指示溢出。當(dāng)?shù)?1幀丟棄,通過canRead從緩沖區(qū)檢索時,第12個CAN幀將指示溢出。
?2.
canReadStatus
用于確定CAN幀是否已被丟棄的第二種方法是調(diào)用canReadStatus。如果設(shè)置了canSTAT_HW_OVERRUN或canSTAT_SW_OVERRUN位,該函數(shù)返回的標(biāo)志參數(shù)將指示溢出。你可以使用canSTAT_OVERRUN掩碼檢查這些溢出位是否已設(shè)置。
此狀態(tài)信息是異步更新的,意味著canReadStatus返回的值是最后一次報告的值,但不一定是當(dāng)前狀態(tài)。要確保報告的數(shù)據(jù)是最新的,你可以以周期性速率調(diào)用canRequestChipStatus。canRequestChipStatus要求更新狀態(tài)信息,但是函數(shù)退出時信息不是最新的。調(diào)用完成后將保持當(dāng)前的狀態(tài)一段時間。
所以讓我們拿前面的我們的完整的緩沖區(qū)以及硬件接收到第11個報文為例來說明。我們每秒調(diào)用canRequestChipStatus兩次,每秒調(diào)用一次canReadStatus。

此時canReadStatus不會指示溢出。當(dāng)硬件接收到第12個CAN幀覆蓋未添加到緩沖區(qū)的幀時,芯片狀態(tài)改變以指示溢出。

在下一個周期性canRequestChipStatus調(diào)用過程中報告該狀態(tài)開始。當(dāng)進(jìn)程完成時,下一次調(diào)用canReadStatus將指示溢出。這意味著根據(jù)第12個CAN幀在canRequestChipStatus和canReadStatus調(diào)用的周期中到達(dá)的時間,canReadStatus調(diào)用將不會在事件(在本例中)后最多一秒鐘指示狀態(tài)。
一旦在canReadStatus調(diào)用的標(biāo)志參數(shù)中指示溢出,狀態(tài)將保持鎖定狀態(tài),直到你使用canIOCtl例程與canIOCTL_CLEAR_ERROR_COUNTERS函數(shù)清除狀態(tài)。這是為了防止應(yīng)用程序由于檢查到溢出和使用canReadStatus例程輪詢狀態(tài)之間的競爭情況而丟棄檢測到的溢出。
03.
請求接收緩沖區(qū)級別
第三種方法是通過使用函數(shù)參數(shù)設(shè)置為canIOCTL_GET_RX_BUFFER_LEVEL的canIoCtl例程來監(jiān)視接收緩沖區(qū)的當(dāng)前深度。返回的緩沖區(qū)將是當(dāng)前存儲在接收緩沖區(qū)中的CAN幀的計數(shù)。
請記住,有時候與其把時間花費在檢查緩沖區(qū)級別,不如花點時間清空接收緩沖區(qū)。在執(zhí)行預(yù)定義塊傳輸時,檢查接收緩沖區(qū)級別可能更有用,其中應(yīng)用程序可以等待直到在處理幀之前接收到整個塊。
注意事項
你可能會注意到,當(dāng)使用第二、三個方法(canReadStatus或canIOCTL_GET_RX_BUFFER_LEVEL)時,如果緩沖區(qū)已滿并處于溢出狀態(tài),那么在接下來的canRead調(diào)用中指示溢出狀態(tài)。要在這些方法中檢索數(shù)據(jù),接收隊列必須置于穩(wěn)定狀態(tài),以便檢查整個隊列。在此過程中,由于空間不足,報文可能在驅(qū)動程序和應(yīng)用程序緩沖區(qū)之間被丟棄。這種丟棄由使用canRead檢索的下一個CAN幀的溢出狀態(tài)表示。
要點總結(jié)
應(yīng)用程序開發(fā)人員應(yīng)該在canRead()處理期間始終檢測丟棄的報文,以防止在由應(yīng)用程序行為導(dǎo)致錯誤時搜索系統(tǒng)問題。你的應(yīng)用程序設(shè)計可能會對CAN總線上的流量造成問題,這是你的第一條指示。使用此方法進(jìn)行監(jiān)視將有助于在握手報文丟棄或預(yù)期的周期性報文超時時,確定故障發(fā)生在何處。雖然你可以使用單獨的工具來監(jiān)視總線上所需的報文,但監(jiān)視溢出標(biāo)志將指示你的應(yīng)用程序節(jié)點是最終原因或至少有風(fēng)險。
你可以使用canRead溢出信息來跟蹤溢出的頻率。當(dāng)流量帶寬由于報文突發(fā)而增加時,這可以識別應(yīng)用的可能問題。
當(dāng)在GUI上指示當(dāng)前溢出狀態(tài)或向用戶發(fā)出重要報文可能已被丟棄的警告時,使用canReadStatus方法。
當(dāng)你愿意停止GUI或其他進(jìn)程時,將使用檢查接收緩沖區(qū)級別,以便在達(dá)到特定大小后專門計算資源立即清空緩沖區(qū)——防止發(fā)生溢出。一個這樣的情況是閃爍節(jié)點。
審核編輯:劉清
電子發(fā)燒友App









評論