Skip to content

Circular Queue

Description

  • Functions as a regular queue.
  • When full, the next new entry overwrites the oldest entry.
  • Implemented with C++ generics to support any data type.
  • The following functionalities are supported:
    • Inserting
    • Removing
    • Checking whether it is empty or full
    • Clearing
    • Locking and unlocking an internal mutex

Firmware Component Library

Library API Docs

Source Code

Info

This is a common data structure. You can find plenty of information online, such as GeeksForGeek's Introduction to Circular Queue.

Example

Creating a circular queue of integers.

#include "../DFR_Libraries/Application/circular_queue.hpp"

int main() {
    int size = 5;
    pplication::CircularQueue<int> queue(size);

    queue.Enqueue(8);
    queue.Enqueue(2);
    queue.Enqueue(11);
    queue.Enqueue(9);
    queue.Enqueue(4);

    if (queue.IsFull()) {
        printf("Queue is full!\n");
    }

    // Overwrite entry of number 8
    queue.Enqueue(33);

    return 0;
}

Example

Creating a circular queue of DataPayloads.

#include "../DFR_Libraries/Application/circular_queue.hpp"
#include "../DFR_Libraries/Application/data_payload.hpp"

int main() {
    int size = 5;
    pplication::CircularQueue<application::DataPayload> queue(size);

    DataPayload data;
    data.timestamp_ = 2.0f;

    // Insert a copy of the data payload at this instant
    queue.Enqueue(data);

    if (!queue.IsEmpty()) {
        // Receive from the queue
        DataPayload data = queue.Dequeue();
        printf("Timestamp: %f\n", data.timestamp_);
    }

    return 0;
}

The CircularQueue also has an additional constructor for accepting a mutex, if this were to be used as a shared component among threads in an RTOS environment.

Example

Sharing a circular queue between threads using FreeRTOS through CMSIS-RTOS v2.

Assume that the Kernel is already initialized and running.

#include "../DFR_Libraries/Application/circular_queue.hpp"
#include "../DFR_Libraries/Application/data_payload.hpp"

const osMutexAttr_t queue_mutex_attributes = {
    "myThreadMutex",
    osMutexRecursive | osMutexPrioInherit,
    NULL,
    0U
};

auto mutex = std::make_shared<application::MutexCmsisV2>(queue_mutex_attributes);

int size = 5;
application::CircularQueue<int> queue(size, mutex);

void ProducerThread() {
    int num = 2;

    for(;;) {
        num *= 2;

        queue.Lock();
        queue.Enqueue(num);
        queue.Unlock();
    }
}

void ConsumerThread() {
    for(;;) {
        queue.Lock();
        int received_num = queue.Dequeue();
        queue.Unlock();

        printf("Received: %d\n", received_num);
    }
}