FreeRTOS之静态创建任务

1.在前面的文章中介绍了FreeRTOS的动态创建方法,本文介绍一下FreeRTOS的静态任务创建方法xTaskCreateStatic()。相比较动态任务创建过程,静态创创建任务的过程稍显复杂。主要步骤为:

(1)配置相关的宏定义:configSUPPORT_STATIC_ALLOCATION。

(2)实现部分接口函数,用来给空闲任务的任务堆栈和任务控制块分配内存。

(3)配置静态创建任务函数的入口参数。

2.配置相关的宏定义:

将支持静态内存分配的宏定义configSUPPORT_STATIC_ALLOCATION设置为1:

配置静态任务相关的宏定义:

本文开启软件定时器任务,所以需要将软件定时器的宏定义configUSE_TIMERS设置为1:

3.实现接口函数:

(1)重写空闲任务堆栈和任务控制块内存分配的API函数vApplicationGetIdleTaskMemory:

(2)重写软件定时器任务堆栈和任务控制块内存分配的API函数vApplicationGetTimerTaskMemory:

4.配置静态创建任务函数的入口参数:

此处注意的是,静态创建任务时需要用户自己提供任务堆栈,本文自行定义了一个数组作为任务堆栈,堆栈数组为 StackType_t 类型。任务控制块的类型为StaticTask_t。

5.代码:

因为本文和前面动态创建任务实现的功能是相同的,所以本文不再展示所有的代码,仅展示main函数中代码。与前面的动态创建任务相比较,除了上述的宏定义配置外,本文只main函数有修改的地方。

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

static StaticTask_t IdleTaskTCB;																		//¿ÕÏÐÈÎÎñ¿ØÖÆ¿é
static StackType_t IdleTaskStack[configMINIMAL_STACK_SIZE];					//¿ÕÏÐÈÎÎñ¶ÑÕ»

/*ÖØд¿ÕÏÐÈÎÎñ¶ÑÕ»ºÍÈÎÎñ¿ØÖÆ¿éÄÚ´æ*/
void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer,
																		StackType_t **ppxIdleTaskStackBuffer, 
																		uint32_t *pulIdleTaskStackSize )
{
	*ppxIdleTaskTCBBuffer = &IdleTaskTCB;														//ÈÎÎñ¿ØÖÆ¿éÄÚ´æ
	*ppxIdleTaskStackBuffer = IdleTaskStack;												//ÈÎÎñ¶ÑÄÚ´æ
	*pulIdleTaskStackSize = configMINIMAL_STACK_SIZE;								//ÈÎÎñ¶ÑÕ»´óС
}

static StaticTask_t TimerTaskTCB;																	//¶¨Ê±Æ÷ÈÎÎñ¿ØÖÆ¿é
static StackType_t  TimerTaskStack[configTIMER_TASK_STACK_DEPTH];	//¶¨Ê±Æ÷·þÎñº¯Êý¶ÑÕ»
/*ÖØд¶¨Ê±Æ÷·þÎñÈÎÎñµÄ¶ÑÕ»ºÍÈÎÎñ¿ØÖÆ¿éÄÚ´æ*/
void vApplicationGetTimerTaskMemory( 	StaticTask_t **ppxTimerTaskTCBBuffer, 
																			StackType_t **ppxTimerTaskStackBuffer, 
																			uint32_t *pulTimerTaskStackSize )
{
	*ppxTimerTaskTCBBuffer = &TimerTaskTCB;													//ÈÎÎñ¿ØÖÆ¿éÄÚ´æ	
	*ppxTimerTaskStackBuffer = TimerTaskStack;											//ÈÎÎñ¶ÑÕ»ÄÚ´æ
	*pulTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH;					//ÈÎÎñ¶ÑÕ»´óС
}

//¶¨Òåstart_taskµÄÅäÖã¬ÈÎÎñ¾ä±ú£¬ÈÎÎñÓÅÏȼ¶£¬¶ÑÕ»´óС£¬ÈÎÎñÉùÃ÷£º
#define START_TASK_PRIO 1
#define START_TASK_STACK_SIZE 64
StackType_t StartTaskStack[START_TASK_STACK_SIZE];							//ÈÎÎñ¶ÑÕ»
StaticTask_t StartTaskTCB;																			//ÈÎÎñ¿ØÖÆ¿é
TaskHandle_t start_handler;
void start_task(void);

//¶¨ÒåÈÎÎñ1µÄÅäÖã¬ÈÎÎñ¾ä±ú£¬ÈÎÎñÓÅÏȼ¶£¬¶ÑÕ»´óС£¬ÈÎÎñÉùÃ÷£º
#define LED0_TASK_PRIO 2
#define LED0_TASK_STACK_SIZE 64
StackType_t Task1Static[LED0_TASK_STACK_SIZE];										//ÈÎÎñ¶ÑÕ»
StaticTask_t Task1TCB;																			//ÈÎÎñ¿ØÖÆ¿é
TaskHandle_t led0_handler;
void led0(void);

//¶¨ÒåÈÎÎñ2µÄÅäÖã¬ÈÎÎñ¾ä±ú£¬ÈÎÎñÓÅÏȼ¶£¬¶ÑÕ»´óС£¬ÈÎÎñÉùÃ÷£º
#define LED1_TASK_PRIO 3
#define LED1_TASK_STACK_SIZE 64
StackType_t Task2Static[LED1_TASK_STACK_SIZE];										//ÈÎÎñ¶ÑÕ»
StaticTask_t Task2TCB;																			//ÈÎÎñ¿ØÖÆ¿é
TaskHandle_t led1_handler;
void led1(void);

