FreeRTOS队列的特点

FreeRTOS队列是一种用于任务间通信的机制,具有以下特点:

  1. 先进先出(FIFO):FreeRTOS队列采用先进先出的原则,即最早放入队列的数据最先被取出。
  2. 有限长度:队列的长度是固定的,需要在创建队列时指定长度,队列满时无法继续添加数据,队列空时无法继续取出数据。
  3. 阻塞和非阻塞:FreeRTOS队列支持阻塞和非阻塞两种模式。在阻塞模式下,当队列已满时,尝试往队列中添加数据的任务会被阻塞,直到队列有空闲空间;当队列为空时,尝试从队列中取出数据的任务会被阻塞,直到队列中有数据可取。在非阻塞模式下,尝试往满队列中添加数据或从空队列中取出数据时,任务不会被阻塞,而是立即返回一个错误码。
  4. 可用于不同数据类型:FreeRTOS队列能够存储不同类型的数据,例如整数、浮点数、结构体等。
  5. 线程安全:FreeRTOS队列在多任务环境下保证数据的安全性,可以同时被多个任务读写。

FreeRTOS队列的相关操作

FreeRTOS提供了一系列函数用于创建、删除、读写队列,常用的队列操作函数有:

  1. xQueueCreate(): 创建队列,需要指定队列的长度和数据类型。
  2. xQueueSend(): 往队列中发送数据,可以指定阻塞时间。
  3. xQueueReceive(): 从队列中接收数据,可以指定阻塞时间。
  4. uxQueueMessagesWaiting(): 获取队列中当前等待的消息数。
  5. vQueueDelete(): 删除队列,释放内存。

示例代码

下面是一个使用FreeRTOS队列的示例代码,其中创建了一个长度为5的队列,两个任务分别向队列中发送数据和接收数据:

#include <stdio.h>
#include <stdlib.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"

#define QUEUE_LENGTH 5
#define ITEM_SIZE sizeof(int)

xQueueHandle queue;

void sender_task(void *pvParameters)
{
    for (int i = 0; i < QUEUE_LENGTH; i++)
    {
        if (xQueueSend(queue, &i, portMAX_DELAY) != pdPASS)
        {
            printf("Failed to send item to queue\n");
        }
    }
    vTaskDelete(NULL);
}

void receiver_task(void *pvParameters)
{
    int item;
    for (int i = 0; i < QUEUE_LENGTH; i++)
    {
        if (xQueueReceive(queue, &item, portMAX_DELAY) != pdPASS)
        {
            printf("Failed to receive item from queue\n");
        }
        printf("Received item: %d\n", item);
    }
    vTaskDelete(NULL);
}

void app_main()
{
    queue = xQueueCreate(QUEUE_LENGTH, ITEM_SIZE);
    if (queue == NULL)
    {
        printf("Failed to create queue\n");
        return;
    }

    xTaskCreate(sender_task, "sender_task", 2048, NULL, 5, NULL);
    xTaskCreate(receiver_task, "receiver_task", 2048, NULL, 5, NULL);
}

以上代码创建了一个长度为5的队列,并定义了两个任务sender_taskreceiver_task,分别用于发送和接收数据。sender_task向队列中发送数据,receiver_task从队列中接收数据,并打印接收到的数据。任务通过xQueueSendxQueueReceive函数来操作队列。