摇滚固定计时器中断处理

时间:2014-03-24 18:36:21

标签: interrupt microcontroller race-condition avr

我需要以固定的时间间隔执行一个程序。该过程需要很长时间才能执行,在此期间其他中断必须处于活动状态。此外,在每次定时器溢出时执行该过程至关重要。

看看这个伪代码:

ISR(timer_overflow)
{
  timer_flag = 1;
}

main_loop()
{
  if (timer_flag)
  {
     long_time_consuming_procedure();
     timer_flag = 0;
  }
  (* if a timer interrupt fires here, will the procedure be executed? *)
  sleep();
}

如果以上内容不起作用,下面的代码会让事情变得坚如磐​​石吗?

main_loop()
{
  cli();
  if (timer_flag)
  {
     sei();
     long_time_consuming_procedure();
     timer_flag = 0;
  }
  sei();
  sleep();
}

或者这可能会更好,因为其他中断处理得非常快:

ISR(timer_overflow)
{
  sei();
  long_time_consuming_procedure();
}

main_loop()
{
  sleep();
}

我正在使用avr-gcc

修改

看起来我分享的细节太少了。我害怕这种最糟糕的情况:

  • 某些中断(除了计时器溢出)唤醒了uc
  • 由于没有计时器溢出,
  • long_time_consuming_procedure未被调用
  • 就在cpu重新进入睡眠状态之前(if (timerflag)sleep()之间),计时器溢出
  • 定时器中断正确执行
  • 从ISR cpu返回后进入睡眠而不执行long_time_consuming_procedure,因为我们已经通过if (timerflag)
  • 以下定时器周期没有其他中断,因此cpu在下一次溢出后被唤醒

这种方式有两个定时器中断,只有一个long_time_consuming_procedure执行。发生这种情况的可能性非常小,但如果出现问题,情况会更糟。

4 个答案:

答案 0 :(得分:0)

通常,数字1是最常见的解决方案。因为它允许您的程序执行,而其他中断仍然处理。

应该避免使用2号,因为打开和关闭中断不是很好的做法。有边缘情况,但需要更多的细节,为什么数字1不起作用。

在执行长时间运行的过程时,数字3不允许其他中断处于活动状态,因此应该避免它,因为其他中断不会在ISR中处理。

答案 1 :(得分:0)

您没有为特定答案提供足够的信息。如果要求是,你的long_time_consuming_procedure()只是每个间隔执行一次,但是当它在那段时间完成时它是无关紧要的,我会去找解决方案#1。

确保在long_time_consuming_procedure()处理期间可能发生的所有中断的long_time_consuming_procedure()+执行时间的执行时间短于计时器间隔。

即使一般概念非常简单,但有时候使基于中断的代码完全符合要求也是非常重要的。您必须仔细评估每个中断和个别要求。

答案 2 :(得分:0)

如果你想在每次定时器溢出时执行程序,并且在执行过程中有可能发生中断,请使用:

ISR(timer_overflow)
{
  timer_flag = 1;
}

main_loop()
{
  if (timer_flag)
  {
     cli();
     timer_flag = 0;
     sei();

     long_time_consuming_procedure();
  }
  sleep();
}

答案 3 :(得分:0)

在AVR Libc用户手册中,sleep.h的详细说明中我找到了一个例子:

  

set_sleep_mode(<mode>); cli(); if (some_condition) { sleep_enable(); sei(); sleep_cpu(); sleep_disable(); } sei();

     

此序列确保在禁用中断的情况下对some_condition进行原子测试。如果满足条件,则将准备睡眠模式,并且将在SEI指令之后立即调度SLEEP指令。 由于SEI保证在中断触发之前执行,因此可以确保设备真正进入休眠状态。

sleep_enable()和朋友

的帮助下,看起来胜利者是#2