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

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

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

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

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

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

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









評(píng)論