Forum: PC-Programmierung C++ Zugriff auf ein Datenobjekt


von fred (Gast)


Lesenswert?

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.

von Rolf M. (rmagnus)


Lesenswert?

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.

von einfach Klasse (Gast)


Lesenswert?

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

von Torsten R. (Firma: Torrox.de) (torstenrobitzki)


Lesenswert?

einfach Klasse schrieb:
> Es wird eine Klasse FiFo benötigt.

Hat der OP schon. Allerdings hat er das Ding Queue genannt.

von einfach Klasse (Gast)


Lesenswert?

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!

von Rolf M. (rmagnus)


Lesenswert?

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.

von einfach Klasse (Gast)


Lesenswert?

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? ;-)

von Torsten R. (Firma: Torrox.de) (torstenrobitzki)


Lesenswert?

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

von M.K. B. (mkbit)


Lesenswert?

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
Noch kein Account? Hier anmelden.