Реентерабельная функция - PullRequest
0 голосов
/ 30 декабря 2018

Здравствуйте, в статье от https://www.embedded.com/design/operating-systems/4008268/2/Back-to-the-Basics--Practical-Embedded-Coding-Tips-Part-1, есть упоминание о том, как сделать функцию повторного ввода.

long i; 
void do_something(void){ 
    disable_interrupts();
    i+=0x1234; 
    enable_interrupts();
}

Автор сообщает: "Это решение не работает. Если do_something () - это общая процедура, которая, возможно, вызывается из многих мест и вызывается с отключенными прерываниями; она возвращается после их повторного включения. Контекст машины изменяется, возможно, очень опасным образом. "

Я не понимаю, как именно изменился контекст машины опасно?Может ли кто-нибудь привести какой-то пример, где это может привести к пагубным последствиям, чтобы прояснить это?

1 Ответ

0 голосов
/ 30 декабря 2018

Обратите внимание, что do_something() можно вызывать как из мест, где прерывания разрешены, так и из мест, где прерывания уже отключены.Включение прерываний во втором случае противоречит ожиданиям вызывающего абонента очень опасным образом.

Что вам действительно нужно, так это сохранить предыдущее состояние прерываний при их отключении и восстановить его после этого.

Итак, лучшая версия будет:

long i; 
void do_something(void){ 
    irq_state_t prev_int_state = disable_interrupts_save();
    i+=0x1234; 
    restore_interrupts(prev_int_state);
}
...