一.动态创建任务
1.宏定义
xTaskCreate()函数使用动态的方法创建一个任务,使用该函数所需的 RAM 会自动从 FreeRTOS的堆中自动分配。在动态创建一个任务前,需要定义FreeRTOS.h中的宏configSUPPORT_DYNAMIC_ALLOC
若想使用动态创建任务则需要将该宏置1
#define configSUPPORT_DYNAMIC_ALLOCATION 1
2.xTaskCreate函数
BaseType_t xTaskCreate( TaskFunction_t pxTaskCode, //任务函数
const char * const pcName, //任务名字,长度不超过...
configMAX_TASK_NAME_LEN
const uint16_t usStackDepth, //任务堆栈大小
void * const pvParameters, //传递给任务的参数
UBaseType_t uxPriority, //任务优先级
TaskHandle_t * const pxCreatedTask ) //任务句柄 即任务的任务堆栈
3.实例代码
#include "Device/Include/stm32f10x.h" // Device header
#include "FreeRTOS.h"
#include "task.h"
#include "LED.h"
TaskHandle_t Task1_Handler; //任务句柄
void LED1_Task(void* pvParameters); //任务函数
TaskHandle_t Task2_Handler; //任务句柄
void LED2_Task(void* pvParameters); //任务函数
int main(void)
{
LED_Init(); //硬件初始化
xTaskCreate(LED1_Task, //任务函数
"LED1_Task", //任务名称
configMINIMAL_STACK_SIZE, //任务堆栈大小 此处使用默认最小
NULL, //传递给任务函数的参数
1, //任务优先级
&Task1_Handler); //任务句柄
xTaskCreate(LED2_Task,
"LED2_Task",
configMINIMAL_STACK_SIZE, //...
NULL,
1,
&Task2_Handler);
vTaskStartScheduler(); //开启任务调度
while(1);
}
// task1任务函数
void LED1_Task(void* pvParameters)
{
while(1)
{
LED1_Turn();
vTaskDelay(1000);
LED1_Turn();
vTaskDelay(1000);
}
}
// task2任务函数
void LED2_Task(void* pvParameters)
{
while(1)
{
LED2_Turn();
vTaskDelay(100);
LED2_Turn();
vTaskDelay(1000);
}
}
前三个由我们自己创建,后三个由操作系统来完成。
二.静态任务创建
1.宏定义
在静态创建一个任务前,需要定义FreeRTOS.h中的宏configSUPPORT_STATIC_ALLOC
使用前需将其置1
#define configSUPPORT_STATIC_ALLOCATION 1
2.xCreateStatic函数
/*在创建任务之前,需要自己定义任务堆栈大小与任务控制块*/
TaskHandle_t Task1_Handler; //任务句柄
void Task1(void *pvParameters); //任务函数
StackType_t Task1TaskStack[128]; //任务堆栈 堆栈大小为128字 即128*4字节
StaticTask_t Task1TaskTCB; //任务控制块
/* 与动态创建不一样,这里不用传入任务句柄,任务句柄由函数xTaskCreateStatic返回 */
Task1_Handler = xTaskCreateStatic((TaskFunction_t )pxTaskCode, //任务函数
(const char* )"pcName", //任务名字
(uint16_t )usStackDepth,//任务堆栈大小
(void* )pvParameters,//传递参数
(UBaseType_t )uxPriority, //任务优先级
(StackType_t* )Task1TaskStack,//堆栈起始地址
(StaticTask_t* )&Task1TaskTCB);//任务控制块
3.空闲任务与定时器服务任务
//空闲任务任务堆栈
static StackType_t IdleTaskStack[configMINIMAL_STACK_SIZE];
//空闲任务控制块
static StaticTask_t IdleTaskTCB;
//定时器服务任务堆栈
static StackType_t TimerTaskStack[configMINIMAL_STACK_SIZE];
//定时器服务任务控制块
static StaticTask_t TimerTaskTCB;
//获取空闲任务地任务堆栈和任务控制块内存,因为本例程使用的
//静态内存,因此空闲任务的任务堆栈和任务控制块的内存就应该
//由用户来提供,当没有任务占用CPU时,需要由空闲任务来占用CPU,静态创建中需要我们自己实现
//FreeRTOS提供了接口函数vApplicationGetIdleTaskMemory()
//实现此函数即可。
//ppxIdleTaskTCBBuffer:任务控制块内存
//ppxIdleTaskStackBuffer:任务堆栈内存
//pulIdleTaskStackSize:任务堆栈大小
void vApplicationGetIdleTaskMemory(StaticTask_t **ppxIdleTaskTCBBuffer,
StackType_t **ppxIdleTaskStackBuffer,
uint32_t *pulIdleTaskStackSize)
{
*ppxIdleTaskTCBBuffer=&IdleTaskTCB;
*ppxIdleTaskStackBuffer=IdleTaskStack;
*pulIdleTaskStackSize=configMINIMAL_STACK_SIZE;
}
//获取定时器服务任务的任务堆栈和任务控制块内存
//ppxTimerTaskTCBBuffer:任务控制块内存
//ppxTimerTaskStackBuffer:任务堆栈内存
//pulTimerTaskStackSize:任务堆栈大小
void vApplicationGetTimerTaskMemory(StaticTask_t **ppxTimerTaskTCBBuffer,
StackType_t **ppxTimerTaskStackBuffer,
uint32_t *pulTimerTaskStackSize)
{
*ppxTimerTaskTCBBuffer=&TimerTaskTCB;
*ppxTimerTaskStackBuffer=TimerTaskStack;
*pulTimerTaskStackSize=configMINIMAL_STACK_SIZE;
}
4.实例代码
#include "Device/Include/stm32f10x.h" // Device header
#include "FreeRTOS.h"
#include "task.h"
#include "LED.h"
#include "Key.h"
static StackType_t IdleTaskStack[configMINIMAL_STACK_SIZE];
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;
*ppxIdleTaskStackBuffer=IdleTaskStack;
*pulIdleTaskStackSize=configMINIMAL_STACK_SIZE;
}
void vApplicationGetTimerTaskMemory(StaticTask_t **ppxTimerTaskTCBBuffer,
StackType_t **ppxTimerTaskStackBuffer,
uint32_t *pulTimerTaskStackSize)
{
*ppxTimerTaskTCBBuffer=&TimerTaskTCB;
*ppxTimerTaskStackBuffer=TimerTaskStack;
*pulTimerTaskStackSize=configMINIMAL_STACK_SIZE;
}
TaskHandle_t Task1_Handler; //任务句柄
void task_1(void *pvParameters);
StackType_t Task1TaskStack[128]; //任务堆栈
StaticTask_t Task1TaskTCB; //任务控制块
TaskHandle_t Task2_Handler; //任务句柄
void task_2(void *pvParameters);
StackType_t Task2TaskStack[128]; //任务堆栈
StaticTask_t Task2TaskTCB; //任务控制块
int main(void)
{
LED_Init();
//创建开始任务
taskENTER_CRITICAL(); //进入临界区
//创建task1任务
Task1_Handler = xTaskCreateStatic((TaskFunction_t )task_1,
(const char* )"task_1",
(uint16_t )50,
(void* )NULL,
(UBaseType_t )2,
(StackType_t* )Task1TaskStack,
(StaticTask_t* )&Task1TaskTCB);
//创建task2任务
Task2_Handler = xTaskCreateStatic((TaskFunction_t )task_2,
(const char* )"task_2",
(uint16_t )50,
(void* )NULL,
(UBaseType_t )2,
(StackType_t* )Task2TaskStack,
(StaticTask_t* )&Task2TaskTCB);
taskEXIT_CRITICAL(); //退出临界区
vTaskStartScheduler(); //开启任务调度
}
//LED0任务函数
void task_1(void *pvParameters)
{
while(1)
{
LED1_Turn();
vTaskDelay(100);
}
}
//LED1任务函数
void task_2(void *pvParameters)
{
while(1)
{
LED2_Turn();
vTaskDelay(1000);
}
}
静态创建任务流程如下图