将 RTOS 队列对象封装在仅具有静态分配的 IQueue 自定义接口中
Encapsulating RTOS Queue object in an IQueue custom interface having only static allocation
在基于嵌入式组件的系统中,我有一个自定义接口 IQueue,它可以派生出特定的系统实现,例如,FreeRTOSQueue。
class IQueue { ... virtual void push(...) = 0; ... };
class FreeRTOSQueue : public IQueue { ... };
我只想使用静态分配,而 IQueue 无法做到这一点。由于它是一个基于组件的系统,我不想将FreeRTOSQueue直接实例化成一个系统class。
理想的用法类似于下面的代码,这与 FreeRTOS 的用法有点相似。
class MyApplication {
public:
...
IQueue queue;
void init()
{
this->queue = this->kernel->createQueue(...);
}
};
我可以将队列实例化为全局变量并与内核实例和其他组件一起注入 classes,但这不是很好,因为队列不是系统元素,它是仅限该模块。
我想听听架构方面的建议,以了解使它简洁明了的最佳方法。请记住它是一个嵌入式系统。
obs.: 如果您认为这是不可能的,因为在某些时候我需要为特定队列分配一些内存class,请随时指出。
谢谢,
拉斐尔
我找到了适合自己的解决方案,希望对有类似需求的人有所帮助。
首先,我声明了一个接口 IQueue 并向前声明了一个类型 Queue
class IQueue { ... virtual void push(...) = 0; ... };
class Queue;
然后,当我声明我的 IKernel 接口时,createQueue 方法返回 Queue 对象的值
class IKernel { ... virtual Queue createQueue(...) = 0; ... };
为了实现,我声明了一个 FreeRTOSQueue 和从它继承的队列 class:
class FreeRTOSQueue : public IQueue { ... xQueueHandle handle; ... };
class Queue : public FreeRTOSQueue {};
FreeRTOSQueue 将包含 xQueueHandle,同样可以扩展到信号量。内核 createQueue 实现将是:
class FreeRTOSKernel : public IKernel {
public:
Queue createQueue(...)
{
Queue q;
q.handle = xQueueCreate(...);
return q;
}
}
以及用法:
class MyApplication {
public:
...
Queue queue;
void init()
{
this->queue = this->kernel->createQueue(...);
}
};
我仍在考虑将 createQueue 作为 "init" 方法移动到 IQueue class 上,它认为这样会更干净。
如果我没理解错的话,你要找的是所谓的线程安全内存池:
https://en.m.wikipedia.org/wiki/Memory_pool。
用谷歌搜索这个术语会产生大量准确的设计和实现,包括适用于任何 OS 而不仅仅是 FreeRTOS
的 Boost
在基于嵌入式组件的系统中,我有一个自定义接口 IQueue,它可以派生出特定的系统实现,例如,FreeRTOSQueue。
class IQueue { ... virtual void push(...) = 0; ... };
class FreeRTOSQueue : public IQueue { ... };
我只想使用静态分配,而 IQueue 无法做到这一点。由于它是一个基于组件的系统,我不想将FreeRTOSQueue直接实例化成一个系统class。
理想的用法类似于下面的代码,这与 FreeRTOS 的用法有点相似。
class MyApplication {
public:
...
IQueue queue;
void init()
{
this->queue = this->kernel->createQueue(...);
}
};
我可以将队列实例化为全局变量并与内核实例和其他组件一起注入 classes,但这不是很好,因为队列不是系统元素,它是仅限该模块。
我想听听架构方面的建议,以了解使它简洁明了的最佳方法。请记住它是一个嵌入式系统。
obs.: 如果您认为这是不可能的,因为在某些时候我需要为特定队列分配一些内存class,请随时指出。
谢谢,
拉斐尔
我找到了适合自己的解决方案,希望对有类似需求的人有所帮助。
首先,我声明了一个接口 IQueue 并向前声明了一个类型 Queue
class IQueue { ... virtual void push(...) = 0; ... };
class Queue;
然后,当我声明我的 IKernel 接口时,createQueue 方法返回 Queue 对象的值
class IKernel { ... virtual Queue createQueue(...) = 0; ... };
为了实现,我声明了一个 FreeRTOSQueue 和从它继承的队列 class:
class FreeRTOSQueue : public IQueue { ... xQueueHandle handle; ... };
class Queue : public FreeRTOSQueue {};
FreeRTOSQueue 将包含 xQueueHandle,同样可以扩展到信号量。内核 createQueue 实现将是:
class FreeRTOSKernel : public IKernel {
public:
Queue createQueue(...)
{
Queue q;
q.handle = xQueueCreate(...);
return q;
}
}
以及用法:
class MyApplication {
public:
...
Queue queue;
void init()
{
this->queue = this->kernel->createQueue(...);
}
};
我仍在考虑将 createQueue 作为 "init" 方法移动到 IQueue class 上,它认为这样会更干净。
如果我没理解错的话,你要找的是所谓的线程安全内存池: https://en.m.wikipedia.org/wiki/Memory_pool。
用谷歌搜索这个术语会产生大量准确的设计和实现,包括适用于任何 OS 而不仅仅是 FreeRTOS
的 Boost