FreeRTOS kernel: Detailed explanation of Queue queue FIFO (GPT4 help writing)

(Note: Part of the copywriting in this article was generated with the assistance of ChatGPT, but the content has been reviewed and optimized by Howie, so feel free to use it.)


1. Background

When we use FreeRTOS in an embedded system, Queue (Queue) is a very important data structure, which can help us realize the communication between multiple tasks.

In FreeRTOS, the implementation of the queue is based on the principle of FIFO (First-In-First-Out), which means that the data that enters the queue first will be dequeued first.

Below, we dive into the details and usage of FreeRTOS queue management.

A FreeRTOS queue is a data structure that can pass data between tasks. A queue can store multiple data items, and each data item can be any type of data, such as integers and structures. The implementation of the queue is based on the FIFO principle

insert image description here


2. Queue-related APIs

2.1 xQueueCreate(): create

In FreeRTOS, we can use the xQueueCreate() function to create a queue. The function's prototype looks like this:

QueueHandle_t xQueueCreate(UBaseType_t uxQueueLength, UBaseType_t uxItemSize);

After the queue is created, a handle is returned to facilitate reference to the queue, where the uxQueueLength parameter is the maximum number of data items that can be stored in the queue, and the uxItemSize parameter is the size (in bytes) of each data item.

When creating, the FreeRTOS kernel allocates FIFO memory space from the heap space Heap, if there is not enough space, the function returns NULL

For example, if we want to create a queue that can store 10 integers, we can use the following code:

QueueHandle_t xQueue = xQueueCreate(10, sizeof(int));

.

2.2 xQueueSend(): send

In FreeRTOS, we can use the xQueueSend() function to send data to the queue. The function's prototype looks like this:

BaseType_t xQueueSend(QueueHandle_t xQueue, const void * pvItemToQueue, TickType_t xTicksToWait);

Among them, the xQueue parameter is the queue handle of the data to be sent, the pvItemToQueue parameter is the pointer of the data to be sent, and the xTicksToWait parameter is the maximum time waiting for the data to be sent (in FreeRTOS clock ticks).

xQueueSend() == xQueneSendToBack() sends data to the end of queue
interrupt, use xQueueSendToBackFromISR() safe version API

For example, if we wanted to send the integer 10 to the queue, we could use the following code:

int data = 10;
BaseType_t result = xQueueSend(xQueue, &data, 100);

In the code above, we send the integer 10 to the queue and wait 100 FreeRTOS ticks for the data to be sent. The return value of this function is a value of type BaseType_t, which is used to indicate whether the data is successfully sent to the queue.

.

2.3 xQueueReceive(): receive

In FreeRTOS, we can use the xQueueReceive() function to receive data from the queue. The function's prototype looks like this:

BaseType_t xQueueReceive(QueueHandle_t xQueue, void * pvBuffer, TickType_t xTicksToWait);

Among them, the xQueue parameter is the queue handle to receive data, the pvBuffer parameter is a pointer to a buffer for storing the received data, and the xTicksToWait parameter is the maximum time for waiting for data to be received (in FreeRTOS clock ticks).

XQueueReceive() is used to read data from FIFO, and the read unit data will be automatically deleted from FIFO at the same time

For example, if we want to receive an integer from the queue, we can use the following code:

int data;
BaseType_t result = xQueueReceive(xQueue, &data, 100);

In the above code, we receive an integer from the queue and wait 100 FreeRTOS ticks for the data to be received. The return value of this function is a value of type BaseType_t, which is used to indicate whether the data has been successfully received in the buffer.

.

2.4 vQueueDelete(): delete

In FreeRTOS, we can use the vQueueDelete() function to delete a queue. The function's prototype looks like this:

void vQueueDelete(QueueHandle_t xQueue);

Among them, the xQueue parameter is the queue handle to be deleted. For example, if we wanted to delete the queue created above, we could use the following code:

vQueueDelete(xQueue);

.

2.5 xQueuePeek() : read data from FIFO without deleting, and do not change FIFO after reading

Use xQueueReceiveFromISR() in the same interrupt

.

2.6 uxQueueMessagesWaiting(): Returns the number of valid data units currently in the FIFO.

.

2.7 xQueueReset(): used to reset the queue.


3. The principle of FreeRTOS FIFO

All communication and synchronization mechanisms in FreeRTOS are implemented based on message queues

  • A queue is a linked list
  • Queue has two keywords: depth and size of each unit. The depth is the maximum number of units that the queue can hold

FIFO is a kernel object with its own independent authority, which is not a resource of Task. All tasks can write and read from the same FIFO queue.

Task status when reading FIFO:

A blocking timeout can be set for the Task read queue.
1. Under normal circumstances, within the set timeout period, if the FIFO is empty, the task will remain blocked. When the FIFO has data written (such as other Tasks or interrupts writing to the FIFO), At this time, the Task will automatically change from the blocking state to the ready state.
2. When the waiting time exceeds the set timeout period, even if the queue is empty, the Task will automatically turn to the ready state.
If multiple tasks read the FIFO, decide which Task is unblocked according to the priority and waiting time

Task status when writing FIFO:

When the FIFO is full, the task in the write queue enters the blocking state to wait for the FIFO space to become available, and the blocking timeout can also be set.

insert image description here

Regarding priority:

If the task priority of the read queue is high -> the queue is always empty, otherwise the priority of the write queue is high -> the queue is always full

Once the read queue task reads a data unit from the queue, a write queue task will immediately preempt the read queue task, rewrite the position just read, and then enter the blocking state to wait for the queue space to become available.

If the priority of the read queue task is the lowest, the read queue task will be executed only when all write queue tasks enter the blocking state, and the write queue will enter the blocked state only when the queue is full, so the queue must be certain when the read queue task is executed. is full.

4. Code example

Here is a simple code example demonstrating how to use FIFO queues in FreeRTOS:

#include <stdio.h>
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#define QUEUE_LENGTH 5
#define QUEUE_ITEM_SIZE sizeof(int)
QueueHandle_t queue;
void producer_task(void *pvParameters)
{
    
    
    int i;
    for (i = 0; i < 10; i++) {
    
    
        printf("Producer: Sending %d to queue\n", i);
        xQueueSend(queue, &i, 0);
    }
    vTaskDelete(NULL);
}
void consumer_task(void *pvParameters)
{
    
    
    int item;
    while (1) {
    
    
        xQueueReceive(queue, &item, portMAX_DELAY);
        printf("Consumer: Received %d from queue\n", item);
    }
}
int main(void)
{
    
    
    queue = xQueueCreate(QUEUE_LENGTH, QUEUE_ITEM_SIZE);
    xTaskCreate(producer_task, "Producer", 1000, NULL, 1, NULL);
    xTaskCreate(consumer_task, "Consumer", 1000, NULL, 1, NULL);
    vTaskStartScheduler();
    return 0;
}

In this example, we create a FIFO queue, and create a producer task and a consumer task. Producer tasks send data to the queue, and consumer tasks receive data from the queue. In this way, we can test how the FIFO queue works.


5. Summary

FreeRTOS provides a very convenient and efficient FIFO queue management method, which can help developers better manage and transmit data. In practical applications, we can choose different queue management methods according to specific needs, and write corresponding codes according to the changing rules to realize data storage and transmission.


Blogger's popular article recommendation:

insert image description here

A reading series:

LoRa Mesh series:

Network Security Series:

Embedded development series:

AI/Machine Learning Series:


Attachment: GPT4 output:

insert image description here
insert image description here
insert image description here

Guess you like

Origin blog.csdn.net/HowieXue/article/details/120700322