應(yīng)用方案設(shè)計(jì)中,開發(fā)者經(jīng)常會碰到某個(gè)子函數(shù)需要多次多級調(diào)用的情況。程序執(zhí)行過程中有可能打斷本該順序執(zhí)行的指令轉(zhuǎn)而跨層執(zhí)行其他層級指令的情況,為了說明方便,將主循環(huán)程序作為一層,不同的中斷服務(wù)程序各自為一層。
一、現(xiàn)象描述
keil編譯器編譯code后,經(jīng)常會遇到如下warning:[*** WARNING L15:MULTIPLE CALL TO SEGMENT ],碰到此warning就是編譯器提醒開發(fā)者,不同層級出現(xiàn)調(diào)用同一子函數(shù)的情況,或者主循環(huán)與中斷服務(wù)中都有調(diào)用,或者不同中斷服務(wù)程序中都有調(diào)用。
二、注意事項(xiàng)分析
1)全局變量有可能被非可控篡改。
同一子函數(shù)在不同層同時(shí)調(diào)用,那如果在當(dāng)前層執(zhí)行此函數(shù)時(shí)被臨時(shí)打斷跨層后同樣執(zhí)行此函數(shù),那此子函數(shù)中的變了就有可能出現(xiàn)主循環(huán)中此子函數(shù)調(diào)用的變了出現(xiàn)非需求改變。
出錯(cuò)舉例:鍵盤應(yīng)用中,主循環(huán)和中斷中都調(diào)用USB上報(bào)鍵值的子函數(shù),如下:
當(dāng)主循環(huán)剛好在執(zhí)行這個(gè)子函數(shù)時(shí),出現(xiàn)中斷,轉(zhuǎn)而去執(zhí)行中斷服務(wù)程序,而中斷服務(wù)程序中也執(zhí)行這個(gè)子函數(shù)的時(shí)候。buffer_addr(xdata全局指針變量)的數(shù)據(jù)就將被填充成非正常的狀態(tài),整程序運(yùn)行就會出錯(cuò)。
2)局部變量和全局變量全被非可控篡改。
KEIL編譯器在順序分配局部變量地址時(shí),不同層級臨時(shí)變量分配地址不會復(fù)用,但同層級調(diào)用的子函數(shù)分配局部變量的地址時(shí)可能是相同的,舉個(gè)簡單的例子
如上:
delay_us()和pwm_control_led_mode1()在主循環(huán)中調(diào)用,KEIL編譯器可能將兩個(gè)函數(shù)中的臨時(shí)變量i(不局限同名)分配到同一個(gè)RAM地址中,如果子函數(shù)同層級調(diào)用時(shí)不會有問題的,因?yàn)楹瘮?shù)都是順序執(zhí)行的。
同樣是上述兩個(gè)函數(shù),delay_us()在timer0中斷服務(wù)程序中調(diào)用, pwm_control_led_mode1()在主循環(huán)和timer0中斷服務(wù)程序中都有調(diào)用,那編譯器有可能將delay_us()和pwm_control_led_mode1()判定為同層級(中斷服務(wù)),那臨時(shí)變量i就有可能分配為同一RAM地址。
此時(shí)如果主循環(huán)在pwm_control_led_mode1()函數(shù)中執(zhí)行到i=10時(shí)timer中斷發(fā)生,程序被打斷進(jìn)入中斷服務(wù)程序,中斷執(zhí)行delay_us()函數(shù)后i=500后回到主循環(huán),因?yàn)閮蓚€(gè)子函數(shù)中臨時(shí)變量i在RAM中的地址是公用的,所以回到主循環(huán)pwm_control_led_mode1()繼續(xù)執(zhí)行時(shí),其臨時(shí)變量i的值已經(jīng)是500了,變量led_status_temp[i]可能會因?yàn)閕值溢出導(dǎo)致賦值的數(shù)據(jù)被賦值到非led_status_temp變量存儲驅(qū)導(dǎo)致程序中變量出錯(cuò)。
三、解決辦法建議
出現(xiàn)[*** WARNING L15:MULTIPLE CALL TO SEGMENT ]warning的時(shí)候,程序都是存在潛在風(fēng)險(xiǎn)的,最徹底的改善就是從程序架構(gòu)上避免出現(xiàn)不同層級重復(fù)調(diào)用的情況。當(dāng)然正式應(yīng)用方案中可能會因?yàn)榭臻g大小或者其他原因不得不重復(fù)調(diào)用同一子函數(shù)的情況,針對此種情況,推薦幾種規(guī)避方式,僅供讀者參考
1)執(zhí)行子函數(shù)關(guān)中斷法
程序開發(fā)中,出現(xiàn)多層調(diào)用的情況一般就是兩種情況,一是主循環(huán)跟中斷服務(wù)程序中重復(fù)調(diào)用,另外就是不同中斷服務(wù)程序中同時(shí)調(diào)用,經(jīng)過上面分析,但凡出問題時(shí),都是在執(zhí)行被重復(fù)調(diào)用的子函數(shù)時(shí)打斷去執(zhí)行其他層指令,要徹底解決出問題的可能,只需在執(zhí)行低優(yōu)先級層(比如主循環(huán))同一子函數(shù)之前關(guān)中斷,執(zhí)行完此子函數(shù)后再開中斷就可解決所以可能存在的問題。
說明:有一種情況雖然會這個(gè)warning,但不會出問題,比如在不同的中斷服務(wù)程序中掉用同一個(gè)子函數(shù),但是中斷的優(yōu)先級同級,也就是不存在嵌套的情況。
優(yōu)點(diǎn):簡單便捷,徹底解決問題。
缺點(diǎn):有些應(yīng)用中因?yàn)闀r(shí)序的問題,不允許臨時(shí)關(guān)中斷。
2)子函數(shù)copy改名法
就是重復(fù)調(diào)用的子函數(shù),copy一份改一下函數(shù)名稱,分別給不同層級調(diào)用,這樣waring也會消失。
優(yōu)點(diǎn):簡單,不存在臨時(shí)變量被改的情況
缺點(diǎn):仍然存在全局變量同時(shí)操作并被修改的情況,需要設(shè)計(jì)者注意是否會存在執(zhí)行此子函數(shù)時(shí)臨時(shí)中斷換層又執(zhí)行到此子函數(shù)的情況。
3)臨時(shí)變量不復(fù)用法
在開發(fā)者確定不會存在執(zhí)行此子函數(shù)時(shí)臨時(shí)中斷換層又執(zhí)行到此子函數(shù)的情況(全局變量篡改)下,可配置KEIL編譯器,使編譯器給臨時(shí)變量分配地址時(shí),每個(gè)臨時(shí)變量占用一個(gè)地址,不復(fù)用。配置方式如下:
編譯器中嵌入這個(gè)NOOVERLAY命令,意思是臨時(shí)變量不復(fù)用RAM地址
優(yōu)點(diǎn):可簡單方便解決臨時(shí)變量篡改導(dǎo)致的問題。
缺點(diǎn):增加RAM的使用量。
說明:如果重復(fù)調(diào)用的子函數(shù)臨時(shí)變量很少,不妨就將子函數(shù)中的臨時(shí)變量直接定義成全局變量,這樣不至于增加太多的RAM空間。
結(jié)束語:
上述推薦的方法只是一點(diǎn)建議,必定還有很多辦法可以解決這類問題,個(gè)人認(rèn)為最重要的是慎重處理此warning,并明確其存在的風(fēng)險(xiǎn)和內(nèi)在邏輯,至于如何解除應(yīng)用風(fēng)險(xiǎn),每個(gè)人每個(gè)方案的做法可以根據(jù)實(shí)際情況處理。
審核編輯:劉清
-
RAM
+關(guān)注
關(guān)注
8文章
1368瀏覽量
114682 -
變量
+關(guān)注
關(guān)注
0文章
613瀏覽量
28368
原文標(biāo)題:子函數(shù)多層調(diào)用主要事項(xiàng)
文章出處:【微信號:SINO_25181447,微信公眾號:中穎電子】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
相關(guān)推薦
FPC流程和要注意事項(xiàng)簡介
買電動車需要注意什么及注意事項(xiàng)
使用全局變量及調(diào)用子函數(shù)應(yīng)該注意的問題點(diǎn)
FPGA學(xué)習(xí)及設(shè)計(jì)中需要注意事項(xiàng)有哪些?
膽機(jī)使用的注意事項(xiàng)
購買手機(jī)主要注意事項(xiàng)
LUA腳本API函數(shù)中的回調(diào)函數(shù)使用方法和注意事項(xiàng)資料和程序免費(fèi)下載
![LUA腳本API<b class='flag-5'>函數(shù)</b>中的回調(diào)<b class='flag-5'>函數(shù)</b>使用方法和<b class='flag-5'>注意事項(xiàng)</b>資料和程序免費(fèi)下載](https://file.elecfans.com/web1/M00/AA/85/pIYBAF2n5FuAC187AAQa_alPoN0267.png)
LabVIEW中調(diào)用DLL的整個(gè)過程及注意事項(xiàng)
空閑任務(wù)鉤子函數(shù)詳解
![空閑任務(wù)鉤<b class='flag-5'>子函數(shù)</b>詳解](https://file1.elecfans.com/web2/M00/8E/63/wKgZomTF0ReAPBqHAAN0G70m85I754.jpg)
評論