Инкапсуляция объекта очереди RTOS в пользовательском интерфейсе IQueue, имеющем только статическое распределение - PullRequest
0 голосов
/ 18 октября 2018

во встроенной компонентной системе, у меня есть пользовательский интерфейс IQueue, который может получить конкретную системную реализацию, например, FreeRTOSQueue.

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

Я хотел бы использовать только статическое распределение, которое яне могу сделать с IQueue.Поскольку это система, основанная на компонентах, я не хочу создавать экземпляр FreeRTOSQueue непосредственно в системном классе.

Идеальным вариантом использования будет что-то вроде следующего кода, который похож на использование FreeRTOS.

class MyApplication {
public:
    ...

    IQueue queue;

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

Я мог бы создавать очереди как глобальные и вставлять в классы вместе с экземпляром ядра и другими компонентами, но это не очень хорошо, потому что очередь не является системным элементом, это элемент только этого модуля.

Я хотел бы услышать предложения по архитектуре о том, как сделать его более простым и понятным.Пожалуйста, имейте в виду, что это встроенная система.

obs .: если вы считаете, что это невозможно, так как в какой-то момент мне нужно выделить память для определенного класса очереди, не стесняйтесь указывать на это.

Спасибо,

Рафаэль

Ответы [ 2 ]

0 голосов
/ 01 ноября 2018

Если я правильно вас понимаю, то, что вы ищете, называется потокобезопасным пулом памяти: https://en.m.wikipedia.org/wiki/Memory_pool.

Поиск в этом выражении дает массу точных проектов и реализаций, включая Boost, который бы работалдля любой ОС, а не только FreeRTOS

0 голосов
/ 19 октября 2018

Я нашел подходящее для меня решение, надеюсь, оно поможет всем, кому нужно нечто подобное.

Сначала я объявил интерфейс IQueue, а forward объявил тип очереди

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

затем, когда я объявил свой интерфейс IKernel, метод createQueue, возвращаемый по значению объектом Queue

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

для реализации, я объявил FreeRTOSQueue и класс Queue, унаследованный от него:

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, этодумаю, что будет чище.

...