FreeRTOS-stm32f407学习笔记-任务创建和删除

任务创建和删除函数

相关若函数如图
在task.c中定义
在这里插入图片描述

1.xTaskCreate()

在这里插入图片描述


pxTaskCode  //任务函数
pcName 任务名字//有限定长度,不超过configMAX_TASK_NAME_LEN。
usStackDepth //任务堆栈大小,字节数等于config MINIMAL_STACK_SIZE
pvParameters //传递给任务函数参数
uxPriotiry //任务优先级,不能使用最低最高优先级,前者由空闲任务占据,后者是时钟配置,必须为最高级
pxCreatedTask //任务句柄,任务创建后返回此任务句柄,即任务堆栈;动态创建的句柄名自定义,内存自动分配

返回值:

pdPASS 任务创建成功
errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY 创建失败,内存不够

2.xTaskCreateStatic()

在这里插入图片描述


pxTaskCode  //任务函数
pcName 任务名字//有限定长度,不超过configMAX_TASK_NAME_LEN。
usStackDepth //任务堆栈大小,字节数等于config MINIMAL_STACK_SIZE
pvParameters //传递给任务函数参数
uxPriotiry //任务优先级
puxStackBuffer//任务堆栈,一般为数组,数组类型要为StackType_t
pxTaskBuffer//任务控制块
//静态创建的堆栈自定义,句柄名自动返回

返回值

NULL 任务创建失败,在puxStackBuffer或者pxTaskBuffer为NULL时候会导致错误发生

其他值:任务创建成功,返回任务的任务句柄

3.xTaskCreateRestricted()

pxTaskDefinition //指向一个结构体TaskParameters_t,这个结构体描述了任务的任务函数,堆栈大小,优先级等,于task.h定义
pxCreatedTask //任务句柄

返回值 pdPASS

4.函数vTaskDelete()

删除一个已经创建的任务,被删除后任务不再存在,也就是说再也不会进入运行态。任务被删除后就不再使用此任务句柄。
在使用动态创建(无Static)时,该任务之前申请的堆栈和控制块内存会在空闲任务被清除,因此删除后需要等待一段时间

如果是静态创建,则需要自己来释放掉,当任务删除后使用vPortFree()将50字节释放掉,否则会导致内存泄漏

如果在一个任务中程序为做完相关任务后删除自己,则可以直接写xTaskDelete(NULL);
参数

xTaskToDelete() //要删除的任务的任务句柄

动态创建

主要使用xTaskCreate()和vTaskDelete()这两个函数,函数来自于task.h
源代码兼过程如下:
首先,确保task.h的configSUPPORT_DYNAMIC_ALLOCATION == 1

#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "FreeRTOS.h"//这个头文件必须在task.h之前被包含进来,否则报错,
#include "task.h"
void start_task(void *pvParameters);//引用起始函数,因为函数定义于main后边
TaskHandle_t *StartTask_Handler; //因为在start_task任务生成时候是直接用&xx(xx指的是自定义句柄名称。&即取址符号)的

void task1_task(void *pvParameters);
TaskHandle_t *Task1Task_Handler; 

void task2_task(void *pvParameters);
TaskHandle_t *Task2Task_Handler; 

int main(void)
{     
	delay_init(168);  
	LED_Init();				
	
	LED0=1;
	LED1=1;
	xTaskCreate((TaskFunction_t) start_task,
							(const char *  )  "start_task",//任务名
							(const uint16_t) 50,//堆栈大小
							(void *        )  NULL,	//	参数
							(UBaseType_t   ) 1,//优先级
							(TaskHandle_t *) &StartTask_Handler );//句柄取址
	
	vTaskStartScheduler() ;//开启任务调度,之后在内存中的代码/任务们开始运行,按照优先级大小

}

void start_task(void *pvParameters)
{
	xTaskCreate((TaskFunction_t) task1_task,
							(const char *  )  "task1_task",
							(const uint16_t) 50,
							(void *        )  NULL,
							(UBaseType_t   ) 2,
							(TaskHandle_t *) &Task1Task_Handler );
							
							
							
		xTaskCreate((TaskFunction_t) task2_task,
							(const char *  )  "task2_task",
							(const uint16_t) 50,
							(void *        )  NULL,
							(UBaseType_t   ) 3,
							(TaskHandle_t *) &Task2Task_Handler );
							


	vTaskDelete(NULL);//删除任务,这里由于是自尽所以用NULL

}

