打印
[STM8]

一个关于STM8中断应用异常的话题

[复制链接]
428|30
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
AD, ST
某日一工程师跟我反映,他在使用STM8S芯片开发产品,用到某ADC通道,使用连续采集模式,开启ADC转换结束中断。整个中断程序执行时间大概200多us,因为连续采集转换,在这个ISR处理过程中可能会有新的EOC标志产生。
他发现一个奇怪的现象,ADC中断服务程序能够不停的自己嵌套自己,仿佛进入了递归嵌套,最后导致堆栈溢出跑飞而令系统复位。在调试过程中也的确能发现ADC中断服务程序有连续多次入栈的情况。


后来他发现这个异常跟在ADC ISR中首尾分别加了一句关中断和开中断语句有关。即在ISR的开头加了disableInterrupt(); ISR结尾部分加了 enableInterrupt();


如果拿掉首尾那2句开关中断的代码就一切正常。现在最大的疑问就是为什么加了这两句开关中断代码会导致ADC中断服务程序能自己嵌套自己?按道理说应该没有影响才对啊?

使用特权

评论回复
沙发
米多0036|  楼主 | 2021-12-31 15:52 | 只看该作者
关于中断函数不少人可能会这样写,在ISR的首尾分别加上关中断和开中断指令,尤其51系列过来的人,经常会在进中断后来一句CLR EA,中断退出之前补一句 SETB EA之类的指令。51系列芯片那样写是没有问题的。

使用特权

评论回复
板凳
米多0036|  楼主 | 2021-12-31 15:54 | 只看该作者
那对于STM8芯片来讲,这样写很可能就会出问题。有时或许有跟上面一样的写法而没有出问题,那是因为你程序简单没有复杂的多中断响应事件,或者说即使某时段只有单一中断源,但在中断响应过程中并无新的中断请求发生。

说实在的,要解释上面工程师的疑问,有点说来话长。不妨先直接说出原因,有兴趣的话就细看技术资料或下面的分析。

显然,问题就出在他在ISR里面做了关中断、开中断的操作,随意了改变正在执行的中断服务程序的中断优先级而导致的问题。

使用特权

评论回复
地板
米多0036|  楼主 | 2021-12-31 15:54 | 只看该作者
那个disableInterrupt();函数所对应的汇编指令就是SIM,该指令就是关闭所有可屏蔽的中断请求,此时执行程序所处中断优先级为L3,即软件中断禁用级。正因为如此,此时不会发生RESET/TRAP/TLI以外的中断。

使用特权

评论回复
5
米多0036|  楼主 | 2021-12-31 15:55 | 只看该作者
下面截图是STM8技术手册关于SIM指令的描述。在复位后的程序开始使用该指令是没用的。【为什么没用呢,因为程序复位后所处中断优先级就是L3。等会下面还会提到。】

红色方框内那句明确说明,在中断执行程序的开头不需使用该指令【SIM】,因为当前中断程序的优先级已经被自动的在CC寄存器中L1,L0位设定。【到底怎么设定自动的呢,下面文字在讲ITC_SPR寄存器时有描述。】

使用特权

评论回复
6
米多0036|  楼主 | 2021-12-31 15:56 | 只看该作者
再来看看 enableInterrupt(); 其实它所对应的汇编指令就是 RIM.该指令就是解除所有中断屏蔽,允许各路中断请求。执行该指令后,此时执行程序所处中断优先级为L0,即主程序运行级别,属于最低优先级别。换句话说,此时任何新的或待处理的中断请求都可以中断或打断当前的执行程序。

使用特权

评论回复
7
米多0036|  楼主 | 2021-12-31 15:57 | 只看该作者
下面是STM8相关技术手册对RIM指令的描述。它说该指令一般放在复位之后的主程序代码里,并提示在WFI/HALT指令前无须使用该指令。【此处并未对该提示作细节展开。它意思是说WFI/HALT指令还具备跟RIM指令同样的解除中断屏蔽、允许中断请求的功效。】

使用特权

评论回复
8
米多0036|  楼主 | 2021-12-31 16:02 | 只看该作者

使用特权

评论回复
9
米多0036|  楼主 | 2021-12-31 16:04 | 只看该作者
好,那我们结合上面案例具体分析下。

先假设上面那位工程师对ADC中断的软件优先级设置为2.【当然也可设置为3或1】

当ADC产生EOC中断请求进入中断服务程序【ISR】后,他首先来个SIM指令【即disableInterrupt();】,此时ISR程序不管刚才响应时刻的中断优先级是多少,现在被强行更改变为L3。从这点看,这个指令用得就显得随意或任性,在有多个中断源的情况下,有可能无意中改变了设计者关于各个中断响应轻重缓急的先后秩序的初衷。

继续回到这个话题。当ADC ISR执行一定时间后,在IRET返回前他又来个RIM指令。前面我们介绍了RIM指令的作用,此时ISR的中断优先级又由刚才的L3跳到L0,即最低软件优先级。可此时外边侯着的新的ADC EOC中断请求,它的软件中断优先级一定高于L0,机会来了,不用等本次ISR执行完,立即嵌套进入下一轮ADC ISR 程序。每进一次还要压一次栈,这样多次循环下去,直至堆栈穿底,PC乱飞,系统崩溃复位。

