2016-11-22 3 views
5

Я пытаюсь реализовать следующий псевдокод на контроллере Cortex-M3 (STM32L151 в частности)Изменить уровень уровня приоритета для обработчика прерываний?

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

Другими словами, запустить первую часть с уровнем приоритета 0, то каким-то образом снизить текущий приоритет прерывания 15, так что остальные могут быть вытеснены другими аппаратными прерываниями.

Идея состоит в том, чтобы переместить do_low_priority_periodic_tasks(); в отдельный обработчик прерываний и вызвать этот обработчик через NVIC_SetPendingIRQ(), который устанавливает ожидающий бит в регистре NVIC->ISPR[]. Таким образом, другое прерывание немедленно будет следовать за SysTick, если только что-либо с приоритетом между 0 и 14 ожидает.

#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 */ 
    } 
} 

Я выбрал IRQ 55, потому что он не занят на мой контроллер, это будет обработчик прерываний AES на STM32L162, но я немного волнуюсь там. Должен ли я выбрать другой IRQ вместо этого, возможно, неиспользуемое прерывание канала DMA? Можно ли использовать прерывания 57-67, которые определены в ядре Cortex-M3, но не в серии STM32L? Есть ли лучший способ сделать это?

ответ

4

Можно ли использовать прерывания 57-67, которые определены в ядре Cortex-M3, но не в серии STM32L?

№ Ваша NVIC не может их фактически реализовать.

Но PendSV точно сделано для решения этой задачи:

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 
} 

Смотрите также эту answer о PendSV.

+0

Это именно то, что я ищу, спасибо – berendi

+0

Вы можете очень хорошо изменить приоритет. 'PendSV обычно используется для RTOS, а не для обработчиков пользовательских прерываний, поэтому он не будет доступен для нескольких обработчиков. Это совершенно не связано с использованием нереализованных прерываний. – Olaf

Смежные вопросы