经过上一次的移植后,本次开始创建第一个FreeRTOS任务
1.创建一个动态的任务,动态分配内存
cpp
BaseType_t xTaskCreate( TaskFunction_t pxTaskCode, //函数指针
const char * const pcName, //任务名字
const configSTACK_DEPTH_TYPE uxStackDepth, //任务栈大小(深度)
void * const pvParameters, //任务参数
UBaseType_t uxPriority, //任务优先级
TaskHandle_t * const pxCreatedTask //任务句柄
)
// 函数名 传入参数
//任务函数typedef void (* TaskFunction_t)( void * arg );
上述包含了创建一个任务所需函数以及内部参数注释
1.1初始化硬件
首先初始化你的基础硬件比如LED_init这种确保led可以正常使用。
cpp
void system_init()
{
delay_init(); //延时函数初始化
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
uart_init(115200); //串口初始化为115200
LED_Init(); //LED端口初始化
KEY_Init(); //初始化与按键连接的硬件接口
}
1.2创建任务函数
比如想让一个灯循环闪烁可以这样写
cpp
void LED0_TASK(void *param) //任务函数
{
while (1)
{
LED0 =!LED0;
vTaskDelay(1000);
}
}
1.3 创建任务
cpp
TaskHandle_t xled_task_handle;//首先定义任务句柄(一种结构体)
通过下行命令创建任务
cpp
xTaskCreate(LED0_TASK,"open_led",100,NULL,1,&xled_task_handle); //动态分配内存
第一个参数为任务指针,第二个为任务名,第三个为堆栈大小暂时设定为100,传入该任务的参数设为空,最后一个传入刚刚创建的句柄地址。上述就是创建一个动态分配内存任务的过程。
2.创建一个静态分配内存的任务
首先打开FreeRTOSConfig.h,修改如下宏定义
cpp
#define configSUPPORT_STATIC_ALLOCATION 1 /* 1: 支持静态申请内存, 默认: 0 */ //此时改为1
cpp
//静态分配任务//默认不打开静态分配任务需要去FreeRTOSConfig.h文件中将configSUPPORT_STATIC_ALLOCATION宏定义为1
TaskHandle_t xTaskCreateStatic( TaskFunction_t pxTaskCode,//函数指针
const char * const pcName,//任务名字
const configSTACK_DEPTH_TYPE uxStackDepth,//任务栈大小(深度)
void * const pvParameters,//任务参数
UBaseType_t uxPriority,//任务优先级
StackType_t * const puxStackBuffer,//静态栈分配空间
StaticTask_t * const pxTaskBuffer //分配TCB句柄
)
首先创建一个任务函数
cpp
void LED1_TASK(void *param) //任务函数
{
while (1)
{
LED1 =!LED1;
vTaskDelay(500);
}
}
第二步定义一个堆栈数据(一个数组),定义一个任务句柄
cpp
StackType_t xTaskLedStack[100] = {0};//注意此时数据堆栈大小需要按照创建的任务堆栈大小的深度一致
StaticTask_t xTaskLedBuffer;
最后创建一个静态任务
cpp
xTaskCreateStatic(LED1_TASK,"LED_Flicker",100,NULL,1,xTaskLedStack,&xTaskLedBuffer);
3.解决错误
通常在静态任务中会出现两个错误,如下