使用特权

评论回复
10
米多0036|  楼主 | 2021-12-31 16:06 | 只看该作者
原因大致就这样,不要想当然、随意地在ISR里面添加些影响执行程序优先级的指令,换句话说你在使用类似SIM/RIM指令时一定要心里清楚在做什么,有什么目的,会对当前中断程序优先级产生什么影响。


如果希望在执行某中断程序时不要被其它可屏蔽的中断请求打断,怎么办呢?很简单,将相关中断的ITC_SPR寄存器中相应软件优先级位配置为L3即可。当中断程序执行完毕退出后再回到之前的软件中断优先级。


关于STM8中断原理,个人觉得技术资料讲得不是很细致。这里根据个人的理解做了个简单的总结,一起分享下。并在后面用个实例验证上面的分析结论。

使用特权

评论回复
11
米多0036|  楼主 | 2021-12-31 16:09 | 只看该作者
STM8中断可分为不可屏蔽中断和可屏蔽中断。不可屏蔽中断是指RESET,TRAP,TLI.可屏蔽中断是指那些基于GPIO的外部中断和其它外设中断。

使用特权

评论回复
12
米多0036|  楼主 | 2021-12-31 16:09 | 只看该作者

使用特权

评论回复
13
米多0036|  楼主 | 2021-12-31 16:13 | 只看该作者
中断优先级分硬件优先级和软件优先级。硬件优先级是固定的,参照各芯片数据手册里的中断矢量表的序号来定,序号越小硬件优先级越高。各中断源或事件的软件中断优先级可以通过寄存器编程配置,其中RESET,TRAP非屏蔽中断事件无软件中断优先级。

使用特权

评论回复
14
米多0036|  楼主 | 2021-12-31 16:27 | 只看该作者
中断的管理主要基于两个寄存器,一个是CCR,一个是ITC_SPRx. 其中CCR寄存器中的L1和L0位表示当前程序执行代码所处中断优先级。ITC_SPRx.各寄存器分别对应各个中断服务程序的软件中断优先级,用户可自行配置各中断服务程序所处的中断优先级。软件中断优先级分为4级,从低往高依次是LEVEL0,LEVEL1,LEVEL2,LEVEL3,分别对应CCR寄存器中的L1、L0位的10,01,00,11。

L0级即用户主程序级,就是程序处在按部就班的用户主程序代码执行状态,为最低软件优先级。此时CCR寄存器中的L1、L0为10。

L3级又称软件中断禁用级。这个地方的表述和理解可能有点费劲。在L3软件中断优先级状态下,不会发生软件中断,即所谓的中断关闭状态。此时CCR寄存器中的L1、L0为11。其中,RESET\TRAP\TLI三个中断源是特例,可以打断L3优先级状态下的执行程序而产生中断。

总之,STM8芯片任何时刻的程序执行总处于某一软件中断优先级状态,其软件中断优先级由当前CCR寄存器中的L1、L0位决定。理解这个概念很重要。

使用特权

评论回复
15
米多0036|  楼主 | 2021-12-31 16:30 | 只看该作者
下面截图是对CCR寄存器描述,系统复位后的默认值为0x28,对应到L1\L0就是11。即系统复位后中断软件优先级为L3,软件中断禁用级,也就是中断关闭状态。这也正好印证了上面讲SIM指令时,芯片复位后使用SIM没啥意义。因为芯片复位后程序执行就处于软件中断禁用级。

使用特权

评论回复
16
米多0036|  楼主 | 2021-12-31 16:31 | 只看该作者

使用特权

评论回复
17
米多0036|  楼主 | 2021-12-31 16:42 | 只看该作者
上面提到,各个可屏蔽中断源的软件中断优先级可以通过ITC_SPRx 寄存器进行配置。一共8个ITC_SPR寄存器,每个寄存器最多可以配置4个中断源的软件中断优先级。当某中断请求得到响应时,该寄存器里相应中断源的VECTnSPR[1:0] 两位数据会自动载入到CCR寄存器中的L1、L0位进而决定该中断服务程序所处软件中断优先级。所以,在各中断服务程序里除非有需要,不要在中断服务程序里随意使用类似SIM/RIM这些导致改变执行程序中断优先级的指令。否则,程序优先级改变了而自己可能还不知晓。

使用特权

评论回复
18
米多0036|  楼主 | 2021-12-31 16:43 | 只看该作者

使用特权

评论回复
19
米多0036|  楼主 | 2021-12-31 16:46 | 只看该作者
我们说中断,提优先级,无非就是为了拟定妥善处理多个中断事件发生竞争时的处理规则。对于STM8芯片,在同一时刻多个中断请求发生时,响应规则如下:

中断请求中相对最高软件优先级的中断先响应;

如果软件优先级一样,硬件优先级相对最高的先响应;

使用特权

评论回复
20
米多0036|  楼主 | 2021-12-31 16:52 | 只看该作者

使用特权

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

本版积分规则

73

主题

1163

帖子

0

粉丝