任务的创建和删除

任务管理是FreeRTOS的核心功能,涉及任务的创建,任务的删除,任务挂起,任务的恢复和任务调度等内容,任务句柄用来标识一个任务,其类型名为TaskHandle_t,指向任务控制块。

1,任务函数

函数名         函数功能
xTaskCteat() 用动态内存分配方法创建任务
xTaskCteatStatic() 用静态内存分配方法创建任务
xTaskCteatRestricted() 创建MPU内存保护任务,任务堆栈用静态内存分配,任务控制块用动态内存分配
xTaskCteatRestrictedStatic() 创建MPU内存保护任务,任务堆栈和任务控制块都用静态内存分配
vTaskDelete() 删除任务

无论用什么方法创建任务都要使用任务函数,任务函数的返回值必须为void;FreeRTOS任务是一个死循环【while(1)】,任务不允许任何方式从实现函数中返回,即不可以有一条return语句,也不可以执行到函数末尾,如果一个函数不被需要,可以显示将其删除。

1.1,xTaskCteat()

BaseType_t xTaskCteat(

                       任务函数;
                       任务名;
                       任务堆栈大小,单位word;
                       任务参数;
                       任务优先级;
                       任务句柄;
                      )

举例:

 步骤一:创建任务函数Led0Task();

static void Led0Task(void *pvParameters)
{
	while(1)
	{
		HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_15);
		HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET);		  
		HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET);
		vTaskDelay(pdMS_TO_TICKS(500));
	}
}

步骤二:定义任务句柄,用xTaskCreat()创建任务

static TaskHandle_t Led0TaskHandle = NULL;  //任务句柄

xTaskCreate(Led0Task,                //任务函数
			"Led0Task",              //任务名
			128,                     //堆栈大小
			NULL,                    //参数
			3,                       //优先级
			&Led0TaskHandle);        //句柄

vTaskStartScheduler();    //开启调度器

1.2,删除任务

void vTaskDelete(任务句柄);

使用此函数需要在FreeRTOSConfig.h中将宏INCLUDE_vTaskDelete设置为1。如果传入参数为NULL,那么就是删除当前正在运行的任务。

void vTaskDeiete(TaskHandle_t Led0TaskHandle);  //删除任务LEd0Task

2, 任务创建和删除示例

在项目根目录中添加appTask文件,在文件中添加一对文件appTask.c和appTask.h,将appTask.c和appTask.h分别添加到Application/MDK-ARM和FreeRTOS/include中;在C/C++选项卡中添加文件路径。

任务创建与删除示例 :本示例通过 appStartTask()函数创建两个 FreeRTOS 任务。任务 1 的任务函数为Led0Task(),其功能是使LED0每秒闪烁1次,在完成5次闪烁后删除任务1。任务2的任务函数是Led1Task(),其功能是使LED1每秒闪烁2次。硬件的连接参考图,如果选用的是其他开发板,则请参考自己所选开发板的电路原理图。 

开发板原理图

任务的创建和删除_第1张图片任务的创建和删除_第2张图片

2.1,appTask.h内容

#ifndef _APPTASK_H_
#define _APPTASK_H_
#include "freertos.h"                            //FreeRTOS任务头文件
#include "task.h"                                //FreeRTOS任务实现头文件
static void Led0Task(void *pvParameters);             //LED0闪烁任务
static void Led1Task(void *pvParameters);            //LED1闪烁任务
void appStartTask(void);                            //用于创建其他任务的函数
#endif 

2.2,appTask.c文件内容

#include "appTask.h"
#include "usart.h"
#include "string.h"
#include "stdio.h"
#include "FreeRTOS.h"

static TaskHandle_t Led0TaskHandle = NULL; 
static TaskHandle_t Led1TaskHandle = NULL; 


//Led0Task()任务函数创建
static void Led0Task(void *pvParameters)
{
   uint16_t cnt = 0;        //用于计数的局部变量
   while(1)
	 {
		HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_8);
        HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET);		  
		HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET);
		vTaskDelay(pdMS_TO_TICKS(500)); //每秒闪烁一次

		printf("LED0正以1秒为周期闪烁。\r\n");
		if(++cnt>=10)
		{
			if(eTaskGetState(Led0TaskHandle) != eDeleted)    //如果没有被删除
			{
				vTaskDelete(Led0TaskHandle);                  //删除任务
				printf("LED0任务被删除\r\n");
			}
		}
	 }
	 vTaskDelete(NULL);    //删除自身
}




//Led1Task()任务函数创建
static void Led1Task(void *pvParmeters)
{
	while(1)
	{
		HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_9);	
		HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET);		  
		HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET);
		vTaskDelay(pdMS_TO_TICKS(250));     //每秒闪烁一次

		printf("LED1每秒闪烁一次¸\r\n");
	}
	 vTaskDelete(NULL);    //删除自身
}



//开始任务函数,用于创建其他任务并开启调度器
void appStartTask(void)
{
	taskENTER_CRITICAL();        //进入临界段,关中断
	xTaskCreate(Led0Task,
	            "Led0Task",
				128,
				NULL,
				4,
				&Led0TaskHandle );
	
	xTaskCreate(Led1Task,
	            "Led1Task",
				128,
				NULL,
				4,
				&Led1TaskHandle );

	taskEXIT_CRITICAL();        //退出临界段,开中断
	vTaskStartScheduler();        //开启调度器
}


2.3,main.c文件修改

#include "main.h"
#include "usart.h"
#include "gpio.h"
#include "freertos.h"
#include "task.h"
#include "stdio.h"
#include "string.h"
#include "appTask.h"        //添加头文件



int main(void)
{
    /* USER CODE END 2 */

    appStartTask(); //创建任务并开启调度器

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
    
    while(1){
    
    }
}

代码放在/* USER CODE END 2 */和  /* USER CODE BEGIN WHILE */之间,否则项目更新时会被删除!main()中appStartTask();后的代码不会被执行!

编译无误后将程序下载到开发板上,打开串口调试助手,可以看到LED0以每秒1次的频率闪烁,LED1以每秒2次的频率闪烁,LED0闪烁5次后,LED0停止闪烁,因为此时LED0闪烁任务已经被删除。

任务的创建和删除_第3张图片

 如果不可运行,可以试着修改堆栈大小(FreeRTOSConfig.h中)

#define configCPU_CLOCK_HZ				( SystemCoreClock )
#define configTICK_RATE_HZ				( ( TickType_t ) 1000 )
#define configMAX_PRIORITIES			( 5 )
#define configMINIMAL_STACK_SIZE		( ( unsigned short ) 130 )
#define configTOTAL_HEAP_SIZE			( ( size_t ) ( 15 * 1024 ) )    //修改堆栈大小

你可能感兴趣的:(c#,开发语言)