freertos task创建和 queue使用简述

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 
#include 
#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)