在程序中出現了如下警告:
*** WARNING L15: MULTIPLE CALL TO SEGMENT
SEGMENT: ?PR?_CRCDATA?PANEL_DISP
CALLER1: ?C_C51STARTUP
CALLER2: ?PR?UART_RECV?PANEL_DISP
*** WARNING L15: MULTIPLE CALL TO SEGMENT
SEGMENT: ?PR?ANALOGALLBECKON?PANEL_DISP
CALLER1: ?C_C51STARTUP
CALLER2: ?PR?UART_RECV?PANEL_DISP
*** WARNING L15: MULTIPLE CALL TO SEGMENT
SEGMENT: ?PR?SWITCHALLBECKON?PANEL_DISP
CALLER1: ?C_C51STARTUP
CALLER2: ?PR?UART_RECV?PANEL_DISP
我的程序編譯出來就這3個警告,但是程序可以正常下載運行。但是我覺得有這些警告會使程序存在bug。從字面上看是它的意思是我程序中接受函數UART_RECV()多調用了analogAllBeckon()、switchAllBeckon()。
因為51的普通函數是不可重入的,變量放在固定的地址,兩個函數同時運行時,就會修改同一個變量,從而導致結果錯誤。於是我在analogAllBeckon()、switchAllBeckon()函數後面加了void analogAllBeckon()reentrant{//All Analog data beckon使程序消除了警告。這種方法是表明函數是可被多哥任務調用而不修改函數裡邊的變量值,以此來實現函數的重入性。
關於reentrant的使用keil的官方論壇上有詳細的討論。
Andy Neil(官方工程師)建議
"Are you sure that you really need to make everything reentrant?...A reading of the Keil app notes & knowledgebase articles on this subject showed that it was not necessary. "
由於每一次調用被reentrant聲明的函數都要把函數的參數和內部變量壓棧,所以很容易使堆棧區溢出,S52隻有256Bytes的data段,一個簡單的函數如果有一個參數三個內部變量,則需要壓棧4位元組以上,這還不包括函數調用堆棧.reentrant其實並不是適合低端的單片機,keil論壇上有人說對於那些有KB以上RAM的單片機reentrant才適合。