Change priority level level of running interrupt handler?

前提是你 提交于 2021-01-27 05:49:23

问题


I am trying to implement the following pseudocode on a cortex-m3 controller, (STM32L151 in particular)

void SysTick_Handler() {
    do_high_priority_periodic_tasks(); // not to be interrupted
    lower_interrupt_priority();
    do_low_priority_periodic_tasks();  // these may be interrupted
}

In other words, run the first part with priority level 0, then somehow lower the current interrupt priority to 15, so that the rest could be preempted by other hardware interrupts.

One idea is to move do_low_priority_periodic_tasks(); into a separate interrupt handler, and invoke this handler through NVIC_SetPendingIRQ() which sets a pending bit in the NVIC->ISPR[] register. This way, the other interrupt would immediately follow SysTick, unless there is anything with priority between 0 and 14 pending.

#define LOWPRIO_IRQn 55
void IRQ55_Handler() {
    do_low_priority_periodic_tasks();  // these may be interrupted
}

void SysTick_Handler() {
    do_high_priority_periodic_tasks(); // not to be interrupted
    NVIC_SetPendingIRQ(LOWPRIO_IRQ);
}

void main() {
    HAL_Init();
    HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
    HAL_NVIC_SetPriority(LOWPRIO_IRQn, 15, 0);
    HAL_NVIC_EnableIRQ(LOWPRIO_IRQn);
    while(1) {
        /* main loop */
    }
}

I've picked IRQ 55 because it's not occupied on my controller, it would be the AES interrupt handler on a STM32L162, but I'm a bit worried there. Should I pick a different IRQ instead, perhaps an unused DMA channel interrupt? Is it safe to use interrupts 57-67, which are defined in the Cortex-M3 core, but not on the STM32L series? Is there any better way to do it?


回答1:


Is it safe to use interrupts 57-67, which are defined in the Cortex-M3 core, but not on the STM32L series?

No. Your NVIC may not actually implement them.

But the PendSV is exactly made for this task:

void SysTick_Handler() {
  do_high_priority_periodic_tasks(); // not to be interrupted
  // Set the PENDSVSET to trigger a PendSV exception
  SCB->ICSR |= SCB_ICSR_PENDSVSET_Msk;
}

void PendSV_Handler() {
    do_low_priority_periodic_tasks();  // these may be interrupted
}

See also this answer about PendSV.



来源:https://stackoverflow.com/questions/40747463/change-priority-level-level-of-running-interrupt-handler

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!