FreeRTOS task creation and deletion

API functions for task creation and deletion

  • xTaskCreate(): create a task using a dynamic method
  • Xtask createstatic(): create a task using a static method
  • Xtask createrestricted(): create a task restricted by MPU, and the related memory uses dynamic memory allocation
  • Vtask delete(): deletes a task

xTaskCreate

Using this function, configsupport_ DYNAMIC_ The allocation should be set to 1

	#if( configSUPPORT_DYNAMIC_ALLOCATION == 1 )
	BaseType_t xTaskCreate(	TaskFunction_t pxTaskCode,
							const char * const pcName,
							const uint16_t usStackDepth,
							void * const pvParameters,
							UBaseType_t uxPriority,
							TaskHandle_t * const pxCreatedTask ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
#endif

  • pxTaskCode: function name, function of task execution. We can treat a task as a function, but this function can be executed circularly
  • pcName: task name, which is generally used for tracking and debugging. The task name cannot exceed configMAX_TASK_NAME_LEN´╝îconfigMAX_ TASK_ NAME_ Len in FreeRTOSConfig.h file
  • Ustackdepth: the size of the task stack. The stack actually applied for is 4 times larger than ustackdepth. The size of the idle task stack is configMINIMAL_STACK_SIZE´╝îconfigMINIMAL_ STACK_ Size is defined in the FreeRTOSConfig.h file
  • pvParameters: parameters passed to the task function
  • uxPriority: task priority. The range is 0-configMAX_PRIORITIES-1
  • pxCreatedTask: task handle. The task handle of this task will be returned after the task is successfully created.

Return value:
pdPASS if the task was successfully created and added to a ready list, otherwise an error code defined in the file projdefs.h

xTaskCreateStatic

Using this function, configSUPPORT_STATIC_ALLOCATION must be equal to 1

#if( configSUPPORT_STATIC_ALLOCATION == 1 )
	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 ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
#endif /* configSUPPORT_STATIC_ALLOCATION */

See xTaskCreate for specific functions of parameters,

  • Ulsackdepth: it needs to be given by the user. It is usually an array. This parameter is the size of the array
  • puxStackBuffer: Must point to a StackType_t array that has at least ulStackDepth indexes - the array will then be used as the task's stack,removing the need for the stack to be allocated dynamically.
  • pxTaskBuffer: task control block, pxTaskBuffer Must point to a variable of type StaticTask_t, which will then be used to hold the task’s data structures, removing the need for the memory to be allocated dynamically.

Return value:
If neither pxStackBuffer or pxTaskBuffer are NULL, then the task will be created and pdPASS is returned. If either pxStackBuffer or pxTaskBuffer are NULL then the task will not be created and errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY is returned.

xTaskCreateRestricted

Using this function, portUSING_MPU_WRAPPERS=1

#if( portUSING_MPU_WRAPPERS == 1 )
	BaseType_t xTaskCreateRestricted( const TaskParameters_t * const pxTaskDefinition, TaskHandle_t *pxCreatedTask ) PRIVILEGED_FUNCTION;
#endif
  • pxTaskDefinition: a structure that describes the task function, stack size, priority, etc., and is defined in task.h
  • pxCreatedTask: task handle

vTaskDelete

void vTaskDelete( TaskHandle_t xTaskToDelete ) PRIVILEGED_FUNCTION;
  • xTaskToDelete: the task handle to delete the task
    The deleted task no longer exists. For the memory automatically allocated to the task by the kernel, this function will automatically release. The memory allocated to the task by the user needs to be released by the user. For example, pvPortMalloc() allocates 500 bytes of memory. After the task is deleted, the user needs to call vPortFree function to delete these memories, otherwise memory leakage will occur

Design

There are three tasks:

  • start_task: used to create two other tasks
  • task1_task: after the secondary task runs 5 times, call vTaskDelete to delete the task task2_. Task, this task will also control LED0 to flash and periodically refresh the background color of the specified area of the LCD
  • task2_task: this task is a common application task. It will control the flashing of LED1 and periodically take the lead in the background color of the LCD specified area
Dynamic creation

main function code:

#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "FreeRTOS.h"
#include "task.h"
#include "lcd.h"
#include "sdram.h"

//Task priority
#define START_TASK_PRIO		1
//Task stack size	
#define START_STK_SIZE 		128  
//task handle 
TaskHandle_t StartTask_Handler;
//Task function
void start_task(void *pvParameters);

//Task priority
#define TASK1_TASK_PRIO		2
//Task stack size	
#define TASK1_STK_SIZE 		128  
//task handle 
TaskHandle_t Task1Task_Handler;
//Task function
void task1_task(void *pvParameters);

//Task priority
#define TASK2_TASK_PRIO		3
//Task stack size	
#define TASK2_STK_SIZE 		128  
//task handle 
TaskHandle_t Task2Task_Handler;
//Task function
void task2_task(void *pvParameters);

//Color used when LCD swipes the screen
int lcd_discolor[14] = {WHITE ,BLACK,BLUE,BRED,GRED,
							GBLUE,RED,MAGENTA,GREEN,CYAN,
							YELLOW,BROWN,BRRED,GRAY};

int main(void)
{
    HAL_Init();                     //Initialize HAL Library   
    Stm32_Clock_Init(360,25,2,8);   //Set clock, 180Mhz
	delay_init(180);                //Initialization delay function
	LED_Init();						//LED initialization ACR_BYTE0_ADDRESS
	uart_init(115200);
	SDRAM_Init();
	LCD_Init();		
	
	POINT_COLOR = RED;
	
	LCD_ShowString(30,10,200,16,16,"Apolo STM32F4/F7");
	LCD_ShowString(30,30,200,16,16,"FreeeRTOS Examples");
	LCD_ShowString(30,50,200,16,16,"Task create and delete");
	LCD_ShowString(30,70,200,16,16,"2021/11/20");
	
	 xTaskCreate(start_task,            //Task function
                "start_task",          //Task name
                START_STK_SIZE,        //Task stack size
                NULL,                  //Parameters passed to the task function
                START_TASK_PRIO,       //Task priority
                &StartTask_Handler);   //task handle       	
	
	vTaskStartScheduler();		//Turn on task scheduling
	
}


//Start task function
void start_task(void *pvParameters)
{
    taskENTER_CRITICAL();           //Enter critical zone
    //Create TASK1 task
    xTaskCreate(task1_task,             
                "task1_task",           
                TASK1_STK_SIZE,        
                NULL,                  
                TASK1_TASK_PRIO,        
                &Task1Task_Handler);   
    //Create TASK2 task
    xTaskCreate(task2_task,     
                "task2_task",   
                TASK2_STK_SIZE,
                NULL,
                TASK2_TASK_PRIO,
                &Task2Task_Handler); 
    vTaskDelete(StartTask_Handler); //Delete start task
    taskEXIT_CRITICAL();            //Exit critical zone
}
//task1 task function
void task1_task(void *pvParameters)
{
	u8 task1_num=0;
	
	POINT_COLOR = BLACK;

	LCD_DrawRectangle(5,110,115,314); 	//Draw a rectangle	
	LCD_DrawLine(5,130,115,130);		//Draw a line
	POINT_COLOR = BLUE;
	LCD_ShowString(6,111,110,16,16,"Task1 Run:000");
	while(1)
	{
		task1_num++;	//Task execution times plus 1 pay attention to Task1_ When num1 is added to 255, it will be cleared!!
		LED0=!LED0;
		//printf("task 1 has been executed:% d times \ r\n",task1_num);
		if(task1_num==5) 
		{
			if(Task2Task_Handler != NULL)		//Does task 2 exist?	
			{
				vTaskDelete(Task2Task_Handler);	//Task 1 execute 5 times delete task 2
				Task2Task_Handler=NULL;			//Task handle reset
				//printf("task 1 deleted task 2!\r\n");
			}
		}
		LCD_Fill(6,131,114,313,lcd_discolor[task1_num%14]); //Filled area
		LCD_ShowxNum(86,111,task1_num,3,16,0x80);	//Displays the number of task executions
        vTaskDelay(1000);                           //Delay 1s, that is, 1000 clock beats	
	}
}

//task2 task function
void task2_task(void *pvParameters)
{
	u8 task2_num=0;
	
	POINT_COLOR = BLACK;

	LCD_DrawRectangle(125,110,234,314); //Draw a rectangle	
	LCD_DrawLine(125,130,234,130);		//Draw a line
	POINT_COLOR = BLUE;
	LCD_ShowString(126,111,110,16,16,"Task2 Run:000");
	while(1)
	{
		task2_num++;	//Task 2 execution times plus 1 pay attention to Task1_ When num2 is added to 255, it will be cleared!!
        LED1=!LED1;
		//printf("task 2 has been executed:% d times \ r\n",task2_num);
		LCD_ShowxNum(206,111,task2_num,3,16,0x80);  //Displays the number of task executions
		LCD_Fill(126,131,233,313,lcd_discolor[13-task2_num%14]); //Filled area
        vTaskDelay(1000);                           //Delay 1s, that is, 1000 clock beats	
	}
}



Static creation

To create a static task, you need to set the macro configsupport in FreeRTOSConfig.h_ STATIC_ The allocation is set to 1. After configuration, two functions, vApplicationGetIdleTaskMemory and vApplicationGetTimerTaskMemory, need to be implemented to allocate memory to the task stack and task control block of idle tasks and timer service tasks. These two functions are defined in main.c:

//Idle task stack
static StackType_t IdleTaskStack[configMINIMAL_STACK_SIZE];
//Idle task control block
static StaticTask_t IdleTaskTCB;

//Timer service task stack
static StackType_t TimerTaskStack[configTIMER_TASK_STACK_DEPTH];
//Timer service task control block
static StaticTask_t TimerTaskTCB;
//Get the task stack and task control block memory of idle tasks, because this routine uses
//Static memory, so the memory of the task stack and task control block of idle tasks should be
//FreeRTOS provides the interface function vApplicationGetIdleTaskMemory()
//Just implement this function.
//ppxIdleTaskTCBBuffer: task control block memory
//Ppxidletasksackbuffer: task stack memory
//pulIdleTaskStackSize: task stack size
void vApplicationGetIdleTaskMemory(StaticTask_t **ppxIdleTaskTCBBuffer, 
								   StackType_t **ppxIdleTaskStackBuffer, 
								   uint32_t *pulIdleTaskStackSize)
{
	*ppxIdleTaskTCBBuffer=&IdleTaskTCB;
	*ppxIdleTaskStackBuffer=IdleTaskStack;
	*pulIdleTaskStackSize=configMINIMAL_STACK_SIZE;
}
//Gets the task stack and task control block memory of the timer service task
//ppxTimerTaskTCBBuffer: task control block memory
//ppxTimerTaskStackBuffer: task stack memory
//pulTimerTaskStackSize: task stack size
void vApplicationGetTimerTaskMemory(StaticTask_t **ppxTimerTaskTCBBuffer, 
									StackType_t **ppxTimerTaskStackBuffer, 
									uint32_t *pulTimerTaskStackSize)
{
	*ppxTimerTaskTCBBuffer=&TimerTaskTCB;
	*ppxTimerTaskStackBuffer=TimerTaskStack;
	*pulTimerTaskStackSize=configTIMER_TASK_STACK_DEPTH;
}

The main function contains:

#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "FreeRTOS.h"
#include "task.h"
#include "lcd.h"
#include "sdram.h"

//Idle task stack
static StackType_t IdleTaskStack[configMINIMAL_STACK_SIZE];
//Idle task control block
static StaticTask_t IdleTaskTCB;

//Timer service task stack
static StackType_t TimerTaskStack[configTIMER_TASK_STACK_DEPTH];
//Timer service task control block
static StaticTask_t TimerTaskTCB;

//Task priority
#define START_TASK_PRIO		1
//Task stack size	
#define START_STK_SIZE 		128  
//task stack 
StackType_t StartTaskStack[START_STK_SIZE];
//Task control block
StaticTask_t StartTaskTCB;
//task handle 
TaskHandle_t StartTask_Handler;
//Task function
void start_task(void *pvParameters);

//Task priority
#define TASK1_TASK_PRIO		2
//Task stack size	
#define TASK1_STK_SIZE 		128  
//task stack 
StackType_t Task1TaskStack[TASK1_STK_SIZE];
//Task control block
StaticTask_t Task1TaskTCB;
//task handle 
TaskHandle_t Task1Task_Handler;
//Task function
void task1_task(void *pvParameters);

//Task priority
#define TASK2_TASK_PRIO		3
//Task stack size	
#define TASK2_STK_SIZE 		128  
//task stack 
StackType_t Task2TaskStack[TASK2_STK_SIZE];
//Task control block
StaticTask_t Task2TaskTCB;
//task handle 
TaskHandle_t Task2Task_Handler;
//Task function
void task2_task(void *pvParameters);


//Get the task stack and task control block memory of idle tasks, because this routine uses
//Static memory, so the memory of the task stack and task control block of idle tasks should be
//FreeRTOS provides the interface function vApplicationGetIdleTaskMemory()
//Just implement this function.
//ppxIdleTaskTCBBuffer: task control block memory
//Ppxidletasksackbuffer: task stack memory
//pulIdleTaskStackSize: task stack size
void vApplicationGetIdleTaskMemory(StaticTask_t **ppxIdleTaskTCBBuffer, 
								   StackType_t **ppxIdleTaskStackBuffer, 
								   uint32_t *pulIdleTaskStackSize)
{
	*ppxIdleTaskTCBBuffer=&IdleTaskTCB;
	*ppxIdleTaskStackBuffer=IdleTaskStack;
	*pulIdleTaskStackSize=configMINIMAL_STACK_SIZE;
}
//Gets the task stack and task control block memory of the timer service task
//ppxTimerTaskTCBBuffer: task control block memory
//ppxTimerTaskStackBuffer: task stack memory
//pulTimerTaskStackSize: task stack size
void vApplicationGetTimerTaskMemory(StaticTask_t **ppxTimerTaskTCBBuffer, 
									StackType_t **ppxTimerTaskStackBuffer, 
									uint32_t *pulTimerTaskStackSize)
{
	*ppxTimerTaskTCBBuffer=&TimerTaskTCB;
	*ppxTimerTaskStackBuffer=TimerTaskStack;
	*pulTimerTaskStackSize=configTIMER_TASK_STACK_DEPTH;
}



//Color used when LCD swipes the screen
int lcd_discolor[14] = {WHITE ,BLACK,BLUE,BRED,GRED,
							GBLUE,RED,MAGENTA,GREEN,CYAN,
							YELLOW,BROWN,BRRED,GRAY};

int main(void)
{
    HAL_Init();                     //Initialize HAL Library   
    Stm32_Clock_Init(360,25,2,8);   //Set clock, 180Mhz
	delay_init(180);                //Initialization delay function
	LED_Init();						//LED initialization ACR_BYTE0_ADDRESS
	uart_init(115200);
	SDRAM_Init();
	LCD_Init();		
	
	POINT_COLOR = RED;
	
	LCD_ShowString(30,10,200,16,16,"Apolo STM32F4/F7");
	LCD_ShowString(30,30,200,16,16,"FreeeRTOS Examples");
	LCD_ShowString(30,50,200,16,16,"Task create and delete");
	LCD_ShowString(30,70,200,16,16,"2021/11/20");
	
	StartTask_Handler= xTaskCreateStatic(start_task,"start_task",START_STK_SIZE,NULL, START_TASK_PRIO,StartTaskStack,&Task1TaskTCB);  	
	
	vTaskStartScheduler();		//Turn on task scheduling
	
}


//Start task function
void start_task(void *pvParameters)
{
    taskENTER_CRITICAL();           //Enter critical zone
    //Create TASK1 task
	Task1Task_Handler=xTaskCreateStatic((TaskFunction_t	)task1_task,		
										(const char* 	)"task1_task",		
										(uint32_t 		)TASK1_STK_SIZE,	
										(void* 		  	)NULL,				
										(UBaseType_t 	)TASK1_TASK_PRIO, 	
										(StackType_t*   )Task1TaskStack,	
										(StaticTask_t*  )&Task1TaskTCB);	   
    //Create TASK2 task
    Task2Task_Handler=xTaskCreateStatic(task2_task,     
                "task2_task",   
                TASK2_STK_SIZE,
                NULL,
                TASK2_TASK_PRIO,
				Task2TaskStack,
                &Task2TaskTCB); 
    vTaskDelete(StartTask_Handler); //Delete start task
    taskEXIT_CRITICAL();            //Exit critical zone
}
//task1 task function
void task1_task(void *pvParameters)
{
	u8 task1_num=0;
	
	POINT_COLOR = BLACK;

	LCD_DrawRectangle(5,110,115,314); 	//Draw a rectangle	
	LCD_DrawLine(5,130,115,130);		//Draw a line
	POINT_COLOR = BLUE;
	LCD_ShowString(6,111,110,16,16,"Task1 Run:000");
	while(1)
	{
		task1_num++;	//Task execution times plus 1 pay attention to Task1_ When num1 is added to 255, it will be cleared!!
		LED0=!LED0;
		//printf("task 1 has been executed:% d times \ r\n",task1_num);
		if(task1_num==5) 
		{
			if(Task2Task_Handler != NULL)		//Does task 2 exist?	
			{
				vTaskDelete(Task2Task_Handler);	//Task 1 execute 5 times delete task 2
				Task2Task_Handler=NULL;			//Task handle reset
				//printf("task 1 deleted task 2!\r\n");
			}
		}
		LCD_Fill(6,131,114,313,lcd_discolor[task1_num%14]); //Filled area
		LCD_ShowxNum(86,111,task1_num,3,16,0x80);	//Displays the number of task executions
        vTaskDelay(1000);                           //Delay 1s, that is, 1000 clock beats	
	}
}

//task2 task function
void task2_task(void *pvParameters)
{
	u8 task2_num=0;
	
	POINT_COLOR = BLACK;

	LCD_DrawRectangle(125,110,234,314); //Draw a rectangle	
	LCD_DrawLine(125,130,234,130);		//Draw a line
	POINT_COLOR = BLUE;
	LCD_ShowString(126,111,110,16,16,"Task2 Run:000");
	while(1)
	{
		task2_num++;	//Task 2 execution times plus 1 pay attention to Task1_ When num2 is added to 255, it will be cleared!!
        LED1=!LED1;
		//printf("task 2 has been executed:% d times \ r\n",task2_num);
		LCD_ShowxNum(206,111,task2_num,3,16,0x80);  //Displays the number of task executions
		LCD_Fill(126,131,233,313,lcd_discolor[13-task2_num%14]); //Filled area
        vTaskDelay(1000);                           //Delay 1s, that is, 1000 clock beats	
	}
}

Just compile

Tags: Single-Chip Microcomputer stm32 ARM FreeRTOS

Posted on Sat, 20 Nov 2021 15:57:38 -0500 by gum1982