关于STM32,一次中断,多次进入中断服务函数的问题说明

2019-08-14 20:17发布

以战舰板的例程(实验8,定时器中断实验)说明:
该例程,定时3中断服务函数如下:
//定时器3中断服务程序   void TIM3_IRQHandler(void) {           if(TIM3->SR&0X0001)//溢出中断 { LED1=!LED1;               }    TIM3->SR&=~(1<<0);//清除中断标志位     } 仿真如下图:
 仿真得出的结论是,第一个断点进入一次,第二个断点会多次进入.
当我们改成:

改成这样以后,就会发现,2个断点,每次中断只会进入一次,而不会像之前的情况,多次进入了.

这个问题,ST官方已经给出了答案:
Q: When I cleared the interrupt as the last instruction in the ISR, 
the ISR code is called immediately upon exit half the time. Is there a 
possibility of race condition ?

Answer:
The core (Cortex-M3) generates bufferable write transfer. This mean 
that the CPU consider that the data is written from an AHB point of 
view while the APB write transfer is managed by the AHB2APB bridge and 
could be written later. In this case the CPU left the interrupt 
routine while the interrupt is not yet cleared the CPU will re-enter  
again on the interrupt handler. To avoid this race condition :

1) ISR routine has to clear the interrupt  peripheral flag when just 
entering in the routine to avoid interrupt missing.

2)ISR routine has to Implement a write to the APB  peripheral register 
( to clear the peripheral flag) then followed by a read  access to the 
same register/flag. This operation will force the write buffer to 
complete the effective write and will stall the CPU until the 
effective write of the bit in the register. Therefore  it is 
independent from the AHB/APB ratio prescaler.
Here an example :

STR R1, [R0, #0] ; Store R1 register  peripheral   register  ( or 
using bit-banding peripheral address) 

LDR R2, [R0, #0] ; Load the peipheral register; This will  hold the 
CPU until the effective write of R1.

Use Cortex-M3 Bit-banding feature for interrupt clearing since it is 
an atomic operation and NVIC pending interrupts will be ignored during 
this operation, however Read-Modify-Write is not.


CPU从AHB的角度来看,数据已经写入(清零SR标志),实际上APB上的写操作需要由AHB2APB桥来管理,需要一定时间才能真正完成写操作(SR才能被清零)。那么当CPU退出中断ISR,此时SR还没有真正被清零,此时对应的pending bit仍旧置位,于是又一次触发了中断。


所以,大家如果想避免一次中断,多次进入,可以采取如下办法:
)进入中断后,判断了相应标志位,就clear之,在作后续的处理。 2)如果你硬是要把清标志放在ISR最后,那么为了避免以上情况的发生,写完SR后,再读出来




友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。