Timer 重新发布系统中断
我有一个SysTick中断,每秒触发任务切换4次,如下所示Timer 重新发布系统中断,timer,arm,interrupt,cortex-m,Timer,Arm,Interrupt,Cortex M,我有一个SysTick中断,每秒触发任务切换4次,如下所示 void SysTick_Handler(void) { SCB->ICSR |= SCB_ICSR_PENDSVSET_Msk; // Set PendSV } main中的任务偶尔会通过其中一个UART输出一些消息,为了确保它们具有独占的I/O访问权限,输出例程使用一个由LDREX和STREX设置的互斥锁进行保护。代码在90%以上的时间都能正常工作 但是,该保护的一个副作用似乎是,当SysTick在设置互斥锁期间发生时
void SysTick_Handler(void) {
SCB->ICSR |= SCB_ICSR_PENDSVSET_Msk; // Set PendSV
}
main中的任务偶尔会通过其中一个UART输出一些消息,为了确保它们具有独占的I/O访问权限,输出例程使用一个由LDREX和STREX设置的互斥锁进行保护。代码在90%以上的时间都能正常工作
但是,该保护的一个副作用似乎是,当SysTick在设置互斥锁期间发生时,任务切换将不会发生,而此时正在运行的任务将继续运行,直到下一个任务切换
有没有办法在10毫秒后再次触发SysTick,直到当前运行的任务清除互斥锁?例如:
void SysTick_Handler(void) {
if (mutex) {
// set SysTick to trigger again in 10 ms
} else {
SCB->ICSR |= SCB_ICSR_PENDSVSET_Msk; // Set PendSV
}
}
如果是,如何进行
TIA在互斥释放功能中设置SysTick、PendSV、SVCall或其他一些挂起的中断
如果您想避免不必要中断的代价,您可以在systick处理程序中设置一个原子标志,并在互斥释放功能中检查它,这样您只有在错过预定运行时才会触发中断。我根据Tom V的建议实施了一个解决方案,它的效果非常好!!谢谢 关键部分:
void SysTick_Handler(void)
{
if (mutex > 0) {
sigint++;
} else {
sigint = 0;
SCB->ICSR |= SCB_ICSR_PENDSVSET_Msk; // Set PendSV to pending
}
}
以及:
但是,请注意,此解决方案至少有一个“特性”:如果此代码错过了一个以上的中断,它将只构成一个,但在我的情况下,错过一个以上的中断是极不可能的
// in mutex release
if (sigint) {
__asm(" CPSID i");
sigint = 0;
(*systick_ptr)();
__asm(" CPSIE i");
}