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
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.