5.FreeRTOS的任务创建和删除

目录

一、任务创建和删除的API函数

二、任务创建和删除(动态方法)


一、任务创建和删除的API函数

任务的创建和删除本质就是调用FreeRTOS的API函数

API函数 描述
xTaskCreate() 动态方式创建任务
xTaskCreateStatic() 静态方式创建任务
vTaskDelete 删除任务(删除的是创建好的任务)

动态创建任务:任务的任务控制块以及任务的栈空间所需的内存,均由FreeRTOS从FreeRTOS给管理的堆中分配。

静态创建任务:任务放入任务控制块以及任务的栈空间所需的内存,需要用户分配提供。

二、任务创建和删除(动态方法)

动态创建任务函数

BaseType_t xTaskCreate
(
 TaskFunction_t pxTaskCode,   /*指向任务函数的指针*/
 const char * const pcName,   /*任务名字*/
 const configSTACK_DEPTH_TYPE usStackDepth,   /*任务堆栈大小*/
 void * const pvParameters,          /*传递给任务函数的参数*/
 UBaseType_t uxPriority,                     /*任务优先级*/
 TaskHandle_t * const pxCreatedTask);       /*任务句柄,就是任务的任务控制块*/
}
返回值 描述
pdPASS 任务创建成功
errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY 任务创建失败

实现动态创建任务流程

1、将宏onfigSUPPORT_DYNAMIC_ALLOCAT配置为1

#define configSUPPORT_DYNAMIC_ALLOCATION   1

2、定义函数入口参数

3、编写任务函数

此函数创建的任务会立刻进入就绪态,由任务调度器来执行,找到优先级最高的函数去执行。

动态创建任务内部实现

1、申请堆栈内存或者任务快内存。

2、TCB结构体成员赋值

3、添加新任务到就绪列表中

静态创建任务

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 用户没有提供相应的内存,任务创建失败
其他值 任务句柄,任务创建成功

实现静态创建任务

1、将宏configSUPPORT_STATIC_ALLOCATION

#define configSUPPORT_STATIC_ALLOCATION                 0                      
 /* 1: 支持静态申请内存, 默认: 0 */

2、定义空闲任务&定时器任务的任务堆栈及TCB

3、实现两个接口函数

4、定义函数入口参数

5、编写任务函数

此函数创建的任务会立刻进入就绪态,由任务调度器调度运行

1、TCB结构体成员赋值

2、添加新任务到就绪列表中

任务删除函数

void TaskDelete(TaskHandle_t xTaskToDelete);

形参 描述
xTaskToDelete 带删除任务的任务句柄

被删除的任务将从就绪任务列表、阻塞态任务列表、挂起态任务列表和事件列表中删除。

注意:

1、当传入的参数为NULL,则代表删除任务本身(当前正在运行的任务)

2、空闲任务会负责释放被删除任务中由系统分配的内存,但是由用户在任务删除前申请的内存,则需要由用户在任务被删除前提前释放,否则将导致内存泄漏。

删除任务流程

1、使用删除任务函数,需将宏INCLUDE_vTaskDelete 配置为1

2、入口参数输入需要删除的任务句柄(NULL代表删除本身)

内部实现过程

1、获取所需要删除任务的控制块:通过传入的任务句柄,判断所需要删除哪个任务,NULL代表删除自身。

2、将被删除任务,一处所在列表。将该任务在所在列表中移除,包括:就绪、阻塞、挂起、事件等列表。

3、判断所需要删除的任务

(1)删除任务自身,需要添加等待删除列表,内存释放将在空闲任务执行。

(2)删除其他任务,释放内存,任务数量。

4、更新下一个任务的阻塞超时时间,以防被删除的任务就是下一个阻塞超时的任务。

三、实战

任务创建和删除-动态方法

1、主要是两个函数:

(1)xTaskCreate()

(2)vTaskDelete()

2、我们总共设计四个任务,分别是:start_task、task1、task2、task3

并且设置四个任务的功能如下:

  • start_task  用来创建其他的三个任务,只执行一次
  • task1实现LED0和LED1每500ms闪烁一次
  • task2实现函数打印
  • task3判断按键KEY0是否按下,按下删除掉task1

第一步:将宏 configSUPPORT_DYNAMIC_ALLOCATION配置为1,它的配置在FreeRTOSConfig.h中进行配置。我们默认为1,是动态创建的配置。

#define configSUPPORT_DYNAMIC_ALLOCATION                1                       
/* 1: 支持动态申请内存, 默认: 1 */

第二步:动态创建任务函数入口函数的编写

首先我们跳进去,我们把原形复制出来

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

然后我们修改,建议用括号做一下强转,这样编译不会出现警告,不然会有很多警告的,任务函数,我们创建的是开始任务,所以要创建的任务是start_task,其中任务名字和任务函数一模一样就好,

    xTaskCreate((TaskFunction_t )start_task,            /* 任务函数 */
                (const char*    )"start_task",          /* 任务名称 */
                (uint16_t       )START_STK_SIZE,        /* 任务堆栈大小 */
                (void*          )NULL,                  /* 传入给任务函数的参数 */
                (UBaseType_t    )START_TASK_PRIO,       /* 任务优先级 */
                (TaskHandle_t*  )&StartTask_Handler);   /* 任务句柄 */

第三步:我们创建三个任务

任务一:

void task1(void *pvParameters)
{ 
	
    while(1)
    {
		printf("Task1正在运行!!!\r\n");
        LED0_TOGGLE();                                            /* LED0闪烁 */
	    LED1_TOGGLE();
        vTaskDelay(500);                                               /* 延时500ticks */
    }
	
}

任务二:

void task2(void *pvParameters)
{
    float test = 0.0;

    while(1)
    {   printf("Task2正在运行!!!\r\n");
//		printf("小羽嵌入式编程\r\n");
        test += 0.01f;                         /* 更新数值 */
        printf("test_num: %0.4f\r\n", test);  /* 打印数值 */
        vTaskDelay(1000);                           /* 延时1000ticks */
    }
}

任务三:

void task3(void *pvParameters)
{
	uint8_t key=0;

    while(1)
    {  
		key =key_scan(0);
		if(key==KEY0_PRES)
		{
			if(Task1Task_Handler!=NULL)
			{
				printf("删除task1任务\r\n");
				vTaskDelete(Task1Task_Handler);
				Task1Task_Handler = NULL;
			}
		}
		vTaskDelay(10);
		
    }
}

我已验证,完全正确,有疑问请私聊

你可能感兴趣的:(FreeRTOS系统教程,FreeRTOS系统)