FreeRTOS-01_创建动态任务

标题

1、相关API函数

1.1、xTaskCreate()

任务创建函数

BaseType_t xTaskCreate(	TaskFunction_t pxTaskCode,
							const char * const pcName,
							const uint16_t usStackDepth,
							void * const pvParameters,
							UBaseType_t uxPriority,
							TaskHandle_t * const pxCreatedTask )

功能 :动态创建任务
返回值:BaseType_t 类型{
  pdPASS:说明任务创建成功;
  errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY:说明任务创建失败;
}
参数 :

  • pxTaskCode:任务函数
  • pcName:任务名称
  • usStackDepth:任务堆栈大小(单位为字,因为STM32是32位的,所以1字=4字节)
  • pvParameters:任务函数参数(一般为空NULL)
  • uxPriority:任务优先级(越大优先级越高)
  • pxCreatedTask:任务控制句柄(相当于任务的身份证)

1.2、vTaskStartScheduler()

任务调度器

void vTaskStartScheduler( void )

功能:开启任务调度
无返回值无参

1.3、vTaskDelete()

任务删除函数

void vTaskDelete( TaskHandle_t xTaskToDelete )

功能:删除任务
无返回值
参数 :

  • xTaskToDelete:任务控制句柄,如果句柄为空NULL则删除目前所在的任务本身(不过不会立刻删除,会等待当前任务执行完毕再删除当前任务)

1.4、vTaskDelay()

相对延时函数

void vTaskDelay( const TickType_t xTicksToDelay )

功能:任务延迟,其实就是将任务挂起,让出内核的使用权
无返回值
参数 :

  • xTicksToDelay :要延迟的时间,单位ms

1.5、taskENTER_CRITICAL();

进入临界区

taskENTER_CRITICAL()

功能:关中断,进入临界区,防止临界段代码被其他任务打断(一般用于一开始创建运行任务时的创建任务函数,当运行任务全部创建完成后再重新退出临界区)
无返回值无参

1.6、taskEXIT_CRITICAL();

退出临界区

taskEXIT_CRITICAL()

功能:开中断,退出临界区
无返回值无参

2、操作流程

2.1、相应宏设置开启

configSUPPORT_DYNAMIC_ALLOCATION    1
功能:动态内存申请相关宏定义,要使用动态创建任务该宏需置一

2.2、创建宏定义参数变量

提前宏定义任务所需的参数
例如:

  • START_TASK_PRIO       任务优先级
  • START_TASK_STACK_SIZE  任务堆栈大小
  • start_task_handler       任务句柄
  • void start_task(void * pvParameters); 任务执行函数
/*	START_TASK	*/
#define START_TASK_PRIO			1
#define START_TASK_STACK_SIZE 	128
TaskHandle_t start_task_handler;
void start_task(void * pvParameters);

/*	TASK1	*/
#define TASK1_PRIO				2
#define TASK1_STACK_SIZE 		128
TaskHandle_t task1_handler;
void task1(void * pvParameters);
/*	TASK2	*/
#define TASK2_PRIO				3
#define TASK2_STACK_SIZE 		128
TaskHandle_t task2_handler;
void task2(void * pvParameters);
/*	TASK3	*/
#define TASK3_PRIO				4
#define TASK3_STACK_SIZE 		128
TaskHandle_t task3_handler;
void task3(void * pvParameters);

2.3、创建开始任务并开启任务调度器

void freertos_demo(void)
{
	BaseType_t xReturned = xTaskCreate((TaskFunction_t) start_task,
										(char * 			 	) "start_task",
										(uint16_t			) START_TASK_STACK_SIZE,
										(void *				) NULL,
										(UBaseType_t	 	) START_TASK_PRIO,
										(TaskHandle_t *) &start_task_handler ); 
	if(xReturned == pdPASS)
		vTaskStartScheduler();	//开启任务调度器		
	else
		printf("开始任务创建失败");
}

2.4、在开启任务中创建执行任务


void start_task(void * pvParameters)
{
	taskENTER_CRITICAL();		/* 进入临界区 防止创建任务过程被打断 */
	xTaskCreate((TaskFunction_t) task1,
							(char * 			 ) "task1",
							(uint16_t			 ) TASK1_STACK_SIZE,
							(void *				 ) NULL,
							(UBaseType_t	 ) TASK1_PRIO,
							(TaskHandle_t *) &task1_handler );
							
	xTaskCreate((TaskFunction_t) task2,
							(char * 			 ) "task2",
							(uint16_t			 ) TASK2_STACK_SIZE,
							(void *				 ) NULL,
							(UBaseType_t	 ) TASK2_PRIO,
							(TaskHandle_t *) &task2_handler );
							
	xTaskCreate((TaskFunction_t) task3,
							(char * 			 ) "task3",
							(uint16_t			 ) TASK3_STACK_SIZE,
							(void *				 ) NULL,
							(UBaseType_t	 ) TASK3_PRIO,
							(TaskHandle_t *) &task3_handler );
	vTaskDelete(NULL);			//删除自己
	taskEXIT_CRITICAL();		/* 退出临界区 */
}

