此处的信息适用于:

  • C51所有版本

症状

我添加了一个中断处理程序(ISR)到我的项目中,然而我却得到了如下的警告:

***WARNING L15:  MULTIPLE CALL TO SEGMENT
SEGMENT:   ?PR?_WRITE_GMVLX1_REG?D_GMVLX1
CALLER1:   ?PR?VSYNC_INTERRUPT?MAIN
CALLER2:   ?C_C51STARTUP
***WARNING L15:  MULTIPLE CALL TO SEGMENT
SEGMENT:   ?PR?_SPI_SEND_WORD?D_SPI
CALLER1:   ?PR?VSYNC_INTERRUPT?MAIN
CALLER2:   ?C_C51STARTUP
***WARNING L15:  MULTIPLE CALL TO SEGMENT
SEGMENT:   ?PR?SPI_RECEIVE_WORD?D_SPI
CALLER1:   ?PR?VSYNC_INTERRUPT?MAIN
CALLER2:   ?C_C51STARTUP

上面这些都是什么?我该如何解决这个问题呢?

原因

Warning 15向我们表明了linker发现了一个函数,这个函数不仅在main code里被调用了,而且在ISR(或者被ISR调用的函数中)被调用了。或者是被同时被多个ISR同时调用了。

这样会产生一个问题,就是在此函数不是一个可重入函数,而当此函数已经在执行时它可能被另一个ISR所调用。这样就会导致结果是可变的而且很可能会导致一些参数的错误。

另一个问题就是本地变量和参数所使用的内存可能被其他函数的内存覆盖。如果函数是由中断所调用的,则此函数的内存就会被使用。这会引起其它函数的内存错误。

举例来说,对于你的第一个警告,WRITE_GMVLX1_REG是会被多个root所调用。其被定义在D_GMVLX1.C或者D_GMVLX1.A51中。他不仅会被ISR(或者被ISR调用的函数)而且也会被MAIN.C中的VSYNC_INTERRUPT函数所调用。

解决方法

有几种方法去解决这个问题


如果你100%确认这个函数的两个副本都不会同时执行(如果此函数是被main调用并且中断是未被使能的)并且此函数没有使用内存(只使用的寄存器),那么你就可以忽略此警告。


如果此函数使用了内存,你就要使用OVERLAY directive来将此函数从覆盖分析(overlay anaysis)中移除。举例如下:

OVERLAY (?PR?_WRITE_GMVLX1_REG?D_GMVLX1 ! *)

如上语句能阻止被此函数使用的内存遭到覆盖。如果这个函数调用了你程序中其他的在别处的函数,那么你可能需要将这些函数也排除在覆盖分析之外。


如果当此函数在执行时可以被调用,那么事情就会变得比较的复杂。你可能需要:

  1. 无论何时当从main中调用此函数时,需要关闭中断。你可能需要对被调用的函数使用#pragma disable。你也必须使用OVERLAY directive将此函数从overlay analysis中移除。
  2. 为此函数创建两个副本。一个给main,一个给ISR。
  3. 使此函数可重入。举例如下:
    void myfunc(void) reentrant {
    ...
    }

上面的定义会产生一个用来存储参数和本地变量的可重入的栈。如果使用了这种方法那么这个可重入的栈必须在STARTUP.A51中配置。这样会花费更多的RAM并且会减缓可冲入函数的执行。

