微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > keilC51编译常见错误和警告说明

keilC51编译常见错误和警告说明

时间: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 的话,先调用

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top