1、簡介
最近在給客戶完成電機預(yù)測性維護類的 POC 項目時,使用 Keil 編譯器時遇到了一個 NEAI 庫的異常,在和歐洲 NEAI 團隊調(diào)查過程中發(fā)現(xiàn)了比較奇怪的 BUG,本文將介紹該問題發(fā)生的條件和后續(xù)的規(guī)避方法。
2、項目介紹
該項目是和電機相關(guān)的預(yù)測性維護項目,需要模擬一些異常的情況,然后使用 NEAI 進行建模和部署。然后采集正常和異常的數(shù)據(jù),使用 NEAI 的 Abnormal detection 類方法,進行訓(xùn)練,訓(xùn)練完成后進行部署。
3、發(fā)生異常
發(fā)生異常是在部署的時候,使用 neai_anomalydetection_detect 這個 API 的返回值發(fā)生了異常。該函數(shù)使用 input_user_buffer 中的數(shù)據(jù),進行推理,然后將結(jié)果返回到 similarity 變量中。similarity 變量的值范圍為 0~100,表示 input_user_buffer 中的數(shù)據(jù)和正常數(shù)據(jù)相比相似度大概是多少,通過這個返回結(jié)果,可以判斷設(shè)備運轉(zhuǎn)是正常還是異常。但是在實際部署測試的時候,發(fā)現(xiàn) similarity 變量的值有時候會超過 100,明顯是一個不合理的值。
4、調(diào)試過程
該問題非常隱蔽和難以發(fā)現(xiàn),歐洲 NEAI 開發(fā)團隊的同事也花了非常多的精力才定位到發(fā)現(xiàn)問題的點,目前正在執(zhí)行 NEAI 庫中的 log 函數(shù),其中 S0 的值 0.046875 是正確的值,此時單步執(zhí)行下一步匯編代碼中的 VMOV 將 R0 的值移到了 S0,導(dǎo)致 S0 的值不正確,變?yōu)橐粋€非常小的值 1.08577e-19。
5、異常原因
發(fā)生異常的原因,主要是因為在執(zhí)行 log 函數(shù)前一個錯誤的 VMOV 指令,而為什么會生成錯誤的 VMOV 指令,貌似和使用的編譯器有關(guān)。后續(xù)又進行了一些對比測試,使用 gcc 編譯器編譯該段代碼,發(fā)現(xiàn)沒有問題。NEAI 團隊使用了源碼+Keil 編譯器進行編譯,也沒有問題。唯獨使用 Lib+Keil 編譯器會出現(xiàn)該問題。NEAI 團隊進一步對代碼進行了簡化分析,發(fā)現(xiàn)只要使用 lib 鏈接的方式+Keil ARMv6 的編譯器,并使用 log 函數(shù)時,就會復(fù)現(xiàn)該問題。至此幾乎可以斷定,該問題是由 Keil 鏈接器導(dǎo)致的,NEAI 團隊后續(xù)會聯(lián)系 ARM 團隊并反饋該問題。
6、規(guī)避方法
總結(jié)以上,規(guī)避的方法就很明確了:
- 使用源碼編譯。(但客戶幾乎無法獲取 NEAI 庫的源碼)
- 避免使用 Keil。
- 請 NEAI 團隊幫忙編譯。