在中断函数和MAIN函数中同时调用同一个函数的有趣现象相关推荐

  1. onclick如何调用含参函数_在 golang 中如何调用私有函数(绑定隐藏的标识符)

    名字在 golang 中的重要性和在其他任何一种语言是一样的.他们甚至含有语义的作用:在一个包的外部某个名字的可见性是由这个名字首字母是否是大写来决定的. 有时为了更好的组织代码或者在其他包使用某些隐 ...

  2. main.js中封装全局登录函数

    main.js中封装全局登录函数 1. 在 main.js 中封装全局登录函数 通过 vue 对象的原型扩展,可以扩展一个函数,这样这个函数就可以在 每一个界面通过类似指向对象的方式,去访问这个函数. ...

  3. C语言中连续调用rand函数,返回值不变

    C语言中连续调用rand函数,返回值不变 最近用C语言随机函数编程发现了一个奇怪的现象: 简易版代码: #include<stdio.h> #include<stdlib.h> ...

  4. 创建方法求两个数的最大值max2,随后再写一个求3个数的最大值的函数max3。​ 要求:在max3这个函数中,调用max2函数,来实现3个数的最大值计算

    //创建方法求两个数的最大值max2,随后再写一个求3个数的最大值的函数max3.//要求:在max3这个函数中,调用max2函数,来实现3个数的最大值计算public static int max3 ...

  5. matlab 中调用s函数表达式,[求助]S函数中能否调用M函数

    [求助]S函数中能否调用M函数 我现在写了一个S-FUNCTION 里面调用了一些M函数,当把S函数的名字写入S-FUNCTION块的时候 总是出现 ??? SWITCH expression mus ...

  6. linux 下的动态库制作 以及在python 中如何调用 c 函数库

    linux 下的动态库制作 以及在python 中如何调用 c 函数库 动态库: 动态库又称动态链接库英文为DLL,是Dynamic Link Library 的缩写形式,DLL是一个包含可由多个程序 ...

  7. C++中怎么调用C函数

    关于"C++中怎么调用C函数"的方法,之前有浏览过大牛的文章,貌似有好几种方法. 作为小白,this is my way. /* File: parse.h* Purpose: s ...

  8. ng-repeat循环出来的部分调用同一个函数并且实现每个模块之间不能相互干扰

    使用场景:用ng-repeat几个部分,每个部分调用同一个函数,但是每个模块之间的功能不能相互干扰 问题:在用repeat实现.content块repeat的时候打算这样做:新建一个空的数组(nmbe ...

  9. linux多线程调用同一个函数解析

    原文地址:http://blog.csdn.net/mq_ydn3102/article/details/8546722 问题背景:在工作中遇到过一个问题,就是在两个线程同时调用同一个函数的时候,到底 ...

最新文章

  1. 谷歌Jeff Dean团队提出利用深度学习对「电子健康记录」数据进行分析,可提高医疗诊断预测的准确性
  2. linux内核 arm交叉编译
  3. ORA-16019: cannot use LOG_ARCHIVE_DEST_1 解决方法
  4. 6用NetBeans进行JSP开发
  5. AI论文解读丨融合视觉、语义、关系多模态信息的文档版面分析架构VSR
  6. Leetcode-237:删除链表中的节点
  7. 星巴克“啡快”宣布接入支付宝、口碑等阿里应用
  8. MySQL 常见面试知识点
  9. obs计算机丢失,安装obs时提醒没法启动此程序,因为计算机丢失
  10. 银行招聘笔试中行测和综合知识复习心得
  11. 三维动画制作流程之间的关系
  12. 交换机设备登录账号权限1_交换机怎么设置 交换机配置方法【详解】
  13. pytest-allure美化——定制化输出测试报告
  14. 【Tools】Photoshop CS6安装详解教程
  15. ffmpeg 图片合成视频
  16. 谷歌身份验证器 java demo实现 及使用中问题分析
  17. 微信小程序接入环信客服
  18. 贝叶斯法则与虚假阳性的病例
  19. 音量计算机的网红音乐,网红音乐10首抖音网红歌,抖音网红歌曲100首BGM精选
  20. vue3笔记十(vue3 tsx使用)

热门文章

  1. 嵌入式笔试面试问题总结
  2. Selenium自动化测试代理问题
  3. MCU Alarm报警监测
  4. 带之字独特好听、个性充满活力的女孩名字
  5. 反演产品的精度和空间分辨率
  6. Kyligence 春季论坛成功举办,助力企业构建数字化管理新体系
  7. python画猪头程序_用python画猪头的方法
  8. 【Hbase】HBase入门教程
  9. 根据前序遍历和[中序遍历]
  10. 数据库_关键字的使用