MULTIPLE CALL TO SEGMENT
WARNING L15: MULTIPLE CALL TO SEGMENT
1、什么是Function Multiple Call Warning
关于这个问题Keil C 给出的解释如下:
简单来说,某一个函数被Main 函数调用的时候,这个时候发生了中断,在中断中这个函数被再次调用,这个时候就会导致之前的传参,临时变量被替换掉。需要讲一下,C51 由于堆栈空间很小,因此它利用一种 Overlay 的机制,将函数中的变量不存放在堆栈中,而是固定在memory 空间中。这种方式好处是节省堆栈空间。坏处就是函数不可重入,无法被multiple call。
如果是高阶的MCU就不会有这个问题。
2、Function Multiple Call 原因
有两种情况:
1、同一个函数(不可重入), 在正常执行的时候,被中断调用,即上面描述的情况。这个时候原先的变量和传参可能会被破坏掉。
2、两个不同的函数a、b,但由于上面将的Overlay 机制,内部的变量和参数的地址空间是同一个,(Overlay 机制认为两个函数不会被同时调用,因此分配相同的地址空间是没问题的),当a 在执行时,b 被中断调用,这个时候,a的参数,变量会被b 修改掉。
3、解决方法
1、 忽视警告(不推荐)
如果该函数不会以重入的方式执行,并且没有使用任何的memory空间(参数传递和局部变量都没有用到),则可以忽略该warning。
2、 Overlay 指令
使用链接器的OVERLAY指令将函数从覆盖分析(overlay analysis)中除去
这可以让该函数独享某一块内存区域,而不参与overlay。该函数是不可重入的,但是可以在不影响其他函数memory的情况下,被多个thread调用。尽管如此,还是需要确保该函数不被多个thread 同时调用。
3、 复杂情况下应对方式
当某个函数在执行时会被其他thread打断并调用时,则可以使用如下方式:
1) main调用该函数时禁止中断,可以在该函数被调用时用#pragma disable
语句来实现禁止中断的目的。必须使用OVERLAY指令将该函数从覆盖分析中除去。
调用时禁止中断,而不是在函数中禁止中断,因为函数参数传递也有可能用到memory,同时需要使用OVERLAY指令。
2)复制两份该函数的代码,一份到主程序中,另一份复制到中断服务程序中。
最简单可靠的实现,代码量会增加。
3)将该函数设为重入型
例如:
void myfunc(void) reentrant
{
...
}
这种设置将会产生一个可重入堆栈,该堆栈被被用于存储函数值和局部变量,用这种方法时重入堆栈必须在STARTUP.A51文件中配置。这种方法消耗更多的RAM并会降低重入函数的执行速度。
4、参考文档如下:
https://www.keil.com/support/docs/805.htm
Overly 机制参考:
https://blog.csdn.net/shenjin_s/article/details/107212719
本文地址:https://blog.csdn.net/shenjin_s/article/details/108585518
上一篇: 彻底解决Linux无法定位软件包!!!
下一篇: 用vbs实现配置静态 IP 地址
推荐阅读
-
浅谈JavaScript中的apply/call/bind和this的使用
-
PHP 函数call_user_func和call_user_func_array用法详解
-
PHP call_user_func和call_user_func_array函数的简单理解与应用分析
-
python中的__init__ 、__new__、__call__小结
-
Fatal error: Call to undefined function curl_init()解决方法
-
(杭电1019 最大公约数) Least Common Multiple
-
JavaScript函数apply()和call()用法与异同分析
-
mysql存储过程之创建(CREATE PROCEDURE)和调用(CALL)及变量创建(DECLARE)和赋值(SET)操作方法
-
javascript中call,apply,bind函数用法示例
-
js中apply()和call()的区别与用法实例分析