keil中 如何解决warning L13:Recursive call to Function 及overlay解释

最近编译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等。如不把它们弄清楚 就很容易造成项目的各种不稳定性。

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ltshan139

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值