5

我用 atmega168a-pu 和中断开发了一个 C 应用程序。我使用以下中断:

ISR(TIMER0_COMPA_vect);
ISR(TIMER0_COMPB_vect);
ISR (TIMER2_COMPA_vect);
ISR(SPI_STC_vect);
ISR(TIMER1_COMPA_vect);
ISR (PCINT1_vect);

我的代码看起来像

int main(void){
///initialization etc.
   sei();
   while(1){
    ///do some stuff and wait the interrupts
   }
return 0;
}

我想在发生中断时阻止所有其他中断,并在退出中断功能之前启用中断。

您能否在代码片段上解释一下我该怎么做?

编辑:http : //www.nongnu.org/avr-libc/user-manual/optimization.html#optim_code_reorder 指出这种用法会导致重新编码问题。

function(){
  cli();
  ..
  sei();
}
4

2 回答 2

2

我之前在这里发布的答案是基于原始问题,没有提到 avr-gcc 的重新排序问题。显然,我使用 AVR 已经太久了,但是关于禁用中断的铃声响起

修改后的问题答案

保护中断不被打断

Atmel 在数据手册中写到了中断处理:

发生中断时,全局中断使能 I 位被清零,所有中断均被禁用。用户软件可以将逻辑 1 写入 I 位以启用嵌套中断。然后所有启用的中断都可以中断当前的中断程序。执行中断返回指令(RETI)时,I 位自动置位。

因此,您要求的行为已经在硬件中实现。

重新排序问题

我还对这个重新排序问题进行了一些调查。显然,这是否是编译器的错误存在巨大分歧。似乎重新排序的主要风险是中断被禁用的时间比预期的要长。在我的研究中,除了导致更多加载/存储活动的解决方案之外,我没有找到解决方案,我认为这不是一个真正的选择。

于 2013-07-16T16:36:39.670 回答
1

这里的问题有点奇怪,因为中断的默认行为是在处理中断时禁用新的中断(因为不会触发)。

关于编写不能被中断的代码,我通常发现只使用<util/atomic.h>. 如果这还不够,并且您确实必须确保没有重新排序,那么您可以在汇编中编写关键部分。

您可能会使用内存屏障,同时使该代码部分中的所有内容都变得易失,但在许多情况下,这将是一个相当大的悲观情绪。由此生成的程序集可能暗示如果您要手动编写程序集,您将编写什么。

于 2014-11-23T21:39:31.540 回答