新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > keilC51編譯常見錯誤和警告說明

        keilC51編譯常見錯誤和警告說明

        作者: 時間:2016-11-27 來源:網絡 收藏
        ( 1 )L15 重復調用
        ***WARNING L15: MULTIPLE CALL TO SEGMENT
        SEGMENT: ?PR?SPI_RECEIVE_WORD?D_SPI
        CALLER1: ?PR?VSYNC_INTERRUPT?MAIN
        CALLER2: ?C_C51STARTUP
        該警告表示連接器發現有一個函數可能會被主函數和一個中斷服務程序 ( 或者調用中斷服務程序的函數 ) 同時調用 , 或者同時被多個中斷服務程序調用。
        出現這種問題的原因之一是這個函數是不可重入性函數 , 當該函數運行時它可能會被一個中斷打斷 , 從
        而使得結果發生變化并可能會引起一些變量形式的沖突 ( 即引起函數內一些數據的丟失 , 可重入性函數在任何時候都可以被 ISR 打斷 , 一段時間后又可以運行 , 但是相應數據不會丟失 ) 。
        原因之二是用于局部變量和變量 ( 暫且這樣翻譯 ,arguments,[ 自變量 , 變元一數值 , 用于確定程序或子程序的值 ]) 的內存區被其他函數的內存區所覆蓋 , 如果該函數被中斷 , 則它的內存區就會被使用 , 這將導致其他函數
        的內存沖突。

        例如 , 第一個警告中函數 WRITE_GMVLX1_REG 在 D_GMVLX1.C 或者 D_GMVLX1.A51 被定義 , 它被一個中斷
        服務程序或者一個調用了中斷服務程序的函數調用了 , 調用它的函數是 VSYNC_INTERRUPT, 在 MAIN.C 中。

        解決方法:
        如果你確定兩個函數決不會在同一時間執行 ( 該函數被主程序調用并且中斷被禁止 ), 并且該函數不占用內存 ( 假設只使用寄存器 ), 則你可以完全忽略這種警告。
        如果該函數占用了內存 , 則應該使用連接器 (linker)OVERLAY 指令將函數從覆蓋分析 (overlay
        analysis) 中除去 , 例如:
        OVERLAY (?PR?_WRITE_GMVLX1_REG?D_GMVLX1 ! *)
        上面的指令防止了該函數使用的內存區被其他函數覆蓋 。 如果該函數中調用了其他函數 , 而這些被調用在
        程序中其他地方也被調用 , 你可能會需要也將這些函數排除在覆蓋分析 (overlay analysis) 之外。這種 OVERLAY 指
        令能使編譯器除去上述警告信息。
        如果函數可以在其執行時被調用 , 則情況會變得更復雜一些。這時可以采用以下幾種方法:
        1. 主程序調用該函數時禁止中斷 , 可以在該函數被調用時用 #pragma disable 語句來實現禁止中斷的目的。必
        須使用 OVERLAY 指令將該函數從覆蓋分析中除去。
        2. 復制兩份該函數的代碼 , 一份到主程序中 , 另一份復制到中斷服務程序中。
        3. 將該函數設為重入型。例如:void myfunc(void) reentrant {
        ...
        }
        這種設置將會產生一個可重入堆棧 , 該堆棧被被用于存儲函數值和局部變量 , 用這種方法時重入堆棧必須在 STARTUP.A51 文件中配置。這種方法消耗更多的 RAM 并會降低重入函數的執行速度。

        ( 2 ) 提示無 M51 文件
        編譯時候提示:
        F:...XX.M51
        File has been changed outside the editor, reload ?
        ------
        解決方法:
        重新生成項目,產生 STARTUP.A51 即可。

        (3)L16 無調用
        *** WARNING L16: UNCALLED SEGMENT, IGNORED FOR OVERLAY PROCESS
        SEGMENT: ?PR?_COMPARE?TESTLCD
        說明 : 程序中有些函數例如 COMPARE ( 或片段 ) 以前 ( 調試過程中 ) 從未被調用過 , 或者根本沒
        有調用它的語句。
        這條警告信息前應該還有一條信息指示出是哪個函數導致了這一問題。只要做點簡單的調整就
        可以。不理它也沒什么大不了的。
        解決方法 : 去掉 COMPARE() 函數或利用條件編譯 #if … ..#endif, 可保留該函數并不編譯。

        (4)L10 和 L16" 主程序名字寫錯 ( 或無主程序 )"
        程序中 :
        void mian (void)
        編譯提示 :
        *** WARNING L16: UNCALLED SEGMENT, IGNORED FOR OVERLAY PROCESS
        SEGMENT: ?PR?MIAN?MAIN
        *** WARNING L10: CANNOT DETERMINE ROOT SEGMENTProgram Size: data=8.0 xdata=0 code=9
        ---
        修改 :
        缺少主程序 ( 其實是筆誤 ), 將 mian 改為 main

        (5)L16 主程序沒用到前面定義的函數
        主程序里沒用到前面定義的函數,編譯時顯示:
        *** WARNING L16: UNCALLED SEGMENT, IGNORED FOR OVERLAY PROCESS
        SEGMENT: ?PR?DELAY?MAIN

        (6)L210 程序前生成 SRC 語句
        Build target Target 1
        assembling STARTUP.A51...
        compiling test.C...
        linking...
        BL51 BANKED LINKER/LOCATER V6.00 - SN: K1JXC-94Z4V9
        COPYRIGHT KEIL ELEKTRONIK GmbH 1987 - 2005
        "STARTUP.obj",
        "test.obj"
        TO "test"
        *** FATAL ERROR L210: I/O ERROR ON INPUT FILE:
        EXCEPTION 0021H: PATH OR FILE NOT FOUND
        FILE: test.obj
        Target not created
        ---------
        設置上的問題,在程序里屏蔽掉 #pragma src 即可

        (7)C206 函數未定義
        該函數沒定義
        MAIN.C(15): warning C206: delay1: missing function-prototype(8)C141 少分號
        部分程序 :
        {
        pval = P1
        P3 = pval;
        }
        編譯提示出錯 :
        MAIN.C(22): error C141: syntax error near P3
        改正 : P1 后加 ";"

        (9)C129 匯編與 C 后綴問題
        例如寫這么一段小程序,保存為 c0.c ,編譯時出現 error c129 , miss ; before 0000 ;
        如果保存為: c0.asm 就不會出現這個錯誤,保存為 c 的話,先調用 c51 編譯器,按 c 語言的要求編譯,所以
        出現錯誤;可以參考一些書,專門介紹 keilc 這個編譯器的;

        (10)C101 和 C141 關于數組引號問題
        定義了如下的數組:
        unsigned char
        a[36]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f,0x7e,0x7d,0x7b,0x77,0x6f,
        0x5f,0x3f,0x3e,0x3d,0x3b,0x37,0x2f,0x1f,0x1e,0x1d,0x1b,0x17,0x0f,0x0e,0
        x0d,0x0b,0x07,0x06,0x05,0x03,0x02,0x01,0x00};
        可是編譯的時候總通不過,錯誤提示如下:
        Build target Target 1
        compiling shaomiao.c...
        SHAOMIAO.C(3): error C101: 0: invalid character constant
        SHAOMIAO.C(3): error C141: syntax error near xfe
        SHAOMIAO.C(3): error C101: }: invalid character constant
        Target not created
        解決方法:去掉 ... 引號

        (11)C100 和 C141 和 C129 程序有中文標點
        用 keil 編譯時出現錯誤,如下: D:KEILC51INCREG52.H(1): error C100: unprintable character 0xA1
        skipped同上錯誤有很多個,還有 D:KEILC51INCREG52.H(2): error C141: syntax error near #
        D:KEILC51INCREG52.H(2): error C129: missing ; before<
        但是 reg52.h 頭文件是 keil 自帶的(見下),為何會報錯呀。
        ----
        回答: 程序里有帶中文標點,用英文重新寫一遍即可

        (12)A45 匯編出現數字、字母混淆
        MOV PO,A ;put on next 11
        ...
        MOV RO,#0FFH ; 14
        MOV R1,#OFFH ; 15
        ...
        DJNZ RO,DLY_LP ;19
        MOV R0,#OFFH ; 20
        ...
        編譯后:
        ledtest.asm(11): error A45: UNDEFINED SYMBOL (PASS-2)
        ledtest.asm(14): error A45: UNDEFINED SYMBOL (PASS-2)
        ledtest.asm(15): error A45: UNDEFINED SYMBOL (PASS-2)
        ledtest.asm(19): error A45: UNDEFINED SYMBOL (PASS-2)
        ledtest.asm(20): error A45: UNDEFINED SYMBOL (PASS-2)
        Target not created
        ---------
        注意:
        字母 “ O ” 和 數字 “ 0 ” 。主要錯在這里。
        應該輸入數字 “ 0 ” ,而你輸入字母 “ O ” 了。

        (13)Warning 280: ’ i ’ :unreferenced local variable
        說明局部變量 i 在函數中未作任何的存取操作解決方法消除函數中 i 變量的宣告2 Warning 206: ’ Music3 ’ :missing function-prototype
        說明 Music3( ) 函數未作宣告或未作外部宣告所以無法給其他函數調用
        解決方法將敘述 void Music3(void) 寫在程序的最前端作宣告如果是其他文件的函數則要寫
        成 extern void Music3(void), 即作外部宣告

        3 Compling :C:8051MANN.C
        Error:318:can ’ t open file ‘ beep.h ’
        說明在編譯 C:8051MANN.C 程序過程中由于 main.c 用了指令# i nclude “ beep.h ” , 但
        卻找不到所致解決方法編寫一個 beep.h 的包含檔并存入到 c:8051 的工作目錄中

        (14)Compling:C:8051LED.C
        Error 237: ’ LedOn ’ :function already has a body
        說明 LedOn( ) 函數名稱重復定義即有兩個以上一樣的函數名稱
        解決方法修正其中的一個函數名稱使得函數名稱都是獨立的

        15)***WARNING 16:UNCALLED SEGMENT,IGNORED FOR OVERLAY PROCESS
        SEGMENT: ?PR?_DELAYX1MS?DELAY
        說明 DelayX1ms( ) 函數未被其它函數調用也會占用程序記憶體空間解決方法去掉DelayX1ms( ) 函數或利用條件編譯 #if … ..#endif, 可保留該函數并不編譯

        (16) ***WARNING 6 :XDATA SPACE MEMORY OVERLAP
        FROM : 0025H
        TO: 0025H
        說明外部資料 ROM 的 0025H 重復定義地址
        解決方法外部資料 ROM 的定義如下 Pdata unsigned char XFR_ADC _at_0x25 其中 XFR_ADC
        變量的名稱為 0x25, 請檢查是否有其它的變量名稱也是定義在 0x25 處并修正它

        (17) WARNING 206: ’ DelayX1ms ’ : missing function-prototype
        C:8051INPUT.C
        Error 267 : ’ DelayX1ms ‘ :requires ANSI-style prototype C:8051INPUT.C
        說明程序中有調用 DelayX1ms 函數但該函數沒定義即未編寫程序內容或函數已定義但未作宣告
        解決方法編寫 DelayX1ms 的內容編寫完后也要作宣告或作外部宣告可在 delay.h 的包含檔宣告成外部以便其它函數調用

        (18) ***WARNING 1:UNRESOLVED EXTERNAL SYMBOL
        SYMBOL:MUSIC3
        MODULE:C:8051MUSIC.OBJ(MUSIC)
        ***WARNING 2:REFERENCE MADE TO UNRESOLVED EXTERNAL
        SYMBOL:MUSIC3
        MODULE:C:8051MUSIC.OBJ(MUSIC)
        ADDRESS:0018H
        說明程序中有調用 MUSIC 函數但未將該函數的含擴檔 C 加入到工程檔 Prj 作編譯和連接
        解決方法設 MUSIC3 函數在 MUSIC C 里將 MUSIC C 添加到工程文件中去

        (19) ***ERROR 107:ADDESS SPACE OVERFLOW
        SPACE: DATA
        SEGMENT: _DATA_GOUP_
        LENGTH: 0018H
        ***ERROR 118: REFERENCE MADE TO ERRONEOUS EXTERNAL
        SYMBOL: VOLUME
        MODULE: C:8051OSDM.OBJ (OSDM)
        ADDRESS: 4036H
        說明 data 存儲空間的地址范圍為 0~0x7f, 當公用變量數目和函數里的局部變量如果存儲模式設為 SMALL 則局部變量先使用工作寄存器 R2~R7 作暫存當存儲器不夠用時則會
        以 data 型別的空間作暫存的個數超過 0x7f 時就會出現地址不夠的現象
        解決方法將以 data 型別定義的公共變量修改為 idata 型別的定義


        (20).***WARNING L15: MULTIPLE CALL TO SEGMENT
        SEGMENT: ?PR?_WRITE_GMVLX1_REG?D_GMVLX1
        CALLER1: ?PR?VSYNC_INTERRUPT?MAIN
        CALLER2: ?C_C51STARTUP
        ***WARNING L15: MULTIPLE CALL TO SEGMENT
        SEGMENT: ?PR?_SPI_SEND_WORD?D_SPI
        CALLER1: ?PR?VSYNC_INTERRUPT?MAIN
        CALLER2: ?C_C51STARTUP
        ***WARNING L15: MULTIPLE CALL TO SEGMENT
        SEGMENT: ?PR?SPI_RECEIVE_WORD?D_SPI
        CALLER1: ?PR?VSYNC_INTERRUPT?MAIN
        CALLER2: ?C_C51STARTUP
        該警告表示連接器發現有一個函數可能會被主函數和一個中斷服務程序 ( 或者調用中斷服務程序的函數 ) 同時調用 ,或者同時被多個中斷服務程序調用。

        出現這種問題的原因之一是這個函數是不可重入性函數 , 當該函數運行時它可能會被一
        個中斷打斷 , 從而使得結果發生變化并可能會引起一些變量形式的沖突 ( 即引起函數內一些數據的丟失 , 可重入性函數在任何時候都可以被 ISR 打斷 , 一段時間后又可以運行 , 但是相應數據不會丟失 ) 。

        原因之二是用于局部變量和變量 ( 暫且這樣翻譯 ,arguments,[ 自變量 , 變元一數值 , 用于確定程序或子程序的值 ]) 的內存區被其他函數的內存區所覆蓋 , 如果該函數被中斷 , 則它的內存區就會被使用 , 這將導致其他函數的內存沖突。
        例如 , 第一個警告中函數 WRITE_GMVLX1_REG 在 D_GMVLX1.C 或者 D_GMVLX1.A51 被定義 ,
        它被一個中斷服務程序或者一個調用了中斷
        服務程序的函數調用了 , 調用它的函數是 VSYNC_INTERRUPT, 在 MAIN.C 中。

        解決方法:
        如果你確定兩個函數決不會在同一時間執行 ( 該函數被主程序調用并且中斷被禁止 ), 并
        且該函數不占用內存 ( 假設只使用寄存器 ),
        則你可以完全忽略這種警告。
        如果該函數占用了內存 , 則應該使用連接器 (linker)OVERLAY 指令將函數從覆蓋分析
        (overlay analysis) 中除去 , 例如:
        OVERLAY (?PR?_WRITE_GMVLX1_REG?D_GMVLX1 ! *)
        上面的指令防止了該函數使用的內存區被其他函數覆蓋。如果該函數中調用了其他函數 ,
        而這些被調用在程序中其他地方也被調用 ,
        你可能會需要也將這些函數排除在覆蓋分析 (overlay analysis) 之外。這種 OVERLAY 指令能
        使編譯器除去上述警告信息。

        如果函數可以在其執行時被調用 , 則情況會變得更復雜一些。這時可以采用以下幾種方
        法:
        1. 主程序調用該函數時禁止中斷 , 可以在該函數被調用時用 #pragma disable 語句來實現禁
        止中斷的目的。必須使用 OVERLAY 指令將該函數
        從覆蓋分析中除去。
        2. 復制兩份該函數的代碼 , 一份到主程序中 , 另一份復制到中斷服務程序中。3. 將該函數設為重入型。例如:
        void myfunc(void) reentrant {
        ...
        }
        這種設置將會產生一個可重入堆棧 , 該堆棧被被用于存儲函數值和局部變量 , 用這種
        方法時重入堆棧必須在 STARTUP.A51 文件中配置。
        這種方法消耗更多的 RAM 并會降低重入函數的執行速度。

        (21). *** WARNING L16: UNCALLED SEGMENT, IGNORED FOR OVERLAY PROCESS
        SEGMENT: ?PR?_COMPARE?TESTLCD
        說明:程序中有些函數(或片段)以前(調試過程中)從未被調用過 , 或者根本沒有
        調用它的語句。
        這條警告信息前應該還有一條信息指示出是哪個函數導致了這一問題。只要做點簡
        單的調整就可以。不理它也沒什么大不了的。
        解決方法 : 去掉 COMPARE() 函數或利用條件編譯 #if … ..#endif, 可保留該函數并不
        編譯。


        評論


        技術專區

        關閉
        主站蜘蛛池模板: 万源市| 乃东县| 淮滨县| 德昌县| 黄石市| 亳州市| 通城县| 泾川县| 阳曲县| 巴青县| 保德县| 新河县| 东宁县| 灵石县| 大港区| 女性| 宣汉县| 平利县| 望城县| 商河县| 正蓝旗| 潼南县| 榆社县| 信宜市| 西乌| 峡江县| 抚宁县| 东乡县| 且末县| 上杭县| 汶川县| 大同县| 湖州市| 宜君县| 凉城县| 上虞市| 连云港市| 临高县| 平远县| 余庆县| 柳江县|