只要按照上面创建任务的方式将这两个函数重定义即可
如下:任务参数含义基本一致
cpp
// vApplicationGetIdleTaskMemory( &pxIdleTaskTCBBuffer, &pxIdleTaskStackBuffer, &uxIdleTaskStackSize );//参数1:空闲任务的TCB,参数2:空闲任务的栈,参数3:空闲任务栈大小
void vApplicationGetIdleTaskMemory( StaticTask_t ** ppxIdleTaskTCBBuffer,
StackType_t ** ppxIdleTaskStackBuffer,
configSTACK_DEPTH_TYPE * puxIdleTaskStackSize )
{
*ppxIdleTaskTCBBuffer = &( xIdleTaskTCBBuffer );
*ppxIdleTaskStackBuffer = &( xIdleTaskStack[ 0 ] );
*puxIdleTaskStackSize = 100;
}
void vApplicationGetTimerTaskMemory( StaticTask_t ** ppxTimerTaskTCBBuffer,
StackType_t ** ppxTimerTaskStackBuffer,
configSTACK_DEPTH_TYPE * puxTimerTaskStackSize )
{
*ppxTimerTaskTCBBuffer = &( xTimerTaskTCBBuffer );
*ppxTimerTaskStackBuffer = &( xTimerTaskStack[ 0 ] );
*puxTimerTaskStackSize = 100;
}
总的代码如下:
cpp
#include "led.h"
#include "delay.h"
#include "key.h"
#include "sys.h"
#include "FreeRTOS.h"
#include "task.h"
// BaseType_t xTaskCreate( TaskFunction_t pxTaskCode, //函数指针
// const char * const pcName, //任务名字
// const configSTACK_DEPTH_TYPE uxStackDepth, //任务栈大小(深度)
// void * const pvParameters, //任务参数
// UBaseType_t uxPriority, //任务优先级
// TaskHandle_t * const pxCreatedTask //任务句柄
// )
// 函数名 传入参数
//任务函数typedef void (* TaskFunction_t)( void * arg );
void system_init()
{
delay_init(); //延时函数初始化
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
LED_Init(); //LED端口初始化
KEY_Init(); //初始化与按键连接的硬件接口
}
void LED0_TASK(void *param) //任务函数
{
while (1)
{
LED0 =!LED0;
vTaskDelay(1000);
}
}
void LED1_TASK(void *param) //任务函数
{
while (1)
{
LED1 =!LED1;
vTaskDelay(500);
}
}
StackType_t xTaskLedStack[100] = {0};//注意此时数据堆栈大小需要按照创建的任务堆栈大小的深度一致
StaticTask_t xTaskLedBuffer;
StaticTask_t xIdleTaskTCBBuffer;
StackType_t xIdleTaskStack[100] = {0};
StaticTask_t xTimerTaskTCBBuffer;
StackType_t xTimerTaskStack[100] = {0};
//如果使用了静态分配内存必须提供如下函数
// vApplicationGetIdleTaskMemory( &pxIdleTaskTCBBuffer, &pxIdleTaskStackBuffer, &uxIdleTaskStackSize );//参数1:空闲任务的TCB,参数2:空闲任务的栈,参数3:空闲任务栈大小
void vApplicationGetIdleTaskMemory( StaticTask_t ** ppxIdleTaskTCBBuffer,
StackType_t ** ppxIdleTaskStackBuffer,
configSTACK_DEPTH_TYPE * puxIdleTaskStackSize )
{
*ppxIdleTaskTCBBuffer = &( xIdleTaskTCBBuffer );
*ppxIdleTaskStackBuffer = &( xIdleTaskStack[ 0 ] );
*puxIdleTaskStackSize = 100;
}
void vApplicationGetTimerTaskMemory( StaticTask_t ** ppxTimerTaskTCBBuffer,
StackType_t ** ppxTimerTaskStackBuffer,
configSTACK_DEPTH_TYPE * puxTimerTaskStackSize )
{
*ppxTimerTaskTCBBuffer = &( xTimerTaskTCBBuffer );
*ppxTimerTaskStackBuffer = &( xTimerTaskStack[ 0 ] );
*puxTimerTaskStackSize = 100;
}
int main(void)
{
TaskHandle_t xled_task_handle;
system_init();
//创建任务1
xTaskCreate(LED0_TASK,"open_led",100,NULL,1,&xled_task_handle); //动态分配内存
//静态分配任务//默认不打开静态分配任务需要去FreeRTOSConfig.h文件中将configSUPPORT_STATIC_ALLOCATION宏定义为1
// TaskHandle_t xTaskCreateStatic( TaskFunction_t pxTaskCode,//函数指针
// const char * const pcName,//任务名字
// const configSTACK_DEPTH_TYPE uxStackDepth,//任务栈大小(深度)
// void * const pvParameters,//任务参数
// UBaseType_t uxPriority,//任务优先级
// StackType_t * const puxStackBuffer,//静态栈分配空间
// StaticTask_t * const pxTaskBuffer
// )
xTaskCreateStatic(LED1_TASK,"LED_Flicker",100,NULL,1,xTaskLedStack,&xTaskLedBuffer);
//开启调度器
vTaskStartScheduler();
while (1)
{
;
}
// return 0;
}