2.5、编写任务函数

void task1(void * pvParameters)
{
	while(1)
	{
		;
 	}
}
void task2(void * pvParameters)
{
	while(1)
	{
		;
 	}
}
void task3(void * pvParameters)
{ 
	while(1)
	{
		;
 	}
}

3、点灯示例代码

/**************************************************************/
/*	START_TASK	*/
#define START_TASK_PRIO				1
#define START_TASK_STACK_SIZE 128
TaskHandle_t start_task_handler;
void start_task(void * pvParameters);

/*	TASK1	*/
#define TASK1_PRIO				2
#define TASK1_STACK_SIZE 128
TaskHandle_t task1_handler;
void task1(void * pvParameters);
/*	TASK2	*/
#define TASK2_PRIO				3
#define TASK2_STACK_SIZE 128
TaskHandle_t task2_handler;
void task2(void * pvParameters);
/*	TASK3	*/
#define TASK3_PRIO				4
#define TASK3_STACK_SIZE 128
TaskHandle_t task3_handler;
void task3(void * pvParameters);
/**************************************************************/
void freertos_demo(void)
{
	BaseType_t xReturned = xTaskCreate((TaskFunction_t) start_task,
										(char * 			 	) "start_task",
										(uint16_t			) START_TASK_STACK_SIZE,
										(void *				) NULL,
										(UBaseType_t	 	) START_TASK_PRIO,
										(TaskHandle_t *) &start_task_handler ); 
	if(xReturned == pdPASS)
		vTaskStartScheduler();	//开启任务调度器		
	else
		printf("开始任务创建失败");
}


void start_task(void * pvParameters)
{
	taskENTER_CRITICAL();		/* ½øÈëÁÙ½çÇø */
	xTaskCreate((TaskFunction_t) task1,
							(char * 			 ) "task1",
							(uint16_t			 ) TASK1_STACK_SIZE,
							(void *				 ) NULL,
							(UBaseType_t	 ) TASK1_PRIO,
							(TaskHandle_t *) &task1_handler );
							
	xTaskCreate((TaskFunction_t) task2,
							(char * 			 ) "task2",
							(uint16_t			 ) TASK2_STACK_SIZE,
							(void *				 ) NULL,
							(UBaseType_t	 ) TASK2_PRIO,
							(TaskHandle_t *) &task2_handler );
							
	xTaskCreate((TaskFunction_t) task3,
							(char * 			 ) "task3",
							(uint16_t			 ) TASK3_STACK_SIZE,
							(void *				 ) NULL,
							(UBaseType_t	 ) TASK3_PRIO,
							(TaskHandle_t *) &task3_handler );
	vTaskDelete(NULL);			//ɾ³ý×ÔÉí
	taskEXIT_CRITICAL();		/* Í˳öÁÙ½çÇø */
}
/*	任务一:LED0每500ms翻转一次	*/
void task1(void * pvParameters)
{
	while(1)
	{
		printf("任务一运行中!!!\r\n");
		GPIO_SetBits(GPIOB,GPIO_Pin_12);
		vTaskDelay(500);
		GPIO_ResetBits(GPIOB,GPIO_Pin_12);
		vTaskDelay(500);
 	}
}
/*	任务一:LED1每500ms翻转一次	*/
void task2(void * pvParameters)
{
	while(1)
	{
		printf("任务二运行中!!!\r\n");
		GPIO_SetBits(GPIOB,GPIO_Pin_13);
		vTaskDelay(500);
		GPIO_ResetBits(GPIOB,GPIO_Pin_13);
		vTaskDelay(500);
	}
}
/*	任务三:按下KEY0删除任务1	*/
void task3(void * pvParameters)
{ 
	printf("任务三运行中!!!\r\n");
	while(1)
	{
		if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0) == SET){
			vTaskDelay(10);
			//while等待松手时加个延迟可以让任务三不会一直抢占线程
			while(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0) == SET)vTaskDelay(10);
			if(task1_handler != NULL){
				vTaskDelete(task1_handler);
				printf("任务一删除成功!\r\n");
				task1_handler = NULL;
			}
		}
		vTaskDelay(10); //按键检测要加个延迟,因为任务三优先级最高,不然任务三会一直霸占线程
	}
}
/**************************************************************/

有FreeRTOS的问题可以评论私聊一起讨论一下噢

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值