FreeRTOS初始上下文切换

3
我正在尝试理解在freeRTOS上简单的两个任务模型的工作流程。为了更清晰,以下是伪代码:
任务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 (任务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( ;; );
}

假设任务A和任务B都在主函数中创建,调度程序的调用会被执行(在所有任务创建之后)。如果在任务创建之前没有调用调度程序,那么调用调度程序将如何执行?或者简单地说,当执行从主函数开始时,是什么导致控制权从任务A和任务B中退出,以便稍后调用调度程序?如果我理解有误,请纠正我。

1
我并不清楚你在问什么。请编辑问题以提供更多信息,可能添加伪代码以澄清你的困惑所在。 - Ross
3个回答

4
任务创建后并不会立即开始执行。创建任务仅仅是放置了调度器需要知道的数据结构和信息。任务只有在调度程序运行其中一个任务时才开始执行。
在你的示例中,主函数 `main` 正在执行。主函数调用任务创建函数来构建和初始化任务数据结构。它不会运行任务,而是返回到主函数 `main`。然后,主函数 `main` 再次调用任务创建函数,并再次返回到主函数 `main`。最后,主函数 `main` 调用调度程序,调度程序选择最高优先级的准备运行的任务并开始执行该任务。调度程序不会返回到主函数 `main`。

1

首先,主函数开始执行。它调用xTaskCreate函数,该函数仅创建任务1(处于就绪状态),然后返回到主函数,再次调用xTaskCreate函数,该函数仅创建任务2(处于就绪状态),然后返回。在vTaskStartScheduler()函数执行后,调度程序将根据优先级(选择的调度算法)安排这两个任务。最高优先级的任务将首先从就绪状态转换为运行状态,并开始执行作为参数传递的任务函数(TaskA或TaskB),同时调用xTaskCreate。


0

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

    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 用于返回一个句柄,通过该句柄可以引用已创建的任务。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接