原创 KEIL产生WARNINGL15: MULTIPLE CALL TO SEGMENT的原因及解决方法

2008-8-17 12:58 11776 5 6 分类: MCU/ 嵌入式

.***WARNING L15: MULTIPLE CALL TO SEGMENT
SEGMENT: ?。。。?。。。
CALLER1: ?。。。?MAIN
CALLER2: ?C_C51STARTUP


该警告表示连接器发现有一个函数可能会被主函数和一个中断服务程序(或者调用中断服务程序的函数)同时调用,或者同时被多个中断服务程序调用。


 


出现这种警告的原因一般有两种:


第一:这个函数是不可重入函数,当该函数运行时可能被打断,打断后该函数又被再次运行,从而造成函数内部数据丢失;


第二:该函数的内部变量数据所占有的内存在link时被连接器认为是可覆盖的,因此在连接时进行了数据覆盖优化,但是连接器同时发现该函数在运行时被打断后,其他函数(如中断服务子程序)的运行造成了该函数的数据被覆盖。


 


对于第二种原因,我们举个例子:


void task1()


{


     int val1;


    ......\\其他程序


}


 


void task2()


{


   int val2;


  ......\\其他程序


}


void int_ISR()//中断服务子程序


{


   int aaa;


  task2();


}


这里有两个任务函数task1和task2,它们之间没有直接的调用关系,因此连接器在连接时就会做数据覆盖优化,也就是说va11和val2这两个变量会占用相同的内存空间。但是当task1运行时发生了中断,在中断服务子程序中又调用了task2,那么task1的val1值很可能会被覆盖(数据被破坏)。这种情况的解决办法一般有两种:


 


1、使用连接器(linker)OVERLAY 指令将函数从覆盖分析(overlay analysis)中除去;即告知连接器不对task1的val1做覆盖优化,让它独享自己的内存空间;这种方法的唯一缺点是task1不能做递归调用(个人认为,没做验证),要想一个函数可递归调用,唯一的方法是声明该函数为可重入。


 


2、定义两个相同功能的函数,分别在中断和中断外调用;


 


当然,你可以把task1设为可重入函数,产生一个可重入堆栈,用于存储函数的参数和局部变量,但是这种方法会消耗更多的RAM 并会降低重入函数的执行速度。


 


上述是个人理解心得,如有问题请回帖讨论,我会加以更正。

PARTNER CONTENT

文章评论1条评论)

登录后参与讨论

用户1662358 2012-9-12 16:29

学习了。。。
相关推荐阅读
用户141063 2010-12-31 18:40
microSD卡SPI模式读写及FATfs移植(基于c8051f340)
2009年6月4日星期四       花了不到一个月,SD卡的SPI模式读写与FATfs文件系统的移植告一段落了,写下来为大家一个提供参考。硬件(如图1、2、3):(1)       新华龙BT F3...
用户141063 2008-12-08 20:09
清华大学校长留给毕业生的一段话
未来的世界:方向比努力重要,能力比知识重要,健康比成绩重要,生活比文凭重要,情商比智商重要!”                                                     ...
用户141063 2008-10-18 11:56
阻抗匹配
阻抗匹配是指信号源或者传输线跟负载之间的一种合适的搭配方式。阻抗匹配分为低频和高频两种情况讨论。 <?xml:namespace prefix = o ns = "urn:schemas-mic...
用户141063 2008-08-31 09:45
决定高薪必要的细节守则
作者:贾忠贤 转自chinaren: http://i.chinaren.com/group/msg/12331/15987338点到10点之间,是在有目的性阅读,还是为明天的事情做准备,甚至在充电专...
用户141063 2008-08-28 19:33
脑子脱线那一刻...
别人的。。。●有一次坐公交拿了IC卡排队上车,前面一个人是扔硬币的,我大脑短路跟着把IC卡扔进去了……●早上要戴隐形眼镜,结果把盖打开直接把眼镜倒马桶里,然后镇定地倒入新的护理液,准备摘眼镜,半天摘不...
我要评论
1
5
关闭 站长推荐上一条 /3 下一条