//¶¨ÒåÈÎÎñ3µÄÅäÖã¬ÈÎÎñ¾ä±ú£¬ÈÎÎñÓÅÏȼ¶£¬¶ÑÕ»´óС£¬ÈÎÎñÉùÃ÷£º
#define KEY_TASK_PRIO 4
#define KEY_TASK_STACK_SIZE 64
StackType_t Task3Static[KEY_TASK_STACK_SIZE];										//ÈÎÎñ¶ÑÕ»
StaticTask_t Task3TCB;																			//ÈÎÎñ¿ØÖÆ¿é
TaskHandle_t key_handler;
void key_task(void);

int flag = 0;

int main(void)
{
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);// ÉèÖÃÖжÏÓÅÏȼ¶·Ö×é2
	LED_Init();
	KEY_Init();
	delay_init();
	
	start_handler = xTaskCreateStatic(	(TaskFunction_t) start_task,										//ÈÎÎñº¯Êý
																			(const char *) "start_task",										//ÈÎÎñÃû³Æ
																			(	 uint32_t) START_TASK_STACK_SIZE,							//ÈÎÎñ¶ÑÕ»´óС
																			(void *) NULL,																	//ÈÎÎñº¯ÊýÈë¿Ú²ÎÊý
																			(UBaseType_t) START_TASK_PRIO,									//ÈÎÎñÓÅÏȼ¶
																			(StackType_t *) StartTaskStack,									//ÈÎÎñ¶ÑÕ»
																			(StaticTask_t *) &StartTaskTCB );								//ÈÎÎñ¿ØÖÆ¿é
	
			
	vTaskStartScheduler();																															//¿ªÊ¼ÈÎÎñµ÷¶È
}

/*´´½¨¿ªÊ¼ÈÎÎñ£º*/
void start_task(void)
{
//	taskENTER_CRITICAL();	
	/*´´½¨ÈÎÎñ*/
	if(flag == 0)
	{
			led0_handler = xTaskCreateStatic(	(TaskFunction_t) led0,										
																				(const char *) "led0",										
																				( uint32_t) LED0_TASK_STACK_SIZE,					
																				(void *) NULL,																	
																				(UBaseType_t) LED0_TASK_PRIO,									
																				(StackType_t *) Task1Static,									
																				(StaticTask_t *) &Task1TCB );								
			led1_handler = xTaskCreateStatic(	(TaskFunction_t) led1,										
																				(const char *) "led1",										
																				( uint32_t) LED1_TASK_STACK_SIZE,					
																				(void *) NULL,																	
																				(UBaseType_t) LED1_TASK_PRIO,									
																				(StackType_t *) Task2Static,									
																				(StaticTask_t *) &Task2TCB );
			key_handler = xTaskCreateStatic(	(TaskFunction_t) key_task,										
																				(const char *) "key_task",										
																				( uint32_t) KEY_TASK_STACK_SIZE,					
																				(void *) NULL,																	
																				(UBaseType_t) KEY_TASK_PRIO,									
																				(StackType_t *) Task3Static,									
																				(StaticTask_t *) &Task3TCB );							
	 flag = 1;
	}
	 vTaskDelay(500);
										
	 vTaskDelete(NULL);											//ɾ³ýµ±Ç°ÈÎÎñ
//	 taskEXIT_CRITICAL();
}

void led0(void)
{
	while(1)
	{
		GPIO_ResetBits(GPIOA,GPIO_Pin_8);			//´ò¿ªLED
		vTaskDelay(500);
		//delay_ms(500);
		GPIO_SetBits(GPIOA,GPIO_Pin_8);			//´ò¿ªLED
		vTaskDelay(500);
	}
}

void led1(void)
{
	while(1)
	{
		GPIO_ResetBits(GPIOD,GPIO_Pin_2);			//´ò¿ªLED
		vTaskDelay(500);
		//delay_ms(500);
		GPIO_SetBits(GPIOD,GPIO_Pin_2);			//´ò¿ªLED
		vTaskDelay(500);
	}
}

/*´´½¨°´¼üÈÎÎñ£º*/
void key_task(void)
{
	//uint8_t key = 0;
    while(1)
    {
        //printf("task3ÕýÔÚÔËÐУ¡£¡£¡\r\n");
        //key = KEY_Scan(0);
        if(KEY_0 == 0)
        {
            if(led0_handler != NULL)
            {
								delay_us(2000000);
                //printf("ɾ³ýtask1ÈÎÎñ\r\n");
                vTaskDelete(led0_handler);
                led0_handler = NULL;
            }

        }
        vTaskDelay(10);
    }
}

6.运行结果:

7.总结:

本文介绍了FreeRTOS的静态创建任务方法xTaskCreateStatic()。在使用静态方法创建任务时,需要配置相关的宏定义,并实现空闲任务的堆栈和任务控制块内存分配函数vApplicationGetIdleTaskMemory()。

静态创建任务需要用户自行提供堆栈,通常用数组来实现。此外,函数xTaskCreateStatic创建任务成功时的返回值即为任务句柄,创建任务失败时返回值为NULL。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值