void task1_task(void *pvParameters)
{
	
		LED0=~LED0;
		vTaskDelay(500);
		LED0=~LED0;
		vTaskDelay(500);
	
}
void task2_task(void *pvParameters)
{
	while(1)
	{
	LED1=~LED1;
	vTaskDelay(400);
	LED1=~LED1;
	vTaskDelay(400);
	}
	}

最后将其编译并上传,两个灯泡就会同时以不同频率闪烁,感觉就像两个任务同时执行一样

静态创建

源代码以及讲解

#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "beep.h"
#include "key.h"

#include "FreeRTOS.h"//一样,必须是FreeRTOS.h在task.h前面
#include "task.h"

//由于默认不支持静态堆栈,因此需要在FreeRTOSconfig.h中定义一下
#define  configSUPPORT_STATIC_ALLOCATION 1
//由于静态内存创建函数会返回句柄,因此需要定一下接受返回值的句柄
 void start_task(void );
 StaticTask_t StartTaskTCB;
 StackType_t StartTaskStack[128];
 
 void task1_task(void);
 StaticTask_t Task1TaskTCB;
 StackType_t Task1TaskStack[128];
 TaskHandle_t Task1Task_Handler;
 
 void task2_task(void );
 StaticTask_t Task2TaskTCB;
 StackType_t Task2TaskStack[128];
  TaskHandle_t Task2Task_Handler;
 ///
static StackType_t IdleTaskStack[configMINIMAL_STACK_SIZE];//130,来自于FreeRTOS.h中的configMINIMAL_STACK_SIZE,用于定义空闲任务,优先级0
static StaticTask_t IdleTaskTCB;

static StackType_t TimerTaskStack[configMINIMAL_STACK_SIZE];//用于定义定时器任务,优先级最高
static StaticTask_t TimerTaskTCB;

 void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize)//这个包括下边这个由于没有在给定文件中定义,因此需要自己解决
 {
	*ppxIdleTaskTCBBuffer=&IdleTaskTCB;//根据参数类型直接定义即可,如StaticTask_t 
	*ppxIdleTaskStackBuffer=IdleTaskStack;
	*pulIdleTaskStackSize=configMINIMAL_STACK_SIZE;
 }
void vApplicationGetTimerTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, StackType_t **ppxIdleTaskStackBuffer, uint32_t *pulIdleTaskStackSize)
{
	*ppxIdleTaskTCBBuffer=&TimerTaskTCB;
	*ppxIdleTaskStackBuffer=TimerTaskStack;
	*pulIdleTaskStackSize=configMINIMAL_STACK_SIZE;
}


int main(void)
{ 
 
  
	delay_init(168);  //³õʼ»¯ÑÓʱº¯Êý
	LED_Init();				//³õʼ»¯LED¶Ë¿Ú 
	
	LED0=1;
	LED1=1;
	
	 xTaskCreateStatic(	(TaskFunction_t) start_task,
											(char *) "start_task",
											(uint32_t) 128,
											(void *) NULL,
											(UBaseType_t) 1,
											(StackType_t *) StartTaskStack,
											(StaticTask_t *) &StartTaskTCB );//注意,上边一行是数组不用&,这个不是数组,为给指针地址需要取址符
	
	vTaskStartScheduler() ;
	


}


void start_task(	void )
{
	 Task1Task_Handler=xTaskCreateStatic(	(TaskFunction_t) task1_task,
											(char *) "task1_task",
											(uint32_t) 128,
											(void *) NULL,
											(UBaseType_t) 2,
											(StackType_t *) Task1TaskStack,
											(StaticTask_t *) &Task1TaskTCB );

 Task2Task_Handler=xTaskCreateStatic(	(TaskFunction_t) task2_task,
											(char *) "task2_task",
											(uint32_t) 128,
											(void *) NULL,
											(UBaseType_t) 3,
											(StackType_t *) Task2TaskStack,
											(StaticTask_t *) &Task2TaskTCB );
	vTaskDelete(NULL);
}

void task1_task(void)
{
	while(1)
	{
		LED0=~LED0;
		vTaskDelay(500);
	}
}

void task2_task(void)
{
	while(1)
	{
		LED1=~LED1;
		vTaskDelay(400);
	}


}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值