Hallo, wie würdet ihr folgende Aufgabe mit C++ umsetzen? Kurze vereinfachte Einführung: Habe zwei freeRTOS Prozesse. Im einen freeRTOS Prozess (DatenErfassen) sollen Daten, welche über eine Schnittstelle hereinkommen, erfasst werden. Im anderen freeRTOS Prozess (DatenSpeichern) sollen diese Daten auf eine SD Karte abgespeichert werden. Es geht mir um die Betrachtung der Daten. *Sollte ich eine Klasse "CDaten" erstellen mit statischen Variablen. Somit könnten beliebige Objekte in diesen beiden Prozessen auf diese statischen "CDaten" Variablen zugreifen. *Sollte ich im Prozess (DatenErfassen), noch vor dem endlosloop for{;;} eine Instanz "oCDaten" einer "CDaten" Klasse mit nun nicht statischen Variablen erstellen und wenn Daten geschrieben werden sollen, der Queue zum Prozess (DatenSpeichern) den Zeiger auf "oCDaten" übergeben? Über diesen Zeiger kann dann aus dem Anderen Prozess auf "oCDaten" zugegriffen werden. *Sollte ich noch vor dem Starten der beiden Prozesse (DatenErfassen) und (DatenSpeichern) eine Instanz "oCDaten" einer "CDaten" Klasse mit nicht statischen Variablen erstellen und den Instanzen "DatenErfassen" und "DatenSpeichern" über ihren Konstruktor einen Zeiger auf das Objekt "oCDaten" übergeben? Über diesen Zeiger kann ebenso auf "oCDaten" zugegriffen werden. Für mich sind alle hier genanten Ansätze lauffähig, doch welches ist der übliche Ansatz? Gibt es andere? Die Aufteilung auf die Beiden Prozesse ist aber gesetzt.
fred schrieb: > Es geht mir um die Betrachtung der Daten. > > *Sollte ich eine Klasse "CDaten" erstellen mit statischen Variablen. C wie "Chnittstelle"? Oder was soll das C bedeuten? > Somit könnten beliebige Objekte in diesen beiden Prozessen auf diese > statischen "CDaten" Variablen zugreifen. Wozu sind sie dann in einer Klasse? > *Sollte ich im Prozess (DatenErfassen), noch vor dem endlosloop for{;;} > eine Instanz "oCDaten o? Für "orfasst"? ;-) > einer "CDaten" Klasse mit nun nicht statischen > Variablen erstellen und wenn Daten geschrieben werden sollen, der Queue > zum Prozess (DatenSpeichern) den Zeiger auf "oCDaten" übergeben? > Über diesen Zeiger kann dann aus dem Anderen Prozess auf "oCDaten" > zugegriffen werden. Wozu dient dann die Queue? Würde da nicht jedesmal ein Zeiger auf das selbe Objekt übergeben werden? > *Sollte ich noch vor dem Starten der beiden Prozesse (DatenErfassen) und > (DatenSpeichern) eine Instanz "oCDaten" einer "CDaten" Klasse mit > nicht statischen Variablen erstellen und den Instanzen "DatenErfassen" > und > "DatenSpeichern" über ihren Konstruktor einen Zeiger auf das Objekt > "oCDaten" übergeben? Über diesen Zeiger kann ebenso auf "oCDaten" > zugegriffen werden. Du brauchst dann aber auch noch eine Synchronisation. > Für mich sind alle hier genanten Ansätze lauffähig, doch welches ist der > übliche Ansatz? Gibt es andere? Die Aufteilung auf die Beiden Prozesse > ist aber gesetzt. Wozu überhaupt diese "CDaten"-Klasse? Mache eine Klasse oder Struct, die ein einzelnes Datum enthält (sofern das wiederum aus mehreren Werten besteht) und stecke das einfach in die Queue. Der Empfänger nimmt das dann entgegen. Du könntest deine "CDaten" auch um die Queue herum bauen, also so dass die Queue Teil dieser Klasse ist, und dann greifen deine beiden Tasks immer auf diese Klasse zu, und die kümmert sich im Hintergrund darum, die Daten über die Queue zu schicken.
Es wird eine Klasse FiFo benötigt. Eine Task schreibt und die andere liest. Ob die Daten selber eine Klasse sein müssen, hängt davon ab, ob sie nur Werte enthalten, oder auch damit arbeiten: Konvertierung, Runden, Linearisierung, ...
einfach Klasse schrieb: > Es wird eine Klasse FiFo benötigt. Hat der OP schon. Allerdings hat er das Ding Queue genannt.
Gehört seine Queue nicht zum Objekt DatenSchreiben? Fragt er nicht nach der Datenverwaltung, Zeiger, Werte, ...? Die FiFo Klasse hat die Methoden Add und Get und kümmert sich selber um die Speicherung und Freigabe. Die Thematik kann losgelöst von den anderen Themen betrachtet werden und auf das Target zugeschnitten werden. Die Aufteilung der Problematik in kleine eigenständige Häppchen ist doch ein Grundsatz der OOP!
Torsten R. schrieb: > einfach Klasse schrieb: >> Es wird eine Klasse FiFo benötigt. > > Hat der OP schon. Allerdings hat er das Ding Queue genannt. Nein, er hat eine FreeRTOS-Queue. http://www.freertos.org/a00018.html einfach Klasse schrieb: > Gehört seine Queue nicht zum Objekt DatenSchreiben? Soweit ich das verstanden habe, hat die keine Zugehörigkeit. > Die FiFo Klasse hat die Methoden Add und Get und kümmert sich selber um > die Speicherung und Freigabe. Die Thematik kann losgelöst von den > anderen Themen betrachtet werden und auf das Target zugeschnitten > werden. Das war im wesentlichen mein Vorschlag, um die Queue herum eine Klasse zu schreiben, die sich um alles kümmert, was für die Übertragung durch die Queue nötig ist.
Rolf M. schrieb: > Das war im wesentlichen mein Vorschlag, um die Queue herum eine Klasse > zu schreiben, die sich um alles kümmert, was für die Übertragung durch > die Queue nötig ist. Und warum schreibst du das dann nicht einfach? ;-)
Rolf M. schrieb: > Torsten R. schrieb: >> Hat der OP schon. Allerdings hat er das Ding Queue genannt. > > Nein, er hat eine FreeRTOS-Queue. Äh, und was soll diese Spitzfindingkeit jetzt? Ist doch egal, ob das Ding nun Queue oder FreeRTOS-Queue heißt! Egal ob das nun C oder C++ ist. Das Ding ist eine Queue, bleibt eine Queue und sollte man deswegen auch Queue nennen. Auf der einen Seite steckst Du was rein, auf der anderen Seite, kann der Task sich da die Daten raus holen und drauf blocken, wenn keine Daten da sind. -> Nennt man Queue. Was um alles in der Welt wollt Ihr jetzt noch darum stricken? Messdaten fallen an, werden auf die Queue geworfen, werden Empfangen und dann auf die SSD-Karte geschrieben. <- Punkt
Ich würde das ganze so strukturieren. Eine Klasse, die sich um die Queue kümmert und mir einfache Zugriffsmethoden für meine Daten bietet. Diese Klasse verwendet dann intern z.B. die FreeRTOS queue. Damit ließe sich z.B. auch die Typsicherheit nach außen garantieren, wenn die FreeRTOS queue nur void* unterstützt. Das ganze gecaste wäre dann in dieser Klasse gekapselt. Wenn meine Daten eine Struktur sind, dann würde ich eine eigene Datenklasse schreiben und diese dann durch die Queue senden. Beim aufsetzen vor dem main loop würde ich dann eine Instanz meiner Queue anlegen und jeweils eine Referenz an DatenErfassen und DatenSpeichern übergeben. Zu deinen Vorschlägen noch folgende Anmerkungen: > *Sollte ich eine Klasse "CDaten" erstellen mit statischen Variablen. > Somit könnten beliebige Objekte in diesen beiden Prozessen auf diese > statischen "CDaten" Variablen zugreifen. Würde ich nicht machen. Stell die vor du hast einen zweiten DatenErfassen Prozess mit einer eigenen Queue, dann hast du mit den statischen Variablen schon ein Problem. > *Sollte ich im Prozess (DatenErfassen), noch vor dem endlosloop for{;;} > eine Instanz "oCDaten" einer "CDaten" Klasse mit nun nicht statischen > Variablen erstellen und wenn Daten geschrieben werden sollen, der Queue > zum Prozess (DatenSpeichern) den Zeiger auf "oCDaten" übergeben? > Über diesen Zeiger kann dann aus dem Anderen Prozess auf "oCDaten" > zugegriffen werden. Wäre eine Lösung, ich würde aber trotzdem die nächste benutzen. > *Sollte ich noch vor dem Starten der beiden Prozesse (DatenErfassen) und > (DatenSpeichern) eine Instanz "oCDaten" einer "CDaten" Klasse mit > nicht statischen Variablen erstellen und den Instanzen "DatenErfassen" > und > "DatenSpeichern" über ihren Konstruktor einen Zeiger auf das Objekt > "oCDaten" übergeben? Über diesen Zeiger kann ebenso auf "oCDaten" > zugegriffen werden. Das wäre meine Lösung. Wenn es mir um Flexibilität für die Zunkunft ginge würde ich sogar noch weiter gehen. Ich erstelle zwei Interfaceklassen.
1 | class IPutData |
2 | {
|
3 | public:
|
4 | void Put(Data* pData) = 0; |
5 | };
|
6 | class IGetData |
7 | {
|
8 | public:
|
9 | Data* Get() = 0; |
10 | };
|
Die Queue implementiert nun beide Interfaces.
1 | class CQueue : public IPutData, public IGetData |
2 | {
|
3 | ...
|
4 | };
|
In main lege ich dann eine Klasse von CQueue an, übergebe aber an die beiden Prozesse nur jeweils eine Referenz vom Typ IPutData bzw. IGetData. Damit kann ich meine Queueklasse einfach durch eine andere austauschen, die die entsprechenden Interfaces implementiert.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.