keil中 如何解决warning L13:Recursive call to Function 及overlay解释
来源:互联网 发布:ubuntu nvidia smi 编辑:程序博客网 时间:2024/05/17 03:33
最近编译keil项目时,遇到一个比较奇怪的link warning,如下所示。
根据这个warning,容易知道这两个函数存在递归(相互)调用关系。其实在源代码中不存在直接递归调用关系,而是间接地调用,从map文件摘出这个calltree如下
+--> _CBUSMSCREADECBUSSPEEDSDONE/SI_DRVCBUSRX
| | _CBUSMSCREADTMDSSPEEDSDONE/SI_DRVCBUSRX
| | _CBUSMSCREADECBUSDEVROLESDONE/SI_DRVCBUSRX
| | _CBUSMSCREADLOGDEVMAPDONE/SI_DRVCBUSRX
| | _CBUSMSCREADBANDWIDTHDONE/SI_DRVCBUSRX
| | _CBUSMSCREADFEATUREFLAGDONE/SI_DRVCBUSRX
| | _CBUSMSCREADDEVICEIDHDONE/SI_DRVCBUSRX
| | _CBUSMSCREADDEVICEIDLDONE/SI_DRVCBUSRX
| | _CBUSMSCREADSCRATCHPADSIZEDONE/SI_DRVCBUSRX
<--+ _CBUSMSCREADINTSTATSIZEDONE/SI_DRVCBUSRX
简单梳理一下上面的调用树,就是CBUSMSCREADECBUSSPEEDSDONE调用了CBUSMSCREADTMDSSPEEDSDONE, CBUSMSCREADECBUSDEVROLESDONE调用了CBUSMSCREADECBUSDEVROLESDONE。。。 。。。最后CBUSMSCREADINTSTATSIZEDONE又调用了CBUSMSCREADECBUSSPEEDSDONE。
众所周知,Keil51由于内存资源比较紧张,函数的参数及局部变量一般地放在data segment, 为了避免一个函数的变量被另外一个函数的变量覆盖,keil会分析函数之间的相互调用关系,对于没有相互调用的关系的函数变量就可以重叠在一起,即overlay。 对于存在调用关系的函数,则变量存放在data区间的不同地址。但是,递归调用是一种例外,由于
是同一个函数,所以变量都会重叠在一起,这样会造成变量还没用完就被覆盖了。 基于此,原则上,keil51是不允许递归调用的。
关键点:如何解决这类问题?
1)如果是直接递归调用, 如下所示
void B(void)
{
... ...
B()
... ....
}
就将B函数申明为void B(void) reentrant, 这样就会生成模拟栈来储存自动变量和参数,以避免变量被覆盖。
2)如果是间接递归调用,如我的项目遇到的case,怎么办?
在option->LX51 Misc->Misc controls中,有一个Overlay的空白框,这个是干什么用的呢? 查阅LX51 user guide,知道Overlay是link的一个指示符,我们可以利用它来手动
修改或标明call tree关系。比方说,A通过函数指针调用B,为安全起见,可以增加一条OVERLAY(A!(B)) 又比如A和B其实不存在调用关系,如我的项目中遇到的case,这种情况下,只需要增加OVERLAY(A~(B))
其实LX51指示符除了Overlay外还有很多,如removeunused, disablewarning等。如不把它们弄清楚 就很容易造成项目的各种不稳定性。
- keil中 如何解决warning L13:Recursive call to Function 及overlay解释
- 终于解决 归递调用 警告,其实程序没有 归递调用*** WARNING L13: RECURSIVE CALL TO SEGMENT
- keil -- WARNING L15: MULTIPLE CALL TO SEGMENT
- 解决Call to undefined function
- 如何解决Call to undefined function mysql_connect() 问题
- Recursive function convert to Non-Recursive function
- ADS转Keil中 invalid call from '~PRES8' function to 'REQ8' 错误解决之道
- keil C 出现WARNING:MULTIPLE CALL TO SEGMENT的解析
- Keil 中的报警错误:WARNING L15: MULTIPLE CALL TO SEGMENT
- Call to undefined function: iconv() 解决
- call to undefined function mysql_connect()错误解决
- Call to undefined function mysqli_connect()错误解决
- error:Call to undefined function curl_init()解决
- 解决DEDECMS Call to undefined function dede_htmlspecialchars()
- 解决DEDECMS Call to undefined function dede_htmlspecialchars
- 解决DEDECMS Call to undefined function dede_htmlspecialchars
- 关于 keil C51 warning C182: Pointer to Different Objects 解决.
- warning:deprecated conversion from string constant to 'char *' 解释及解决
- 世界杯-英格兰1-2乌拉圭 濒临被淘汰
- extjs mvc的总结
- Android通过JNI调用驱动程序(完全解析实例)
- 成功的道路上,人脉比知识更重要。(SEO核心)
- freeswitch初始化过程
- keil中 如何解决warning L13:Recursive call to Function 及overlay解释
- SQL Server 对XML查询
- sdcard/DCIM/.thumbnails文件夹里的庞然大物 是这样来的
- 算法导论 第15章 动态规划 习题C++实现
- 解决Tomcat使用80端口被占用的问题
- poj2739
- zendstudio设置默认编码格式
- 简单的程序诠释C++ STL算法系列之十六:iter_swap
- 由chrome源码中的arraysize想到的