当前位置: 移动技术网 > 科技>办公>CPU > MULTIPLE CALL TO SEGMENT

MULTIPLE CALL TO SEGMENT

2020年09月01日  | 移动技术网科技  | 我要评论
WARNING L15: MULTIPLE CALL TO SEGMENT1、什么是Function Multiple Call Warning关于这个问题Keil C 给出的解释如下:简单来说,某一个函数被Main 函数调用的时候,这个时候发生了中断,在中断中这个函数被再次调用,这个时候就会导致之前的传参,临时变量被替换掉。需要讲一下,C51 由于堆栈空间很小,因此它利用一种 Overlay 的机制,将函数中的变量不存放在堆栈中,而是固定在memory 空间中。这种方式好处是节省堆栈空间。坏处就是函

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

如您对本文有疑问或者有任何想说的,请点击进行留言回复,万千网友为您解惑!

相关文章:

验证码:
移动技术网