FreeRTOS学习(3)——任务创建和删除(静态)

本代码是基于正点原子的STM32Mini板子,结合其FreeRTOS课程进行学习。

实验一:设计4个任务:start_task、task1、task2、task3

  1. start_task任务:用来创建其他三个任务
  2. task1任务:实现LED0每500ms翻转一次
  3. task2任务:实现LED1亮800ms,暗200ms
  4. task3任务:判断按键KEY0是否按下,按下KEY0删除task1

FreeRTOS中,任务创建和删除(动态方法)的函数为:xTaskCreateStatic、vTaskDelete

动态创建任务和静态创建任务的区别:

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

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

静态创建任务需要注意:

(1)代码中将宏#define configSUPPORT_STATIC_ALLOCATION配置为1;

#define configSUPPORT_STATIC_ALLOCATION         1            //支持静态内存申请

(2)定义配置空闲任务,软件定时器,实现两个接口函数:vApplicationGetIdleTaskMemory、vApplicationGetTimerTaskMemory;

//空闲任务配置
StaticTask_t idle_task_tcb;
StackType_t idel_task_stack[configMINIMAL_STACK_SIZE];
 /*空闲任务内存分配*/
void vApplicationGetIdleTaskMemory ( StaticTask_t **ppxIdleTaskTCBBuffer,
																		 StackType_t **ppxIdleTaskStackBuffer, 
																		 uint32_t *pulIdleTaskStackSize )
{
	* ppxIdleTaskTCBBuffer = &idle_task_tcb;
	* ppxIdleTaskStackBuffer = idel_task_stack;
	* pulIdleTaskStackSize = configMINIMAL_STACK_SIZE;
}

//软件定时器配置
StaticTask_t time_task_tcb;
StackType_t time_task_stack[configTIMER_TASK_STACK_DEPTH];
 /*软件定时器内存分配*/
void vApplicationGetTimerTaskMemory( StaticTask_t **ppxTimerTaskTCBBuffer,
																		 StackType_t **ppxTimerTaskStackBuffer,
                                     uint32_t *pulTimerTaskStackSize)
{
	 * ppxTimerTaskTCBBuffer = &time_task_tcb;
	 * ppxTimerTaskStackBuffer = time_task_stack;
   * pulTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH;
} 

具体代码如下:

#include "led.h"
#include "key.h"
#include "delay.h"
#include "sys.h"
#include "FreeRTOS.h"
#include "task.h"

/*START_TASK 任务配置
 *包括:任务句柄,任务优先级,堆栈大小,创建任务
 */
//任务优先级
#define START_TASK_PRIO		1
//任务堆栈大小	
#define START_TASK_STACK_SIZE   128  //单位是字,128x4才是字节
//任务句柄
TaskHandle_t StartTask_Handler;
//任务函数
void start_task(void *pvParameters);
//自定义堆栈大小
StackType_t  start_task_stack[START_TASK_STACK_SIZE];
//开始任务的任务控制块
StaticTask_t start_task_tcb;

/*TASK1 任务配置
 *包括:任务句柄,任务优先级,堆栈大小,创建任务
 */
//任务优先级
#define TASK1_PRIO		2
//任务堆栈大小	
#define TASK1_SIZE 		50  
//任务句柄
TaskHandle_t Task1_Handler;
//任务函数
void task1(void *pvParameters);
//自定义堆栈大小
StackType_t  task1_stack[TASK1_SIZE];
//开始任务的任务控制块
StaticTask_t task1_tcb;


/*TASK2 任务配置
 *包括:任务句柄,任务优先级,堆栈大小,创建任务
 */
//任务优先级
#define TASK2_PRIO		3
//任务堆栈大小	
#define TASK2_SIZE 		50  
//任务句柄
TaskHandle_t Task2_Handler;
//任务函数
void task2(void *pvParameters);
//自定义堆栈大小
StackType_t  task2_stack[TASK1_SIZE];
//开始任务的任务控制块
StaticTask_t task2_tcb;


/*TASK3 任务配置
 *包括:任务句柄,任务优先级,堆栈大小,创建任务
 */
 //任务优先级
#define TASK3_PRIO		4
//任务堆栈大小	
#define TASK3_SIZE 		50  
//任务句柄
TaskHandle_t Task3_Handler;
//任务函数
void task3(void *pvParameters);
//自定义堆栈大小
StackType_t  task3_stack[TASK1_SIZE];
//开始任务的任务控制块
StaticTask_t task3_tcb;

