Блокировка внутри корпуса переключателя - PullRequest
0 голосов
/ 07 января 2020

Во встроенной системе, работающей под управлением freertos, есть ли причина, по которой у вас не будет блокирующей функции в случае оператора switch?

Например, поток, проходящий через конечный автомат и один из Состояния - это ожидание уведомления о задаче.

Как правило, я делал это с помощью if-else, но есть ли какое-то преимущество или недостаток в том, чтобы сделать его регистром переключения?

Использование cpp17 и избегание STL.

Редактировать: функция блокировки, т. Е. Функция, которая работает вечно до получения уведомления, например, xTaskNotifyWait (...)

Пример:

switch (state)
{
case state1:
  foo();
  break;
case state2:
  xTaskNotifyWait(...);
};

vs

if (state == state1)
{
  foo();
}
else if (state == state2)
{
  xTaskNotifyWait(...);
}

TIA

1 Ответ

2 голосов
/ 07 января 2020

Вы можете использовать оператор switch или if. Там нет большой разницы. Вы можете блокировать вызовы в любом из них.

Я слышал, что в случаях переключения используются таблицы sh, а if-else - нет. Я не уверен, есть ли различия в коде asm, и какое влияние это окажет на размер кода, скорость и т. Д. c.

См. это , чтобы понять разница между переключателем и оператором if. Я цитирую один из ответов ниже:

Основное различие заключается в том, что переключение отправлений происходит немедленно в соответствующем случае, как правило, с помощью индексированного перехода, а не для оценки всех условий, которые потребуются в цепочка if-else, что означает, что код в конце цепочки достигается медленнее, чем код в начале.

Это, в свою очередь, накладывает некоторые ограничения на оператор switch, что цепочка if-else не ' t иметь: он не может обрабатывать все типы данных, и все значения регистра должны быть постоянными.

С помощью конструкции switch вы можете использовать дескриптивную enum для метки регистра, которая говорит, что это состояние должно быть blocking. Я бы лично использовал конструкцию switch, так как метка регистра может быть описательной.

enum state_e {
    INIT,
    WAITING_FOR_EVENT
};

switch (state) {
case INIT:
{
  foo();
  state = WAITING_FOR_EVENT;
  break;
}
case WAITING_FOR_EVENT:
{
  xTaskNotifyWait(...);
  // Change State
  break;
}
};
...