Початкове запитання
У мене загальне питання щодо обробки перебоїв у мікроконтролерах. Я використовую MSP430, але я думаю, що питання може поширюватися і на інші UC. Мені хотілося б знати, чи є хорошою практикою включення / відключення переривань часто уздовж коду. Я маю на увазі, якщо у мене є частина коду, яка не буде чутливою до перерв (або ще гірше, не повинна слухати переривання з будь-якої причини), чи краще:
- Вимкніть переривання раніше, а потім повторно ввімкніть їх після критичного розділу.
- Поставте прапор всередину відповідного ISR і (замість того, щоб вимкнути переривання), встановіть прапор значення false перед критичним розділом і відновіть його до істинного, відразу після. Щоб запобігти виконанню коду ISR.
- Жодне з двох, тому пропозиції вітаються!
Оновлення: переривання та діаграми стану
Я надам конкретну ситуацію. Припустимо, ми хочемо реалізувати діаграму стану, яка складається з 4 блоків:
- Переходи / Ефект.
- Умови виходу.
- Вхідна діяльність.
- Займайтеся активністю.
Цьому нас навчав професор в університеті. Напевно, не найкращий спосіб зробити це, дотримуючись цієї схеми:
while(true) {
/* Transitions/Effects */
//----------------------------------------------------------------------
next_state = current_state;
switch (current_state)
{
case STATE_A:
if(EVENT1) {next_state = STATE_C}
if(d == THRESHOLD) {next_state = STATE_D; a++}
break;
case STATE_B:
// transitions and effects
break;
(...)
}
/* Exit activity -> only performed if I leave the state for a new one */
//----------------------------------------------------------------------
if (next_state != current_state)
{
switch(current_state)
{
case STATE_A:
// Exit activity of STATE_A
break;
case STATE_B:
// Exit activity of STATE_B
break;
(...)
}
}
/* Entry activity -> only performed the 1st time I enter a state */
//----------------------------------------------------------------------
if (next_state != current_state)
{
switch(next_state)
{
case STATE_A:
// Entry activity of STATE_A
break;
case STATE_B:
// Entry activity of STATE_B
break;
(...)
}
}
current_state = next_state;
/* Do activity */
//----------------------------------------------------------------------
switch (current_state)
{
case STATE_A:
// Do activity of STATE_A
break;
case STATE_B:
// Do activity of STATE_B
break;
(...)
}
}
Припустимо також, що, скажімо STATE_A
, я хочу бути чутливим до переривання, що виникає з набору кнопок (із системою дебютування тощо) тощо. Коли хтось натискає одну з цих кнопок, створюється переривання і прапор, пов'язаний з вхідним портом, копіюється в змінну buttonPressed
. Якщо для дебютації якимось чином встановлено 200 мс (таймер сторожового часу, таймер, лічильник, ...), ми впевнені, що buttonPressed
не можна оновити нове значення до 200 мс. Це я прошу вас (і я :) звичайно)
Чи потрібно ввімкнути перерву в діяльності DO STATE_A
та відключити його перед відходом?
/* Do activity */
//-------------------------------------
switch (current_state)
{
case STATE_A:
// Do activity of STATE_A
Enable_ButtonsInterrupt(); // and clear flags before it
// Do fancy stuff and ...
// ... wait until a button is pressed (e.g. LPM3 of the MSP430)
// Here I have my buttonPressed flag ready!
Disable_ButtonsInterrupt();
break;
case STATE_B:
// Do activity of STATE_B
break;
(...)
}
Таким чином, я впевнений, що наступного разу, коли я виконую блок 1 (перехід / ефекти) при наступній ітерації, я впевнений, що умови, перевірені під час переходів, не виходять із наступного переривання, яке перезаписало попереднє значення того, buttonPressed
що я потреба (хоча неможливо, що це трапляється, оскільки 250 мс має минути).