打印
[信息]

【实战经验】进入了已屏蔽的中断

[复制链接]
1003|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 香水城 于 2017-8-16 15:13 编辑

进入了已屏蔽的中断
问题:
某客户工程师在某型号新产品的设计中,使用了STM32F103XXT6。据其工程师讲述:他们在设计中,使用了一个外部中断,用来检测某事件的发生,从而唤醒低功耗模式下的 STM32。对应于该中断输入,有一中断服务程序,内容如表(一)所示。在实测中发现偶尔会发生在有该外部中断输入时 STM32 并未回到正常的运行状态的情况。测量此时 STM32 的功耗,发现其功耗明显增大,说明已从低功耗唤醒。使用调试工具调试,发现当出现该现象时,程序停留在表(一)所示的中断服务程序中,不能退出。进一步跟踪,发现“行(1)”的判断不能通过。进入函数 EXTI_GetITStatus 进一步检查,发现该函数如表(二)。继续跟踪,发现“行(2)”的判断不能通过,而原因是上一行中的 EXTI-> IMR&EXTI_Line 值为‘0’,也就是该中断使能位没有被打开。讲述至此,其工程师一再重复着一句话“为什么中断使能位关闭了,还能进入中断服务程序…”。再三安慰不能使其平静,或许他真的崩溃了。
调研:
天行有常,不为尧存,不为桀亡。我坚信这一点,所以我没有崩溃。检查其代码,找到了“行(3)”,相信是该行代码关掉了中断使能位。于是,建议其工程师修改代码:
1 . 将“行(1)”改为:if(EXTI_GetFlagStatus(IO_PIN_CHUCK) != RESET);
2. 在“行(3)”后插入语句:EXTI_ClearITPendingBit(IO_PIN_CHUCK) ;
如表(三)所示:

修改后重新测试,其工程师反馈结果说:问题解决了,但依然不能理解,为什么这样改动会带来结果的不同。之后就是不断重复的“为什么…为什么…”,仍在崩溃中…

结论:
至此,该下个结论了。其中断服务程序中有两处错误:
1. 选错了中断标志判定方法,应该检测中断请求位,而不能检测中断使能位;
2. 在屏蔽中断后,应该再次清除中断请求位,而其代码中没有。
第 1 点错误会导致对中断产生原因的判断失效,而第 2 点错误则导致缺少对管脚上信号抖动的预防能力。当外部中断的输入信号上有抖动时,STM32 会收到一连串的信号跳变,造成已清除的中断请求位被重新置起。在退出中断服务程序之后,由于中断请求仍在,所以会重新进入中断服务程序。而此时中断使能位已被清除,导致“行(1)”的判断不成立,从而中断服务程序不会对中断请求位做任何的处理,使得中断请求得以保留,最终发生中断服务程序无休止的重复进入的现象。。

处理:
修改代码,如表(三)。

建议:
对于 STM32 来说,除了由于外设的中断请求位没有清除之外,还有另外一种原因,也能导致重复进入中断服务程序。STM32 属于多时钟域系统,外设的信号到达 CPU 会有几个时钟节拍的延迟,造成外设撤消中断请求动作也会有延迟。如果中断服务程序过快的退出,而此时撤消中断请求的动作尚未被 CPU 认可,就会出现重入中断服务程序的现象。
对于这一现象,如果应用程序处理不当,也会导致错误。通常,我们可以通过判断外设的中断请求标志,来避免中断的重复处理。所以,在中断服务程序中,要做的第一件事就是检测中断请求标志,如果没有,则直接返回。这样,既便“中断服务程序重复进入”发生,也只是在中断服务程序中“空转一圈”,不会产生实质的后果。当然,在中断服务程序中要做的第二件事,就是清除该标志,不然,中断服务程序就不是“转一圈”或“转几圈”,而是“无穷多圈”。有时,在程序设计中,希望对中断的管理操作立即生效,而不能延后。这时,可以使用 CPU 对中断的管理机制,而不是通过对外设的操作来实现。比如,CPU 具有对全体中断或某个中断的使能控制,是即时生效的,因为整个 CPU 处于 同一个时钟域。

对应的PDF:进入了已屏蔽的中断
更多实战经验请看:ST MCU实战经验汇总贴
沙发
皈依| | 2015-8-26 10:01 | 只看该作者
细节决定成败啊 学习了

使用特权

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

本版积分规则

认证:意法半导体(中国)投资有限公司
简介:STM32技术专家

596

主题

17089

帖子

284

粉丝