山東航天電子技術(shù)研究所 都曉輝 曹振興
本文介紹了一種以80C32E為核心,具備上注功能的單片機系統(tǒng),軟件在編譯生成上注代碼后,上注代碼在EEPROM運行異常情況,通過對上注代碼運行異常進行分析研究,最終找出由于編譯器優(yōu)化造成部分功能失效的原因,并進行了總結(jié)。
某單片機程序采用固化程序加上注代碼的執(zhí)行模式,若軟件發(fā)現(xiàn)問題可通過上注代碼對部分代碼功能進行更改,本案例說明由于在對上注代碼的制作過程中編譯器優(yōu)化造成上注代碼執(zhí)行部分功能失效的問題。硬件框圖見圖1;
圖1 硬件框圖
80C32系統(tǒng)的硬件結(jié)構(gòu)如圖1所示,包括單片機80C32、ROM、RAM、EEPROM1、EEPROM2和總線接口。ROM、RAM、EEPROM1、EEPROM2和總線接口均與單片機80C32互連。80C32系統(tǒng)上電后運行ROM中的固化程序,根據(jù)需要,可通過總線接口向80C32系統(tǒng)發(fā)送上注程序,并將上注程序?qū)懭隕EPROM1、EEPROM2和RAM中,當系統(tǒng)接收到執(zhí)行上注程序的指令后,執(zhí)行EEPROM中的上注程序。
某軟件在按照部門的統(tǒng)一要求將上注代碼做成完全上注模式后確認測試時發(fā)現(xiàn)在運行上注程序時,發(fā)現(xiàn)部門程序功能失效,運行結(jié)果和預(yù)期不一致。
注:完全上注模式,將在固化程序中出現(xiàn)的軟件功能在上注代碼中全部實現(xiàn)。在上注代碼制作過程中將主程序中MAIN函數(shù)中出現(xiàn)的函數(shù)、變量、標志等定位到與固化程序相同的地址上,所出現(xiàn)的函數(shù)只保留函數(shù)皮(函數(shù)中無內(nèi)容),程序切換到上注執(zhí)行模式后將跳至上注代碼模塊。
上注代碼中選用主程序中的相應(yīng)功能代碼,注入到上注程序區(qū)。為了進一步分析問題將上注代碼上注后將EEPROM中的數(shù)據(jù)讀出,與上注的代碼進行比對,通過比對發(fā)現(xiàn)兩者一致,排除代碼上注的過程中某環(huán)節(jié)出現(xiàn)問題將上注代碼改寫的情況。進而對固化程序和上注代碼的C和編譯生成的匯編代碼進行檢查比對如下。
表1 上注代碼C程序及對應(yīng)匯編
表2 固化程序中C代碼及對應(yīng)匯編
通過比對發(fā)現(xiàn)固化程序比上注程序在退出函數(shù)后將DPTR的值進行了重新賦值(恢復(fù)到標志位的地址)而上注代碼部分則無。(粗斜體部分)
在固化程序中對JMJDataPack()、XJDataPack()、GPSDataPack()三模塊進行查看發(fā)現(xiàn)在函數(shù)內(nèi)多次對DPTR的值進行改寫,退出后對DPTR的值進重新賦值,而在上注程序運行的過程中調(diào)用固化程序相應(yīng)的模塊,結(jié)果跳出相應(yīng)的模塊后,DPTR的值未重新賦值,將對應(yīng)的錯誤的地址值進行改寫,未能實現(xiàn)正確的標志位改變功能,致使出現(xiàn)相對應(yīng)的功能實現(xiàn)不了,在此過程中編譯器編譯出了問題。
分析和試驗發(fā)現(xiàn)編譯器在編譯固化程序時由于JMJDataPack()、XJDataPack()、GPSDataPack()函數(shù)中多次將DPTR的值進行改寫,因此在退出上述函數(shù)后編譯器將標志位的地址重新賦值給DPTR,再對該地址的值進行修改,而編譯器在編譯上注程序時由于上述函數(shù)使用的是空函數(shù)(上注程序中函數(shù)對應(yīng)的地址與固化程序一一對應(yīng),無函數(shù)內(nèi)容),沒有對DPTR進行更改,配置環(huán)境在8級優(yōu)化的情況下編譯器在編譯的過程中將優(yōu)化處理(“窺孔”優(yōu)化,不必要的從存儲器裝入對象及裝入常數(shù)的操作)不對DPTR 的值進行重新賦值,造成上述現(xiàn)象的發(fā)生。在“Options選項/C51標簽頁/Code Optimization欄/Leve框”內(nèi)選取優(yōu)化級別。OPTIMIZE命令設(shè)置優(yōu)化級別和優(yōu)化重點,共有9個優(yōu)化級別,高優(yōu)化級別中包含了前面所有的底優(yōu)化級別。
現(xiàn)在的程序編譯過程中均采用8級優(yōu)化,由于高優(yōu)化級別中包含了前面所有的底優(yōu)化級別,因此編譯器在對上注代碼模塊編譯時將重復(fù)的DPTR賦值操作去掉,造成上述現(xiàn)象的發(fā)生。
針對該問題有目前三種解決方法:
當前固化程序和上注代碼KEILC在環(huán)境配置時選用的8級優(yōu)化,將上注代碼環(huán)境配置優(yōu)化級別選為2級,即不對代碼進行“窺孔”優(yōu)化。
更改上注代碼如下:
將fgYKManage = FALSE; fgGBManage = FALSE;分別放到XJDataPack()和GPSDataPack()函數(shù)內(nèi)。
在使用相應(yīng)的工具進行編程時,尤其是對具有代碼優(yōu)化功能的編譯軟件的環(huán)境配置應(yīng)特別注意,其某些優(yōu)化功能可能會造成對某些代碼的功能出錯,在用之前一定要對相應(yīng)的優(yōu)化內(nèi)容和規(guī)則有深刻了解。在代碼完成后還要加強代碼的各項確認測試工作,認真核對每一項功能是否有偏差,仔細認真的比對每一項指標。