Микроконтроллер должен выполнять несколько несложных задач, например, общаться с медленными внешними устройствами и при этом долго ожидать флаги.
Например
void Task1()
{
runStage1();
while (!flagStage1Complete); // ожидание 1 с
runStage2();
while(!flagStage2Complete); // ожидание 1 с
finishTask1();
}
void Task2()
{
runStageA();
while (!flagStageAComplete); // ожидание 1 с
runStageB();
while(!flagStageBComplete); // ожидание 1 с
finishTask2();
}
void main()
{
while (1)
{
Task1();
Task2();
}
}
В простейшем варианте каждый Task будет выполняться раз в 4 секунды. Очевидно, что во время ожидания флагов в Task1() можно делать полезную работу или заодно проверять флаги из Task2() и наоборот. Но такой подход сильно свяжет Task1 и Task2 которые по логике программы могут вообще не иметь друг к другу отношения.
Обычно я эту проблему решаю с помощью switch
Например:
void Task1()
{
static int task1state=0;
switch (task1state)
{
case 0:
runStage1();
task1state=1;
break;
case 1:
if (flagStage1Complete)
{
runStage2();
task1state=2;
}
break
case 2:
if (flagStage2Complete)
{
finishTask1();
task1state=0;
}
break;
}
}
Task2 оформляется похожим образом.
Функция состоит из отдельных стадий. При проверке флага, происходит выход из функции и переход к другой. Возвращение в функцию происходит в точку проверки флага.
При такой организации каждый Task выполняется раз в 2 секунды.
До некоторого времени такой подход себя оправдывал. пока каждый Task был довольно простым. Если же Task содержит множество стадий и разветвлённую логику, то огромный switch() становится нечитабельным.
Хочется писать Task в виде простой и читабельно функции:
runStageA();
waitforStageAComplete()
runStageB();
waitForStageBComplete()
finishTask2();
Но при этом, чтобы во время ожидания происходил выход из функции и переход к другому Task()
Можно написать планировщик, который будет запускать Task1, а функции waitFor...() будут прерываниями выходить в планировщик. Затем планировщик должен будет переключить контекст (стеки, регистры и т.п.) на Task2 и запустить его.
Кажется, это очень сложно.
Есть ли какой-то простой способ?