BL51: WARNING L13 (RECURSIVE CALL TO SEGMENT) WITH CONSTANTS 解决
问题描述:
将函数名存储在table里,通过函数指针的方式调用函数。
编译提示:
BL51: WARNING L13 (RECURSIVE CALL TO SEGMENT) WITH CONSTANTS
使用环境:
C51 Version 7.00
代码例程(使用Keil官方资料来说明):
文件名是:EXAMPLE1.C
void func1 (unsigned char *msg) {
;
}
void func2 (void) {
unsigned char uc;
func1("xxxxxxxxxxxxxxx");
}
code void (*func_array[])() = { func2 };
void main( void ) {
(*func_array[0])();
}
编译的时候就会提示:
*** WARNING 13: RECURSIVE CALL TO SEGMENT
SEGMENT: ?CO?EXAMPLE1
CALLER: ?PR?FUNC2?EXAMPLE1
原因:
In this program example, func2 defines a constant string ("xxx...xxx") which is located in the constant code segment ?CO?EXAMPLE1. The definition:
code void (*func_array[])() = { func2 };
generates a reference between segment ?CO?EXAMPLE1 (where the code table is located) and the executable code segment ?PR?FUNC2?EXAMPLE1. Since func2 also refers to segment ?CO?EXAMPLE1, BL51 assumes that there is a recursive call.
官方的解决办法:
RESOLUTION
To avoid this problem, you must manually remove the reference between func2 and the ?CO?EXAMPLE1 segment. The following overlay directive does that:
bl51 EXAMPLE1.OBJ IX OVERLAY (?CO?EXAMPLE1 ~ FUNC2, MAIN ! FUNC2)
?CO?EXAMPLE1 ~ FUNC2 deletes the implied call reference between func2 and the code constant segment in the example. Then, MAIN ! FUNC2adds a reference between MAIN and FUNC2. This is required because main calls func2 indirectly. Note that automatic overlay analysis does not allow for references made to functions via pointers. References of this type must be manually implemented, as in the example above.
另一个办法:
将code void (*func_array[])() = { func2 }; 放在另一个C文件里,这样就规避了所谓的递归调用了。
参考文献:
http://www.keil.com/support/docs/2379.htm
http://blog.csdn.net/avideointerfaces/article/details/32687899