Cortex-M4中的SysTick异常可以自行抢占吗?

时间:2015-08-28 13:29:47

标签: c exception embedded cortex-m

我有一个SysTick异常的处理程序,它会计算滴答并调用其执行时间可能比SysTick时间长的其他函数(f1,f2,f3)。这些函数设置并清除它们的活动状态(全局变量),因此如果发生SysTick异常,它可以检测到过载并返回到被中断的函数。

我已将固定优先级分配给SysTick例外(让我们说16)。我希望以某种方式使SysTick能够生成异常而不管它之前的活动状态,转到SysTickHandler,增加tick计数器并返回到中断函数。

可能有用的一种解决方案是使用BASEPRI。它可以设置为低于SysTick的优先级,因此它将启用该异常。不幸的是,使用BASEPRI让我无处可去,因为没有发生任何事情(我将其设置为最大值)。在我更改它之前,在SysTickHandler中BASEPRI值为0。当处理器进入处理函数时,该值是否应该等于SysTick优先级? BASEPRI中是否自动加载了异常优先级?

我还考虑过NVIC在抢占已经激活的异常方面存在问题,但在ARM文档中没有发现任何相关问题。

此外,检测到oveload时从处理程序返回可以将处理器状态设置为线程模式。我们暂时忽略它。

void SysTickHandler(void) { 
    ticks++;
    //set_BASEPRI(max_value);
    if (f1_act || f2_act || f3_act) return;
    else {
        f1();
        f2();
        f3();
    }
}

这个问题(没有返回)的一个更简单的例子是在处理程序中有一个无限循环时增加tick计数器。

void SysTickHandler(void) {
    ticks++;
    set_BASEPRI(max_value);
    while(1);
}

2 个答案:

答案 0 :(得分:1)

如果中断在其处理程序已经运行时变为挂起,则处理程序将运行完成并立即重新进入。您的勾选将是非周期性的,并且如果函数一直需要更长的时间,那么您可能永远不会离开中断上下文。

我可能有可能在处理程序中增加中断的优先级,以便它自己抢占,但即使这样做,我也会毫不犹豫地推荐它。

听起来你真正需要的是RTOS。

答案 1 :(得分:0)

很抱歉让你失望,但这对我来说似乎是一个整体设计问题...

为什么你不想在SysTick中设置一些标志并在其他地方读取它?

像:

#include <stdbool.h>

volatile bool flag = false; 
//Consider any form of atomicity here
//atomic_bool or LDREX/STREX instructions here. Bitbanding will also work


void sysTickHandler(void) {
  ticks++;
  if (f1_act || f2_act || f3_act) return;
  else {
    flag = true;  //or increment some counter if you want to keep track of the amount of executions
  }

以及其他地方:

int main() {
  // some init code

  //main loop
  for(;;) {

   foo();//do sth
   bar(x); //do sth else

    if (flag) {
      f1();
      f2();
      f3();
      flag = false;
    }
  }
}

或者如果我们假设每个中断都会唤醒微控制器并且需要掉电模式,那么......这可能会起作用:

if (flag) {
  f1();
  f2();
  f3();
  flag = false;
}
goToSleep(powerDownModeX); //whatever;