FreeRTOS初始上下文切换

时间:2016-11-11 05:26:24

标签: operating-system kernel embedded scheduling freertos

我试图理解freeRTOS上简单的2任务模型的工作流程。为清晰起见,添加伪代码,

Task_A

void Task_A( void *pvParameters )
{
const char *pcTaskName = "Task_A is running\r\n";
    for( ;; )
    {
    vPrintString( pcTaskName );
    /* Delay for a period. */
    vTaskDelay( 250 / portTICK_RATE_MS );    
    }
}

Task_B

void Task_B( void *pvParameters )
{
const char *pcTaskName = "Task_B is running\r\n";
volatile unsigned long ul;
    for( ;; )
    {
    vPrintString( pcTaskName );
    /* Delay for a period. */
    vTaskDelay( 250 / portTICK_RATE_MS );
    }
}

int main( void )
{
    xTaskCreate( Task_A, "Task 1", 1000, NULL, 1, NULL );
    xTaskCreate( Task_B, "Task 2", 1000, NULL, 1, NULL );
/* Start the scheduler so the tasks start executing. */
vTaskStartScheduler();
    for( ;; );
}

假设两个任务,比如在主函数内创建Task_A和Task_B,则给出对调度程序的调用(成功完成所有任务)。如果在创建任务之前未调用调度程序,将如何执行调度程序调用?或者简单地说,当执行从main开始时,是什么导致控件从Task_A和Task_B中出来,以便稍后调用调度程序?如果我的理解有缺陷,请纠正我。

3 个答案:

答案 0 :(得分:4)

任务在创建时不会开始执行。创建任务只是简化了调度程序需要了解的有关任务的数据结构和信息。在调度程序运行其中一个任务之前,任务不会开始执行。

在您的示例中main正在执行。它调用任务创建例程来构建和初始化任务数据结构。它不会运行任务,而是返回main。然后main再次调用任务创建例程,它再次返回main。最后main调用调度程序,调度程序选择准备运行并开始执行该任务的最高优先级任务。调度程序不会返回main

答案 1 :(得分:1)

第一个main开始执行。它调用xTaskCreate,它只创建Task 1(处于就绪状态)并返回main,再次调用xTaskCreate,它只创建一个Task 2(处于就绪状态)并返回。执行vTaskStartScheduler()后,调度程序将根据优先级(选定的调度算法)调度两个任务。优先级最高的任务将首先从就绪状态进入运行状态并开始执行作为参数传递的任务函数(TaskA或TaskB)在调用xTaskCreate时。

答案 2 :(得分:0)

任务在创建时不会开始执行,但是无论调度程序是否在运行,您都可以在创建任务后立即处理其TaskHandle_t指针。为此,必须将“ * TaskHandle_t * const变量”作为 xTaskCreate 函数的第六个参数传递。

    BaseType_t xTaskCreate( TaskFunction_t pxTaskCode,
                            const char * const pcName,
                            const uint16_t usStackDepth,
                            void * const pvParameters,
                            UBaseType_t uxPriority,
                            TaskHandle_t * const pxCreatedTask )
  

pxCreatedTask 用于回传可用来引用创建的任务的句柄。