任务的挂起与恢复的API函数(熟悉)
- vTaskSuspend():挂起任务, 类似暂停,可恢复
- vTaskResume():恢复被挂起的任务
- xTaskResumeFromISR():在中断中恢复被挂起的任务
任务挂起函数
void vTaskSuspend( TaskHandle_t xTaskToSuspend )
- xTaskToSuspend:待挂起任务的任务句柄,为NULL表示挂起任务自身。
- 需将宏INCLUDE_vTaskSuspend配置为 1。
任务恢复函数
void vTaskResume( TaskHandle_t xTaskToResume )
- INCLUDE_vTaskSuspend必须定义为 1。
- 不论任务被使用 vTaskSuspend() 挂起多少次,只需调用 vTaskResume() 一次,即可使其继续执行。被恢复的任务会重新进入就绪状态。
任务恢复函数(中断中恢复)
函数说明
BaseType_t xTaskResumeFromISR( TaskHandle_t xTaskToResume )
返回值如下:
- pdTRUE:任务恢复后需要进行任务切换。
- pdFALSE:任务恢复后不需要进行任务切换。
注意事项
- INCLUDE_vTaskSuspend 和 INCLUDE_xTaskResumeFromISR 必须定义为 1。
- 在中断服务程序中调用FreeRTOS的API函数时,中断的优先级不能高于FreeRTOS所管理的最高中断优先级。
挂起与恢复调度器
- vTaskSuspendAll():挂起任务调度器,调度器不会进行任务切换,当前任务一直运行。
- xTaskResumeAll():恢复任务调度器,调度器继续任务切换。
查看任务状态
/* 开启跟踪task信息 */
#define configUSE_TRACE_FACILITY 1
#define configUSE_STATS_FORMATTING_FUNCTIONS 1
void vTaskList( char * pcWriteBuffer )

名称 状态 优先级 堆栈使用 任务编号
'X'(运行) 'B'(阻塞)、'R'(就绪)、'S'(暂停)或 'D'(删除)。
任务挂起与恢复实验(掌握)
- start_task:用来创建其他的三个任务。
- task1:实现LED1每500ms闪烁一次。
- task2:实现LED2每500ms闪烁一次。
- task3:判断按键按下逻辑,KEY1按下,挂起task1,按下KEY2在任务中恢复task1,KEY3按下,挂起调度器,KEY4按下,恢复调度器,并打印任务的状态。
FreeRTOSConfig.h代码清单
#define INCLUDE_vTaskSuspend 1
#define INCLUDE_xResumeFromISR 1
/* 开启跟踪task信息 */
#define configUSE_TRACE_FACILITY 1
#define configUSE_STATS_FORMATTING_FUNCTIONS 1
freertos_demo.c代码清单
#include "freertos_demo.h"
/* freertos相关的头文件,必须的 */
#include "FreeRTOS.h"
#include "task.h"
/* 需要用到的其他头文件 */
#include "LED.h"
#include "Key.h"
/* 启动任务的配置 */
#define START_TASK_STACK 128
#define START_TASK_PRIORITY 1
TaskHandle_t start_task_handle;
void start_task(void *pvParameters);
/* 任务1的配置 */
#define TASK1_STACK 128
#define TASK1_PRIORITY 2
TaskHandle_t task1_handle;
void task1(void *pvParameters);
/* 任务2的配置 */
#define TASK2_STACK 128
#define TASK2_PRIORITY 3
TaskHandle_t task2_handle;
void task2(void *pvParameters);
/* 任务3的配置 */
#define TASK3_STACK 128
#define TASK3_PRIORITY 4
TaskHandle_t task3_handle;
void task3(void *pvParameters);
/**
* @description: 启动FreeRTOS
* @return {*}
*/
void freertos_start(void)
{
/* 1.创建一个启动任务 */
xTaskCreate((TaskFunction_t)start_task, // 任务函数的地址
(char *)"start_task", // 任务名字符串
(configSTACK_DEPTH_TYPE)START_TASK_STACK, // 任务栈大小,默认最小128,单位4字节
(void *)NULL, // 传递给任务的参数
(UBaseType_t)START_TASK_PRIORITY, // 任务的优先级
(TaskHandle_t *)&start_task_handle); // 任务句柄的地址
/* 2.启动调度器:会自动创建空闲任务 */
vTaskStartScheduler();
}
/**
* @description: 启动任务:用来创建其他Task
* @param {void} *pvParameters
* @return {*}
*/
void start_task(void *pvParameters)
{
/* 进入临界区:保护临界区里的代码不会被打断 */
taskENTER_CRITICAL();
/* 创建3个任务 */
xTaskCreate((TaskFunction_t)task1,
(char *)"task1",
(configSTACK_DEPTH_TYPE)TASK1_STACK,
(void *)NULL,
(UBaseType_t)TASK1_PRIORITY,
(TaskHandle_t *)&task1_handle);
xTaskCreate((TaskFunction_t)task2,
(char *)"task2",
(configSTACK_DEPTH_TYPE)TASK2_STACK,
(void *)NULL,
(UBaseType_t)TASK2_PRIORITY,
(TaskHandle_t *)&task2_handle);
xTaskCreate((TaskFunction_t)task3,
(char *)"task3",
(configSTACK_DEPTH_TYPE)TASK3_STACK,
(void *)NULL,
(UBaseType_t)TASK3_PRIORITY,
(TaskHandle_t *)&task3_handle);
/* 启动任务只需要执行一次即可,用完就删除自己 */
vTaskDelete(NULL);
/* 退出临界区 */
taskEXIT_CRITICAL();
}
/**
* @description: 任务一:实现LED1每500ms闪烁一次
* @param {void} *pvParameters
* @return {*}
*/
void task1(void *pvParameters)
{
while (1)
{
printf("task1运行...\r\n");
LED_Toggle(LED1_Pin);
vTaskDelay(500);
}
}
/**
* @description: 任务二:实现LED2每500ms闪烁一次
* @param {void} *pvParameters
* @return {*}
*/
void task2(void *pvParameters)
{
while (1)
{
printf("task2运行...\r\n");
LED_Toggle(LED2_Pin);
vTaskDelay(500);
}
}
/**
* @description: 任务三:判断按键按下逻辑,KEY1按下,挂起task1,按下KEY2在任务中恢复task1,KEY3按下,挂起调度器,KEY4按下,恢复调度器,并打印任务的状态
* @param {void} *pvParameters
* @return {*}
*/
char task_info[500]; //定义一个字符数组,用于接收任务信息字符串
void task3(void *pvParameters)
{
uint8_t key = 0;
while (1)
{
printf("task3运行...\r\n");
key = Key_Detect();
if (key == KEY1_PRESS)
{
/* key1按下,挂起task1 */
printf(">>>>挂起task1....\r\n");
vTaskSuspend(task1_handle);
}
else if (key == KEY2_PRESS)
{
/* key2按下,恢复task1 */
printf(">>>>恢复task1....\r\n");
vTaskResume(task1_handle);
}
else if (key == KEY3_PRESS)
{
/* key3按下,挂起调度器 */
printf("<<<<挂起调度器....\r\n");
vTaskSuspendAll();
}
else if (key == KEY4_PRESS)
{
/* key4按下,恢复调度器 */
printf("<<<<恢复调度器....\r\n");
xTaskResumeAll();
}
/* 打印任务的状态 */
vTaskList(task_info);
printf("%s\r\n",task_info);
vTaskDelay(500);
}
}

Comments NOTHING