打印

KEIL,把设置中断优先级的代码全都给删掉了

[复制链接]
4515|22
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
XIANSir|  楼主 | 2011-3-2 14:55 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
今天,升级程序,发现编译器报告“*** WARNING L15: MULTIPLE CALL TO SEGMENT”,经过GOOGLE之后确认,是两个定时器中断调用了同一个非可重入函数。
于是,就搜索学习了一下关于KEIL的函数可重入行以及8051中断嵌套相关的内容,之后果断决定:把所有设置中断优先级的代码全部删除——即让中断优先级都为默认值(默认值应该都是一样的吧?)。

我是这样想的:
1、我的系统的实时性需求并不强,没有必要中断嵌套
2、以前的低优先级的中断处理代码并没有依赖于高优先级中断中设置的标志
3、尽量使代码的执行情况简单,可预知,在当前还比较菜的情况下,应该使用最基本的功能踏踏实实的编程,不应该耍弄奇技淫巧——万一出了奇怪问题,自己又解决不了。

另外,为什我都把所有的中断设为同一优先级了(全部默认),可KEIL编译器还是报那个警告啊。我的理解是:都是同一优先级,没有中断嵌套,这样即使中断调用同一个非可重入函数,应该也不会产生所谓的“可重入问题啊”

相关帖子

沙发
ayb_ice| | 2011-3-2 15:26 | 只看该作者
你的这些行为KEIL怎么可能知道呢,就算知道谁又能保证你的代码是正确呢。。。。
所以KEIL给出的是警告,而不是错误,警告只是可能存在错误,提示需要程序员需要注意。。。
如果不想看到警告
试试在那个被调用的函数定义前加个#pragma disable试试
如果还不行的话,可以分别调用两个不同的函数,但函数功能一模一样

使用特权

评论回复
板凳
XIANSir|  楼主 | 2011-3-2 15:43 | 只看该作者
2# ayb_ice
你的这些行为KEIL怎么可能知道呢”


呵呵,的确是这样子的。


这个警告虽然我可以忽略之,就怕老大看见警告不愿意——实在不行我就定义两个一模一样的函数,反正存储器还剩的多呢:64K ROM才用了4K


可见,选器件的时候价格也没有那么大的影响偶!!

使用特权

评论回复
地板
computer00| | 2011-3-2 16:20 | 只看该作者
给这个函数加个reentrant关键字

使用特权

评论回复
5
XIANSir|  楼主 | 2011-3-2 16:44 | 只看该作者
4# computer00
谢谢指点!:handshake

我不想使用这些高级特性,毕竟自己很菜,写的又是产品代码,不想采用这种冒险方法——等自己以后能够驾驭可重入性这个概念是再用不迟。

使用特权

评论回复
6
ayb_ice| | 2011-3-2 17:23 | 只看该作者
或者禁止KEIL显示对应的警告

使用特权

评论回复
7
hgjinwei| | 2011-3-2 22:41 | 只看该作者
既然确认是非可重入函数,你也敢在两个中断函数中调用?除非调用前禁止中断,返回后再开中断,不然很有可能死得很惨。

使用特权

评论回复
8
nevsayno| | 2011-3-3 08:45 | 只看该作者
楼主最近很活跃 是块搞技术的好料 加油 呵呵~

使用特权

评论回复
9
论坛游客| | 2011-3-3 09:18 | 只看该作者
最简单的办法是搞两个不同名字但内容一模一样的函数  然后不同中断调用不同函数

使用特权

评论回复
10
XIANSir|  楼主 | 2011-3-3 09:35 | 只看该作者
7# hgjinwei
不是这样吧,我查资料后感觉是:只要不发生中断嵌套,在中断中调用非可重入函数就没有问题。

我把所有的中断的优先级都设成一样,这样就不会发生中断嵌套,所以应该不会死的很惨

使用特权

评论回复
11
XIANSir|  楼主 | 2011-3-3 09:37 | 只看该作者
7# hgjinwei
而且,在中断的优先级都相同的情况下,进入中断后,只要这个中断不退出,其他中断是不会被响应的。

使用特权

评论回复
12
XIANSir|  楼主 | 2011-3-3 09:38 | 只看该作者
9# 论坛游客
这方法是简单,可以采用

使用特权

