Message Queue für RTOS für Mikrocontroller

10

Ich schreibe gerade ein RTOS für Mikrocontroller. Das Ganze ist in C ++ 11 geschrieben - wenn jemand interessiert ist und der Link zum Repository unten ist.

Derzeit schreibe ich eine Klasse, die eine einfache Datenwarteschlange zum Übergeben von Objekten zwischen Threads (oder zwischen Interrupt-Handlern und Threads oder Interrupt-Handlern und anderen Interrupt-Handlern) ist. Normalerweise versuche ich, einige gängige APIs zu befolgen, die in anderen Projekten gefunden wurden, aber ich habe kein Beispiel für eine gleichzeitige Warteschlange gefunden, die über eine emplace()Funktion verfügt UND Zeitüberschreitungen unterstützt.

Mein allgemeines "Problem" ist, dass ich mich nicht zwischen diesen beiden Schnittstellen entscheiden kann:

( std::chrono::duration<Rep, Period>ist ein Vorlagen-Typ, ich lasse die Vorlagen-Boilerplate der Klarheit halber weg)

Erste Version:

template<typename T>
class FifoQueue
{
public:
    ...
    template<typename... Args>
    int tryEmplaceFor(std::chrono::duration<Rep, Period>, Args&&... args);
    int tryPopFor(T&, std::chrono::duration<Rep, Period>);
    int tryPushFor(const T&, std::chrono::duration<Rep, Period>);
    int tryPushFor(T&&, std::chrono::duration<Rep, Period>);
    ...
}

Zweite Version:

template<typename T>
class FifoQueue
{
public:
    ...
    template<typename... Args>
    int tryEmplaceFor(std::chrono::duration<Rep, Period>, Args&&... args);
    int tryPopFor(std::chrono::duration<Rep, Period>, T&);
    int tryPushFor(std::chrono::duration<Rep, Period>, const T&);
    int tryPushFor(std::chrono::duration<Rep, Period>, T&&);
    ...
}

(Es wird einen zweiten Satz dieser Funktionen mit ...UntilSuffix geben - diese würden den Zeitpunkt anstelle der Dauer verwenden.)

Die erste Version folgt einem "allgemeinen Stil", bei dem das Zeitlimit als letzter Parameter verwendet wird (Beispiele sind POSIX-Nachrichtenwarteschlangen std::condition_variable, einfache Warteschlangen in jedem RTOS für Mikrocontroller). Das Problem ist, dass es nicht möglich ist, dieses Timeout-Argument als letztes für die tryEmplaceFor () -Funktion zu verwenden, da bei variadischen Vorlagen "bekannte" Argumente an erster Stelle stehen müssen (*). Die zweite Version ist also "konsistent" - alle Funktionen mit Timeout haben das Timeout als erstes Argument. Diese Variante hat das offensichtliche Problem, wahrscheinlich das erste Beispiel für eine Zeitüberschreitung als erstes Argument für eine solche Funktionalität zu sein.

Welche Schnittstelle würde dem Betriebssystem besser dienen:

  • etablierter Standard für das Timeout als letztes Argument (mit Ausnahme von tryEmplaceFor()und tryEmplaceUntil()- wo muss es das erste Argument sein (*))?
  • Konsistenz - lieber das Timeout als erstes Argument?

(*) - Ich weiß, dass ich technisch gesehen das Timeout als letztes Argument für tryEmplaceFor()und haben könnte tryEmplaceUntil(), aber ich würde es lieber vermeiden, solche Vorlagenmagie für solch ein einfaches Szenario zu verwenden - all diese rekursiven Instanziierungen durchzuführen, nur um das letzte Argument zu erhalten, scheint ein bisschen übertrieben. besonders wenn ich mir die Fehler vorstelle, die der Compiler erzeugen würde, falls der Benutzer etwas falsch macht ...


Freddie Chopin
quelle
Was ist der Unterschied zwischen der ersten und der zweiten Version? Bitte markieren.
JBRWilkinson
1
Beobachtung: Nicht jeder kennt POSIX gut genug, um sich über die Platzierung der Zeit Gedanken zu machen, aber jeder, der Ihre Schnittstelle verwendet, wird von der inkonsistenten API frustriert sein. Ich stimme # 2.
J Trana

Antworten:

0

Wie aus einer (leider) gelöschten Antwort und Kommentaren hervorgeht, folgte ich der Zeile "Konsistenz" (zweite vorgestellte Variante) - in allen Funktionen "try ... For" und "try ... Until" gilt das Timeout (Dauer oder Zeitpunkt) ist das erste Argument.

Dies ist der Code in der aktuellen Phase - Link

Freddie Chopin
quelle