freertos中的task可以任务是一个线程,它是freertos系统调度的一个单位,使用xTaskCreate() 可以创建出task,函数原型如下
BaseType_t xTaskCreate(TaskFunction_t pxTaskCode,
const char *const pcName,
const uint16_t usStackDepth,
void *const pvParameters,
UBaseType_t uxPriority,
TaskHandle_t *const pxCreatedTask) PRIVILEGED_FUNCTION;
第一个参数是task的入口函数;第二个参数是task 的名称,第三个参数是task的栈大小(单位不一定是字节,有些平台是4字节对齐,所以栈大小为usStackDepth * 4 字节),第四个参数是传到入口函数的参数,第五个参数是task的优先级,数值越大优先级越高(idle 的优先级是0),第六个参数是指向创建出来task的指针,可用于销毁该task。
下面是一个简单的示例
#include <stdio.h>
#include <string.h>
#include "FreeRTOS/FreeRTOS.h"
#include "FreeRTOS/task.h"
#include "FreeRTOS/queue.h"
#define DEMO_TASK_NAME "demo_task" // 任务名称
#define DEMO_TASK_PRIORITY (tskIDLE_PRIORITY + 12 ) // 任务优先级
#define DEMO_TASK_STACK_SIZE ( 2048 ) // 任务栈大小
#define DEMO_QUEUE_LENGTH ( 5 ) // 队列长度
enum
{
DEMO_MSG_LOG,
}; //消息类型枚举
typedef struct demo_message
{
unsigned char msg_type;
char* msg_content;
} demo_message_t; //消息结构体
static QueueHandle_t demo_message_queue; //指向消息队列
static TaskHandle_t demo_task_handle; //指向创建出来的任务
static BaseType_t demo_task_ready = pdFALSE;//任务是否成功创建标志
static void demo_task(void *pvParameters)
{
demo_message_t xMessage;
for( ;; )
{
/* Wait until a message arrives. */
while(xQueueReceive(demo_message_queue, ( void * )&xMessage, portMAX_DELAY ) == pdPASS )
{
switch(xMessage.msg_type) //需要处理的消息类型
{
case DEMO_MSG_LOG:
if(xMessage.msg_content != NULL)
{
printf("[demo_task] msg_content = %s \n",xMessage.msg_content);
free(xMessage.msg_content); //释放内存
}
break;
default: break;
}
}
}
int create_demo_task()
{
if(demo_task_ready == pdTRUE)
{
printf("[demo_task] demo task had create.\n");
return 0;
}
demo_message_queue = xQueueCreate(DEMO_QUEUE_LENGTH, sizeof(demo_message_t));
if(demo_message_queue == NULL)
{
printf("[demo_task] xQueueCreate fail.\n");
return -1;
}
BaseType_t ret=xTaskCreate(demo_task, DEMO_TASK_NAME, DEMO_TASK_STACK_SIZE, NULL, DEMO_TASK_PRIORITY, &demo_task_handle);
if(ret != pdPASS)
{
printf("[demo_task] xTaskCreate fail.\n");
vQueueDelete(demo_message_queue); //销毁消息队列
return -1;
}
demo_task_ready = pdTRUE; //标志任务成功创建
return 0;
}
int destroy_demo_task()
{
if(demo_task_ready == pdTRUE)
{
vQueueDelete(demo_message_queue);
vTaskDelete(demo_task_handle);
}
demo_task_ready = pdFALSE;
return 0;
}
int demo_log_d(const char* log)
{
if(demo_task_ready == pdFALSE)
{
printf("[demo_task] demo task had no start.\n");
return -1;
}
if(log == NULL)
{
printf("[demo_task] log is null.\n");
return -1;
}
int len = strlen(log);
demo_message_t xMessage;
xMessage.msg_type = DEMO_MSG_LOG;
xMessage.msg_content = (char*)malloc(len+1);//多加一个结束标志
if(xMessage.msg_content == NULL)
{
printf("[demo_task] malloc buff fail.\n");
return -1;
}
xMessage.msg_content[len] = '\0'; //结束标志
BaseType_t ret = xQueueSend(demo_message_queue, ( void * )&xMessage, 0);
if(ret == pdFALSE)
{
printf("[demo_task] xQueueSend fail.\n");
free(xMessage.msg_content); //释放内存
return -1;
}
return 0;
}
task 和queue 的创建调用接口就行了,考虑好创建失败的情况就可以了。创建好了之后,将queue和task关联起来就可以做成一个消息队列,task循环从队列中取出消息进行处理,如果队列中没有消息,就休眠等待,直到有消息进来。
本文简述了FreeRTOS系统中的任务(task)创建和队列(queue)的使用。通过xTaskCreate()函数可以创建任务,参数包括入口函数、任务名、栈大小、传递给任务的参数、优先级和任务指针。任务优先级数值越大,优先级越高。示例中展示了任务和队列的基本创建。将队列与任务关联后,任务可以从队列中取出消息处理,无消息时会休眠等待。

被折叠的 条评论
为什么被折叠?



