Search code examples
c++architectureembeddedfreertosrtos

Encapsulating RTOS Queue object in an IQueue custom interface having only static allocation


in an embedded component based system, I have a custom interface IQueue that can derive a specific system implementation, for this example, FreeRTOSQueue.

class IQueue { ... virtual void push(...) = 0; ... };
class FreeRTOSQueue : public IQueue { ... };

I would like to use static allocation only, which I can not do with IQueue. Since it is a component based system, I do not want to instantiate FreeRTOSQueue directly into a system class.

The ideal usage would be something like the following code, which is kinda similar of the FreeRTOS usage.

class MyApplication {
public:
    ...

    IQueue queue;

    void init()
    {
        this->queue = this->kernel->createQueue(...);
    }
};

I could instantiate the queues as globals and inject into the classes along with kernel instance and other components, but it is not very good because the queue is not a system element, it is an element of that module only.

I would like to hear architecture suggestions on the best approach to make it clean and simple. Please keep in mind it is an embedded system.

obs.: if you think it is not possible, since at some point I need to have some memory allocated for the specific queue class, feel free to point that.

Thank you,

Rafael


Solution

  • I have found a suitable solution for me, I hope it helps anyone who needs something similar.

    First, I declared an interface IQueue and forward declared a type Queue

    class IQueue { ... virtual void push(...) = 0; ... };
    class Queue;
    

    then, when I declared my IKernel interface, the createQueue method returned by value the Queue object

    class IKernel { ... virtual Queue createQueue(...) = 0; ... };
    

    for the implementation, I declared a FreeRTOSQueue and the Queue class inheriting from it:

    class FreeRTOSQueue : public IQueue { ... xQueueHandle handle; ... };
    class Queue : public FreeRTOSQueue {};
    

    the FreeRTOSQueue will contain the xQueueHandle, the same could be extended to semaphores. The kernel createQueue implementation would be:

    class FreeRTOSKernel : public IKernel {
    public:
        Queue createQueue(...)
        {
            Queue q;
            q.handle = xQueueCreate(...);
            return q;
        }
    }
    

    and, the usage:

    class MyApplication {
    public:
        ...
    
        Queue queue;
    
        void init()
        {
            this->queue = this->kernel->createQueue(...);
        }
    };
    

    I am still thinking about moving the createQueue as an "init" method on the IQueue class, it think it would be cleaner.