欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  科技

MULTIPLE CALL TO SEGMENT

程序员文章站 2022-03-11 21:37:31
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

MULTIPLE CALL TO SEGMENT

关于这个问题Keil C 给出的解释如下:
简单来说,某一个函数被Main 函数调用的时候,这个时候发生了中断,在中断中这个函数被再次调用,这个时候就会导致之前的传参,临时变量被替换掉。需要讲一下,C51 由于堆栈空间很小,因此它利用一种 Overlay 的机制,将函数中的变量不存放在堆栈中,而是固定在memory 空间中。这种方式好处是节省堆栈空间。坏处就是函数不可重入,无法被multiple call。
如果是高阶的MCU就不会有这个问题。
MULTIPLE CALL TO SEGMENT

2、Function Multiple Call 原因

有两种情况:
1、同一个函数(不可重入), 在正常执行的时候,被中断调用,即上面描述的情况。这个时候原先的变量和传参可能会被破坏掉。
2、两个不同的函数a、b,但由于上面将的Overlay 机制,内部的变量和参数的地址空间是同一个,(Overlay 机制认为两个函数不会被同时调用,因此分配相同的地址空间是没问题的),当a 在执行时,b 被中断调用,这个时候,a的参数,变量会被b 修改掉。
MULTIPLE CALL TO SEGMENT

3、解决方法
1、 忽视警告(不推荐)

如果该函数不会以重入的方式执行,并且没有使用任何的memory空间(参数传递和局部变量都没有用到),则可以忽略该warning。

2、 Overlay 指令

使用链接器的OVERLAY指令将函数从覆盖分析(overlay analysis)中除去
这可以让该函数独享某一块内存区域,而不参与overlay。该函数是不可重入的,但是可以在不影响其他函数memory的情况下,被多个thread调用。尽管如此,还是需要确保该函数不被多个thread 同时调用。
MULTIPLE CALL TO SEGMENT

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

相关标签: C51