Extra 5% OFF Use Code: OL05
Free Shipping over ₹999

Queues in FreeRTOS

In FreeRTOS, a queue is a data structure that allows for communication between tasks or between tasks and interrupts. Queues provide a safe way to send and receive messages or data in a multi-threaded environment, ensuring that tasks can synchronize and communicate without stepping on each other’s toes.

Key Features of Queues

  1. Data Storage: Queues can store multiple items of data (e.g., integers, structures) until they are processed by a receiving task.
  2. Synchronization: Queues help synchronize tasks by ensuring that data is only accessed when available.
  3. Blocking and Non-blocking Operations: FreeRTOS provides both blocking and non-blocking APIs for sending and receiving items from queues.
  4. Task Communication: Queues are commonly used for inter-task communication, allowing tasks to send messages or share data.

Example: Using Queues in FreeRTOS

In this example, we’ll create two tasks: one that produces data (a producer) and another that consumes data (a consumer). The producer will send integer values to the queue, and the consumer will read and print those values.

Step 1: Set Up the Environment

Make sure you have ESP-IDF installed and your environment set up:

. $HOME/esp/esp-idf/export.sh

Step 2: Create a New Project

Create a new folder for your project and initialize it.

Step 3: Write the Code

Here’s a simple FreeRTOS application using a queue:

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

#define QUEUE_SIZE 5 // Define the size of the queue
#define ITEM_SIZE sizeof(int) // Define the size of each item in the queue

// Create a queue handle
QueueHandle_t queue;

// Producer task
void producer_task(void *pvParameter) {
    int item;
    while (1) {
        item = rand() % 100; // Generate a random integer (0-99)
        if (xQueueSend(queue, &item, portMAX_DELAY) == pdPASS) {
            printf("Produced: %d\n", item);
        } else {
            printf("Failed to send to queue.\n");
        }
        vTaskDelay(1000 / portTICK_PERIOD_MS); // Delay for 1 second
    }
}

// Consumer task
void consumer_task(void *pvParameter) {
    int item;
    while (1) {
        if (xQueueReceive(queue, &item, portMAX_DELAY) == pdPASS) {
            printf("Consumed: %d\n", item);
        } else {
            printf("Failed to receive from queue.\n");
        }
        vTaskDelay(2000 / portTICK_PERIOD_MS); // Delay for 2 seconds
    }
}

// Main application entry point
void app_main(void) {
    // Create a queue capable of holding 5 integers
    queue = xQueueCreate(QUEUE_SIZE, ITEM_SIZE);

    // Create the producer and consumer tasks
    xTaskCreate(producer_task, "Producer Task", 2048, NULL, 1, NULL);
    xTaskCreate(consumer_task, "Consumer Task", 2048, NULL, 1, NULL);
}

Explanation of the Code

  1. Queue Definition:
    • A queue handle queue is declared.
    • The queue size is defined as 5, meaning it can hold up to 5 items at a time.
    • Each item in the queue is an integer.
  2. Producer Task (producer_task):
    • This task generates a random integer (0-99) every second.
    • It attempts to send the generated integer to the queue using xQueueSend().
    • If the queue is full, it prints a message indicating failure; otherwise, it prints the produced item.
    • The portMAX_DELAY parameter makes the function wait indefinitely until space is available in the queue.
  3. Consumer Task (consumer_task):
    • This task attempts to receive an integer from the queue every two seconds using xQueueReceive().
    • If successful, it prints the consumed item; if it fails, it prints a failure message.
    • The portMAX_DELAY parameter makes the function wait indefinitely until an item is available in the queue.
  4. Main Function (app_main):
    • The queue is created using xQueueCreate(), specifying the size and item size.
    • The producer and consumer tasks are created using xTaskCreate().

Step 4: Build and Flash the Project

  1. Build the project:
idf.py build

2. Flash the project to the ESP32:

idf.py -p /dev/ttyUSB0 flash

Output Explanation

When you run the project, you will see output similar to this:

Produced: 42
Consumed: 42
Produced: 27
Consumed: 27
Produced: 88
Consumed: 88
...

The producer will produce random numbers, and the consumer will consume them in the order they were sent. The producer adds items to the queue, and the consumer retrieves items from the queue, demonstrating inter-task communication using FreeRTOS queues.

Summary

In this example, we demonstrated how to create and use queues for communication between tasks in FreeRTOS. Queues are a powerful tool for synchronizing tasks and facilitating data transfer, ensuring that tasks can operate independently while still sharing information safely and efficiently. Understanding how to use queues is essential for developing responsive and robust embedded applications.

    Leave a Reply

    Your email address will not be published.

    Need Help?