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循環從隊列中取出消息進行處理,如果隊列中沒有消息,就休眠等待,直到有消息進來。