//空闲任务配置
StaticTask_t idle_task_tcb;
StackType_t idel_task_stack[configMINIMAL_STACK_SIZE];
 /*空闲任务内存分配*/
void vApplicationGetIdleTaskMemory ( StaticTask_t **ppxIdleTaskTCBBuffer,
									 StackType_t **ppxIdleTaskStackBuffer, 
									 uint32_t *pulIdleTaskStackSize )
{
	* ppxIdleTaskTCBBuffer = &idle_task_tcb;
	* ppxIdleTaskStackBuffer = idel_task_stack;
	* pulIdleTaskStackSize = configMINIMAL_STACK_SIZE;
}

//软件定时器配置
StaticTask_t time_task_tcb;
StackType_t time_task_stack[configTIMER_TASK_STACK_DEPTH];
 /*软件定时器内存分配*/
void vApplicationGetTimerTaskMemory( StaticTask_t **ppxTimerTaskTCBBuffer,
									 StackType_t **ppxTimerTaskStackBuffer,
                                     uint32_t *pulTimerTaskStackSize)
{
	 * ppxTimerTaskTCBBuffer = &time_task_tcb;
	 * ppxTimerTaskStackBuffer = time_task_stack;
     * pulTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH;
}  
int main(void)
{
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);//设置系统中断优先级分组4	 	 
	delay_init();	    				//延时函数初始化	  
	uart_init(115200);					//初始化串口
	LED_Init();		  					//初始化LED
	KEY_Init();               //按键初始化
	//创建开始任务
  StartTask_Handler = xTaskCreateStatic(	(TaskFunction_t  )   start_task,
											(char *     	 )   "start_task",
			                				(uint32_t		 )   START_TASK_STACK_SIZE,
											(void *			 )   NULL,
										 	(UBaseType_t	 )   START_TASK_PRIO,																					 
                                            (StackType_t * )   start_task_stack,
											(StaticTask_t *)   &start_task_tcb);										
    vTaskStartScheduler();          //开启任务调度
}

//开始任务任务函数
void start_task(void *pvParameters)
{
    taskENTER_CRITICAL();           //进入临界区
    //创建task1任务
   Task1_Handler = xTaskCreateStatic(	(TaskFunction_t)   task1,
										(char * 			 )   "task1",
										(uint32_t			 )   TASK1_SIZE,
										(void *				 )   NULL,
										(UBaseType_t	 )   TASK1_PRIO,
										(StackType_t * )   task1_stack,
										(StaticTask_t *)   &task1_tcb);										 
    //创建task2任务
  Task2_Handler = xTaskCreateStatic(	(TaskFunction_t)   task2,
										(char * 			 )   "task2",
								    	(uint32_t			 )   TASK2_SIZE,
										(void *				 )   NULL,
										(UBaseType_t	 )   TASK2_PRIO,
										(StackType_t * )   task2_stack,
										(StaticTask_t *)   &task2_tcb);		     
  //创建task3任务
  Task3_Handler = xTaskCreateStatic(	(TaskFunction_t)   task3,
										(char * 			 )   "task3",
										(uint32_t			 )   TASK3_SIZE,
										(void *				 )   NULL,
										(UBaseType_t	 )   TASK3_PRIO,
										(StackType_t * )   task3_stack,
										(StaticTask_t *)   &task3_tcb);
    vTaskDelete(NULL); //删除开始任务  也可以写成vTaskDelete(StartTask_Handler);
    taskEXIT_CRITICAL();            //退出临界区
}

//task1任务函数:实现LED0每500ms翻转一次
void task1(void *pvParameters)
{
    while(1)
    {
        LED0=!LED0;
        vTaskDelay(500);
    }
}   

//task2任务函数:实现LED1每800ms翻转一次
void task2(void *pvParameters)
{
    while(1)
    {
				LED1=0;
        vTaskDelay(200);
        LED1=1;
        vTaskDelay(800);		
    }
}

//task3任务函数:判断按键KEY0,按下KEY0删除task1
void task3(void *pvParameters)
{
	uint8_t key = 0;
	while(1)
	{
		key = KEY_Scan(0);
		if(key == KEY0_PRES)
		{
			vTaskDelete(Task1_Handler);
		}
		 vTaskDelay(10);
	}
}

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值