评论回复
13
XIANSir|  楼主 | 2011-3-3 09:40 | 只看该作者
8# nevsayno
呵呵,觉得搞单片机挺有意思的,很感兴趣

使用特权

评论回复
14
fox53er| | 2011-3-3 09:40 | 只看该作者
简单也挺实用呃

使用特权

评论回复
15
sytu_chyq| | 2011-3-3 11:19 | 只看该作者
10# XIANSir
即使都设成低优先级(默认是这个吧),不同中断还是有优先级高低之分吧。。

使用特权

评论回复
16
ayb_ice| | 2011-3-3 11:23 | 只看该作者
10# XIANSir  
即使都设成低优先级(默认是这个吧),不同中断还是有优先级高低之分吧。。
sytu_chyq 发表于 2011-3-3 11:19

确实有自然优先级,但仅限于同时申请中断时有限,并不能嵌套,所以不会有问题

使用特权

评论回复
17
hgjinwei| | 2011-3-3 12:45 | 只看该作者
10# XIANSir

确实,只要能保证所有中断优先级一致,不会发生嵌套现象,那确实大可放心。
但是如果之后有人修改了中断优先级,导致嵌套可发生,那就悲剧了。
所以除非设计成可重入模式,不然只有自主保护才是正道。

PS:9L的方法不一定行,函数可重入的本质是不修改全局状态,而不是函数名不同。只要你的函数会修改全局状态,就是不可重入的。
比如有一个全局变量 A
如果B函数执行 A++;C函数执行 A--;那么B和C都具有不可重入性。中断1调用B,中断2调用C,那也是白扯,总有机会踩雷。

使用特权

评论回复
18
ayb_ice| | 2011-3-3 13:32 | 只看该作者
LS
是否修改全局变量,不影响编译器对一个函数是否是重入函数的判断,那是程序员的事。。。
简单的说加重入关键字reetrant的函数是重入函数,但实际执行结果不一定是正确的,但他确实是重入函数,因为有些行为编译器无法控制,只能假定是可以的,编译器只能控制他自己的行为,有些事情是程序员的事情。。。

使用特权

评论回复
19
XIANSir|  楼主 | 2011-3-3 13:56 | 只看该作者
18# ayb_ice
严重同意ayb_ice大侠的观点!
虽然表面上只要加一个reetrant关键字就把函数提升为可重入函数了,看起来很简单,也很诱人,可是我看到网上介绍reetrant实现可重入的原理竟然是:由KEIL产生代码来模拟一个堆栈,来实现函数的可重入。
我立即就被吓晕过去了:lol

使用特权

评论回复
20
XIANSir|  楼主 | 2011-3-3 14:36 | 只看该作者
本帖最后由 XIANSir 于 2011-3-3 14:40 编辑

17# hgjinwei
呵呵,大侠想的很全面。
尤其第二段中关于修改全局变量的函数的可重入性问题的提出,倒是提醒了我。

结合你和ayb_ice大侠的帖子,我有了下面的想法:
reetrant关键字相关的函数可重入性问题和修改全局变量的函数的可重入性问题是两个不同的问题,reetrant相关的可重入性问题是Keil特有的,是由于Keil编译器为了尽量节省51单片机上稀缺的RAM资源而使用局部变量覆盖技术导致的,所以,Keil不得不搞出一个reetrant关键字来有选择的禁用局部变量覆盖特性——因为这导致函数不可重入。而全局变量(保护static局部变量)相关的可重入问题,则是所有的C语言(以及许多其他语言)编程都要面对的问题,如下面ayb_ice大侠所说,解决这个问题只能靠程序员自己,编译器无能为力。

而解决可重入性问题的最最最彻底的方法:完全禁止中断
不管什么类型的可重入性问题,只要完全禁止中断,所有的问题立刻迎刃而解——因为没有中断,函数就没有可重入的必要。

当然了,对于我这种函数只在中断中被调用的情况,解决此函数可重入性问题的最最最彻底的方法就变成了:完全禁止中断嵌套,道理同上

所以,解决我的问题的最佳方法就是:完全禁用中断嵌套

至于大侠说的别人修改中断优先级,我认为,修改代码的人要为自己的行为负完全责任,与俺无关:lol

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:冷暖自知,泰然处之;持之以恒,必有所成!

0

主题

609

帖子

2

粉丝