实现动态创建任务流程
任务控制块结构体成员介绍
typedef struct tskTaskControlBlock
{volatile StackType_t * pxTopOfStack; /* 任务栈栈顶,必须为TCB第一个成员 */ListItem_t xStateListItem; /* 任务状态列表项 */ ListItem_t xEventListItem; /* 任务事件列表项 */ UBaseType_t uxPriority; /* 任务优先级,数值越大,优先级越大 */StackType_t * pxStack; /* 任务栈起始地址 */char pcTaskName[ configMAX_TASK_NAME_LEN ]; /* 任务名字 */ …省略很多条件编译的成员
} tskTCB;
任务控制块(TCB)就是任务的身份证
静态创建任务使用流程
TaskHandle_t xTaskCreateStatic
(TaskFunction_t pxTaskCode, /* 指向任务函数的指针 */const char * const pcName, /* 任务函数名 */const uint32_t ulStackDepth, /* 任务堆栈大小注意字为单位 */void * const pvParameters, /* 传递的任务函数参数 */UBaseType_t uxPriority, /* 任务优先级 */StackType_t * const puxStackBuffer, /* 任务堆栈,一般为数组,由用户分配 */StaticTask_t * const pxTaskBuffer /* 任务控制块指针,由用户分配 */
);
/* 传递的任务函数参数 */一般为NULL
与动态不同静态需要用户指定任务堆栈和任务控制块的内存
静态任务创建流程
空闲任务是必须的软件定时器任务可选,如果都创建都需要提供堆栈和任务控制块的存储空间。
任务创建完成后进入就绪态,由任务调度器调度
任务删除函数
void vTaskDelete(TaskHandle_t xTaskToDelete);
用于删除已被创建的任务
被删除的任务将从就绪态任务列表、阻塞态任务列表、挂起态任务列表和事件列表中移除
1、当传入的参数为NULL,则代表删除任务自身(当前正在运行的任务)
**2、空闲任务会负责释放被删除任务中由系统分配的内存(针对动态创建),(这里注意在task1中删除task1任务则在空闲任务中释放内存,如果删除task2则立马在task1中释放)。(针对静态)但是由用户在任务删除前申请的内存, 则需要由用户在任务被删除前提前释放否则将导致内存泄露 **
删除任务流程
实验目的:学会 xTaskCreateStatic( ) 和 vTaskDelete( ) 的使用
实验设计:将设计四个任务:start_task、task1、task2、task3
开始任务创建123三个任务
任务1 实现LED0每500ms闪烁一次
任务2 实现LED1每500ms闪烁一次
任务3 实现LED0每500ms闪烁一次 判断按键KEY0是否按下,按下则删掉task1
硬件使用到led和按键这里不做硬件介绍
/******************************************************************************************************* @file freertos.c* @author 正点原子团队(ALIENTEK)* @version V1.4* @date 2022-01-04* @brief FreeRTOS 移植实验* @license Copyright (c) 2020-2032, 广州市星翼电子科技有限公司***************************************************************************************************** @attention** 实验平台:正点原子 F407电机开发板* 在线视频:www.yuanzige.com* 技术论坛:www.openedv.com* 公司网址:www.alientek.com* 购买地址:openedv.taobao.com******************************************************************************************************/#include "freertos_demo.h"
#include "./SYSTEM/usart/usart.h"
#include "./BSP/LED/led.h"
#include "./BSP/LCD/lcd.h"
#include "./BSP/KEY/key.h"
/*FreeRTOS*********************************************************************************************/
#include "FreeRTOS.h"
#include "task.h"/******************************************************************************************************/
/*FreeRTOS配置*//* START_TASK 任务 配置* 包括: 任务句柄 任务优先级 堆栈大小 创建任务*/
#define START_TASK_PRIO 1
#define START_TASK_STACK_SIZE 128
TaskHandle_t start_task_handler;
void start_task( void * pvParameters );#define TASK1_PRIO 2
#define TASK1_STACK_SIZE 128
TaskHandle_t task1_handler;
void task1( void * pvParameters );#define TASK2_PRIO 3
#define TASK2_STACK_SIZE 128
TaskHandle_t task2_handler;
void task2( void * pvParameters );#define TASK3_PRIO 4
#define TASK3_STACK_SIZE 128
TaskHandle_t task3_handler;
void task3( void * pvParameters );/******************************************************************************************************//*** @brief FreeRTOS例程入口函数* @param 无* @retval 无*/
void freertos_demo(void)
{ xTaskCreate((TaskFunction_t) start_task,(char *) "start_task",(configSTACK_DEPTH_TYPE) START_TASK_STACK_SIZE,(void *) NULL,(UBaseType_t) START_TASK_PRIO,(TaskHandle_t *)&start_task_handler);//开启任务调度vTaskStartScheduler();}
void start_task( void * pvParameters )
{taskENTER_CRITICAL(); /* 进入临界区 任何任务和中断都不能打断当前程序运行*/xTaskCreate((TaskFunction_t) task1,(char *) "task1",(configSTACK_DEPTH_TYPE) TASK1_STACK_SIZE,(void *) NULL,(UBaseType_t) TASK1_PRIO,(TaskHandle_t *)&task1_handler );xTaskCreate((TaskFunction_t) task2,(char *) "task2",(configSTACK_DEPTH_TYPE) TASK2_STACK_SIZE,(void *) NULL,(UBaseType_t) TASK2_PRIO,(TaskHandle_t *)&task2_handler ); xTaskCreate((TaskFunction_t) task3,(char *) "task3",(configSTACK_DEPTH_TYPE) TASK3_STACK_SIZE,(void *) NULL,(UBaseType_t) TASK3_PRIO,(TaskHandle_t *)&task3_handler );vTaskDelete(NULL);//删除当前任务也就是开始任务taskEXIT_CRITICAL();}void task1( void * pvParameters )
{while(1){printf("task1 正在运行");LED0_TOGGLE();vTaskDelay(500);}
}void task2( void * pvParameters )
{while(1){printf("task2 正在运行");LED1_TOGGLE();vTaskDelay(500);}
}void task3( void * pvParameters )
{uint8_t key =0;while(1){printf("task3 正在运行");key = key_scan(0);if(key==KEY0_PRES){if(task1_handler!=NULL){printf("任务1删除");vTaskDelete(task1_handler);task1_handler=NULL;}}vTaskDelay(10);}
}