Bootstrap

FreeRTOS操作系统(详细速通篇)——— 第五章

         本专栏将对FreeRTOS进行快速讲解,带你了解并使用FreeRTOS的各部分内容。适用于快速了解FreeRTOS并进行开发、突击面试、对新手小白非常友好。期待您的后续关注和订阅!

目录

任务挂起和恢复函数

1 任务挂起和恢复函数简介

1 任务挂起

2 任务恢复

3 任务中断中恢复

2 实例讲解

3 函数内部实现状况(了解一下)

3.1 任务挂起函数

3.2 任务恢复函数


任务挂起和恢复函数

1 任务挂起和恢复函数简介

        任务挂起和主要用到以下三个函数进行操作:

API函数

注释

vTaskSuspend()

挂起任务

vTaskResume()

恢复被挂起的任务

xTaskResumeFromISR()

在中断中恢复被挂起的任务

  1. 挂起任务:通俗的进行解释,挂起相当与把任务给暂停了,无法进行运行。只有当任务被函数恢复后才能进行运行。
  2. 恢复挂起任务:字面意思,将挂起的任务进行恢复
  3. 中断中恢复挂起任务:该任务在中断中进行恢复函数,凡事带有FromISR的API函数均是中断专用的函数。

1 任务挂起

        任务非常简单,需要采用此任务时候,需要将宏定义INCLUDE_vTaskSuspend  配置为 1后,才可以使用。句柄中写入需要挂起的参数,当传入的参数为NULL时,代表将自身任务挂起。        

        无论其优先级别有多高,都不再执行,除非任务被恢复。

void vTaskSuspend(TaskHandle_t xTaskToSuspend)

形参

描述

xTaskToSuspend

待挂起任务的任务句柄

2 任务恢复

        在用此任务函数时,将INCLUDE_vTaskSuspend定义为 1,既可以使用。

        需要注意的是无论任务被挂起多少次,仅仅需要调用此函数一次就可以讲任务进行恢复。

void vTaskResume(TaskHandle_t xTaskToResume)

形参

描述

xTaskToResume

待恢复任务的任务句柄

3 任务中断中恢复

中断中恢复被挂起函数:

BaseType_t xTaskResumeFromISR(TaskHandle_t xTaskToResume

        在使用该函数的时候,需要INCLUDE_vTaskSuspend INCLUDE_xTaskResumeFromISR 必须定义为 1。并且该函数具备返回值,返回值类型如下所示

返回值

描述

pdTRUE

任务恢复后需要进行任务切换

pdFALSE

任务恢复后不需要进行任务切换

2 实例讲解

        该历程展示了在FreeRTOS中使用 vTaskSuspend()vTaskResume()xTaskResumeFromISR() 函数。任务主要内容如下:

  1.  任务1定期挂起和恢复任务2
  2. 在中断服务程序中,任务2也可以被恢复
  3. 任务2进行打印一些数据(用来展示挂起和恢复的情况)
#include "FreeRTOS.h"
#include "task.h"
#include "semphr.h"

TaskHandle_t xTaskToSuspendHandle = NULL; // 用于保存任务句柄
SemaphoreHandle_t xSemaphore = NULL; // 用于在中断中恢复任务

// 任务函数声明
void vTask1(void *pvParameters);
void vTask2(void *pvParameters);
void vISRHandler(void);

//定义两个任务
// 任务1:定期挂起和恢复任务2
void vTask1(void *pvParameters) {
    for (;;) {
        vTaskDelay(pdMS_TO_TICKS(1000)); // 延迟1秒
        vTaskSuspend(xTaskToSuspendHandle); // 挂起任务2

        vTaskDelay(pdMS_TO_TICKS(1000)); // 延迟1秒
        vTaskResume(xTaskToSuspendHandle); // 恢复任务2
    }
}

// 任务2:执行一些操作
void vTask2(void *pvParameters) {
    for (;;) {
        // 执行一些操作
        printf("Task 2 is running...\n");
        vTaskDelay(pdMS_TO_TICKS(500)); // 延迟500毫秒
    }
}

// 中断服务程序(ISR):恢复任务2
void vISRHandler(void) {
    BaseType_t xHigherPriorityTaskWoken = pdFALSE;
    xSemaphoreGiveFromISR(xSemaphore, &xHigherPriorityTaskWoken);
    xTaskResumeFromISR(xTaskToSuspendHandle);
    portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
}

//主程序
int main(void) {
    // 创建二值信号量
    xSemaphore = xSemaphoreCreateBinary();

    // 创建任务1
    xTaskCreate(vTask1, "Task 1", configMINIMAL_STACK_SIZE, NULL, 1, NULL);

    // 创建任务2,并保存任务句柄
    xTaskCreate(vTask2, "Task 2", configMINIMAL_STACK_SIZE, NULL, 2, &xTaskToSuspendHandle);

    // 启动调度器
    vTaskStartScheduler();

    // 如果一切正常,代码不会运行到这里
    for (;;) {
    }
    return 0;
}

3 函数内部实现状况(了解一下)

3.1 任务挂起函数

  1. 获取所要挂起任务的控制块: 通过传入的任务句柄,确定要挂起哪个任务。如果传入的句柄为 NULL,则表示挂起当前任务。

  2. 移除所在列表: 将要挂起的任务从它所在的状态列表(就绪列表或阻塞列表)和事件列表中移除。

  3. 插入挂起任务列表: 将待挂起任务插入到挂起态任务列表的末尾,以标记该任务现在处于挂起状态。

  4. 判断任务调度器是否运行: 如果任务调度器正在运行,则需要更新下一次的阻塞时间,以防止被挂起的任务成为下一次阻塞超时任务。

  5. 判断待挂起任务是否为当前任务: 如果挂起的是当前任务,并且调度器正在运行,则需要进行一次任务切换。如果调度器没有运行,判断挂起的任务数是否等于任务总数。如果是,则将当前任务控制块设为 NULL;否则,寻找下一个最高优先级的任务。

3.2 任务恢复函数

  1. 不能恢复正在运行的任务
  2. 检查任务是否在挂起列表中:如果在挂起列表中,则将其移除,并添加到就绪列表中。
  3. 判断恢复任务的优先级:如果恢复任务的优先级高于当前运行任务,则执行任务切换。

     

       本专栏将对FreeRTOS进行快速讲解,带你了解并使用FreeRTOS的各部分内容。期待诸君的订阅和关注!

;