我在FreeRTOS中有一个程序设计问题:
我有一个状态机,有4个状态和6个任务。在每个状态中,必须执行不同的任务,但Task1除外,它始终处于活动状态:
状态1:任务1,任务2,任务3
状态2:Task1,Task2,Task3,Task4
状态3:任务1,任务5
状态4:任务1,任务6
Task1,Task3,Task4,Task5和Task6是周期性的,每个人都读取不同的传感器 Task2是非周期性的,只有达到阈值才会发送GPRS警报。
状态之间的切换由每个任务的传感器输入的事件决定。
设计main()的最初方法是使用开关来控制状态,并根据状态,暂停并激活相应的任务:
void main ()
{
/* initialisation of hw and variables*/
system_init();
/* creates FreeRTOS tasks and suspends all tasks except Task1*/
task_create();
/* Start the scheduler so FreeRTOS runs the tasks */
vTaskStartScheduler();
while(true)
{
switch STATE:
case 1:
suspend(Task4, Task5, Task6);
activate(Task2, Task3);
break;
case 2:
suspend(Task5, Task6);
activate(Task2, Task3, Task4);
break;
case 3:
suspend(Task2, Task3, Task4, Task6);
activate(Task5);
break;
case 4:
suspend(Task2, Task3, Task4, Task5);
activate(Task6);
break;
}
}
我的问题是:我应该在哪里调用与交换机相关的vTaskStartScheduler()?在我看来,在这段代码中,一旦调用了vTaskStartScheduler,程序就永远不会进入switch语句。
我是否应该创建另一个始终处于活动状态的任务来控制状态机,其中包含之前的while和switch语句,例如以下伪代码?
task_control()
{
while(true)
{
switch STATE:
case 1:
suspend(Task4, Task5, Task6);
execute(Task2, Task3);
and so on...
}
}
任何建议都将不胜感激......
答案 0 :(得分:1)
要回答您的问题,vTaskStartScheduler()
将顾名思义启动调度程序。之后的任何代码只会在调度程序停止时执行,这在大多数情况下是程序结束时,所以永远不会。这就是您switch
赢了的原因。
正如您已经想到的那样,对于您的设计,您可以使用' main'控制其他人的任务。您需要创建此项并在调用vTaskStartScheduler()
之前将其注册到调度程序。
另一方面,如果你采用这种方法,你只想在第一次进入状态时暂停/恢复你的任务,而不是在主要'的每次迭代中暂停/恢复你的任务。任务。
例如:
static bool s_first_state_entry = true;
task_control()
{
while (true)
{
switch (STATE)
{
case 1:
if (s_first_state_entry)
{
// Only do this stuff once
s_first_state_entry = false;
suspend(Task4, Task5, Task6);
execute(Task2, Task3);
}
// Do this stuff on every iteration
// ...
break;
default:
break;
}
}
}
void set_state(int state)
{
STATE = state;
s_first_state_entry = true;
}
答案 1 :(得分:0)
正如Ed King所说,你的解决方案包含一个主要的设计缺陷。也就是说 - 在启动调度程序之后,在调度程序停止之前,在main函数中指定的代码之后都不会执行。
我建议在空闲任务中实现您的状态逻辑(记住在您的任务中包含延迟,以免使Idle挂钩处于处理时间之外)。空闲任务可以根据信号量的menas当前状态阻止和解除阻塞任务。但请记住,Idle挂钩是具有最低优先级的任务,因此在设计系统时要小心。当任务占用大部分处理时间而不允许空闲任务切换状态时,我建议的解决方案可能完全错误。
或者,您可以创建Ed King所提及的优先任务,具有最高优先级。
说实话,一切都取决于任务的实际作用。