我有一个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);
}
答案 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;