應用方案設計中,開發者經常會碰到某個子函數需要多次多級調用的情況。程序執行過程中有可能打斷本該順序執行的指令轉而跨層執行其他層級指令的情況,為了說明方便,將主循環程序作為一層,不同的中斷服務程序各自為一層。
一、現象描述
keil編譯器編譯code后,經常會遇到如下warning:[*** WARNING L15:MULTIPLE CALL TO SEGMENT ],碰到此warning就是編譯器提醒開發者,不同層級出現調用同一子函數的情況,或者主循環與中斷服務中都有調用,或者不同中斷服務程序中都有調用。
二、注意事項分析
1)全局變量有可能被非可控篡改。
同一子函數在不同層同時調用,那如果在當前層執行此函數時被臨時打斷跨層后同樣執行此函數,那此子函數中的變了就有可能出現主循環中此子函數調用的變了出現非需求改變。
出錯舉例:鍵盤應用中,主循環和中斷中都調用USB上報鍵值的子函數,如下:
當主循環剛好在執行這個子函數時,出現中斷,轉而去執行中斷服務程序,而中斷服務程序中也執行這個子函數的時候。buffer_addr(xdata全局指針變量)的數據就將被填充成非正常的狀態,整程序運行就會出錯。
2)局部變量和全局變量全被非可控篡改。
KEIL編譯器在順序分配局部變量地址時,不同層級臨時變量分配地址不會復用,但同層級調用的子函數分配局部變量的地址時可能是相同的,舉個簡單的例子
如上:
delay_us()和pwm_control_led_mode1()在主循環中調用,KEIL編譯器可能將兩個函數中的臨時變量i(不局限同名)分配到同一個RAM地址中,如果子函數同層級調用時不會有問題的,因為函數都是順序執行的。
同樣是上述兩個函數,delay_us()在timer0中斷服務程序中調用, pwm_control_led_mode1()在主循環和timer0中斷服務程序中都有調用,那編譯器有可能將delay_us()和pwm_control_led_mode1()判定為同層級(中斷服務),那臨時變量i就有可能分配為同一RAM地址。
此時如果主循環在pwm_control_led_mode1()函數中執行到i=10時timer中斷發生,程序被打斷進入中斷服務程序,中斷執行delay_us()函數后i=500后回到主循環,因為兩個子函數中臨時變量i在RAM中的地址是公用的,所以回到主循環pwm_control_led_mode1()繼續執行時,其臨時變量i的值已經是500了,變量led_status_temp[i]可能會因為i值溢出導致賦值的數據被賦值到非led_status_temp變量存儲驅導致程序中變量出錯。
三、解決辦法建議
出現[*** WARNING L15:MULTIPLE CALL TO SEGMENT ]warning的時候,程序都是存在潛在風險的,最徹底的改善就是從程序架構上避免出現不同層級重復調用的情況。當然正式應用方案中可能會因為空間大小或者其他原因不得不重復調用同一子函數的情況,針對此種情況,推薦幾種規避方式,僅供讀者參考
1)執行子函數關中斷法
程序開發中,出現多層調用的情況一般就是兩種情況,一是主循環跟中斷服務程序中重復調用,另外就是不同中斷服務程序中同時調用,經過上面分析,但凡出問題時,都是在執行被重復調用的子函數時打斷去執行其他層指令,要徹底解決出問題的可能,只需在執行低優先級層(比如主循環)同一子函數之前關中斷,執行完此子函數后再開中斷就可解決所以可能存在的問題。
說明:有一種情況雖然會這個warning,但不會出問題,比如在不同的中斷服務程序中掉用同一個子函數,但是中斷的優先級同級,也就是不存在嵌套的情況。
優點:簡單便捷,徹底解決問題。
缺點:有些應用中因為時序的問題,不允許臨時關中斷。
2)子函數copy改名法
就是重復調用的子函數,copy一份改一下函數名稱,分別給不同層級調用,這樣waring也會消失。
優點:簡單,不存在臨時變量被改的情況
缺點:仍然存在全局變量同時操作并被修改的情況,需要設計者注意是否會存在執行此子函數時臨時中斷換層又執行到此子函數的情況。
3)臨時變量不復用法
在開發者確定不會存在執行此子函數時臨時中斷換層又執行到此子函數的情況(全局變量篡改)下,可配置KEIL編譯器,使編譯器給臨時變量分配地址時,每個臨時變量占用一個地址,不復用。配置方式如下:
編譯器中嵌入這個NOOVERLAY命令,意思是臨時變量不復用RAM地址
優點:可簡單方便解決臨時變量篡改導致的問題。
缺點:增加RAM的使用量。
說明:如果重復調用的子函數臨時變量很少,不妨就將子函數中的臨時變量直接定義成全局變量,這樣不至于增加太多的RAM空間。
結束語:
上述推薦的方法只是一點建議,必定還有很多辦法可以解決這類問題,個人認為最重要的是慎重處理此warning,并明確其存在的風險和內在邏輯,至于如何解除應用風險,每個人每個方案的做法可以根據實際情況處理。
審核編輯:劉清
-
RAM
+關注
關注
8文章
1367瀏覽量
114528 -
變量
+關注
關注
0文章
613瀏覽量
28329
原文標題:子函數多層調用主要事項
文章出處:【微信號:SINO_25181447,微信公眾號:中穎電子】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論