FreeRTOS中的状态机程序设计-vTaskStartScheduler中的switch语句 [英] State machine program design in FreeRTOS - vTaskStartScheduler in a switch statement

查看:444
本文介绍了FreeRTOS中的状态机程序设计-vTaskStartScheduler中的switch语句的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在FreeRTOS中有一个程序设计问题:

I have a program design question in FreeRTOS:

我有一个具有4个状态和6个任务的状态机.在每种状态下,必须执行不同的任务,但Task1除外,该任务始终处于活动状态:

I have a state machine with 4 states, and 6 tasks. In each state, different tasks must be executed, excepting Task1, which is always active:

状态1:任务1,任务2,任务3
状态2:Task1,Task2,Task3,Task4
状态3:Task1,Task5
状态4:Task1,Task6

State 1: Task1, Task2, Task3
State 2: Task1, Task2, Task3, Task4
State 3: Task1, Task5
State 4: Task1, Task6

Task1,Task3,Task4,Task5和Task6是周期性的,并且每个读取一个不同的传感器.
Task2是非周期性的,仅在达到阈值时才发送GPRS警报.

Task1, Task3, Task4, Task5 and Task6 are periodic, and each one reads a different sensor.
Task2 is aperiodic, it sends a GPRS alarm only if a threshold is reached.

状态之间的切换取决于每个任务的传感器输入中的事件.

The switching between the states is determined by events from the sensor input of each task.

main()设计的最初方法是使用一个开关来控制状态,并根据状态挂起并激活相应的任务:

The initial approach for the design of main() is to have a switch to control the states, and depending on the state, suspend and activate the corresponding tasks:

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语句.

My question is: where should I call vTaskStartScheduler(), in relation with the switch? It seems to me that in this code, once the vTaskStartScheduler is called, the program will never enter the switch statement.

我是否应该创建另一个始终处于活动状态以控制状态机的任务,该任务内部具有先前的while和switch语句,例如下面的伪代码?

Should I create another task always active to control the state machine, which has the previous while and switch statements inside, such as the following pseudocode?

task_control()
{
    while(true)
    {
        switch STATE:
            case 1: 
                   suspend(Task4, Task5, Task6);  
                   execute(Task2, Task3); 
            and so on...
    }
}  

任何建议将不胜感激...

Any advice will be much appreciated...

推荐答案

为回答您的问题,顾名思义,vTaskStartScheduler()将启动调度程序.此后的任何代码仅在调度程序停止时才执行,在大多数情况下是在程序结束时执行,因此永远不会执行.这就是为什么您的switch无法运行的原因.

To answer your question, vTaskStartScheduler() will, as the name suggests, start the scheduler. Any code after it will only execute when the scheduler is stopped, which in most cases is when the program ends, so never. This is why your switch won't run.

正如您已经躲过的那样,对于您的设计,您可以使用主要"任务来控制其他任务.您需要先创建此程序并在调度程序中注册它,然后再调用vTaskStartScheduler().

As you have already eluded to, for your design you could use a 'main' task to control the others. You need to have created this and registered it with the scheduler before calling vTaskStartScheduler().

另一方面,如果您采用这种方法,则只想在首次进入状态时暂停/恢复任务,而不是在主"任务的每次迭代中都暂停/恢复任务.

On a side note, if you do go with this approach, you only want to suspend/resume your tasks on first entry into a state, not on every iteration of the 'main' task.

例如:

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;
}

这篇关于FreeRTOS中的状态机程序设计-vTaskStartScheduler中的switch语句的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