Forum: Mikrocontroller und Digitale Elektronik Wie semi-komplexe Firmware in FreeRTOS-Tasks aufteilen?


von Sascha (Gast)


Lesenswert?

Hi,

ich bin gerade zum Ersten mal dabei eine etwas "komplexere" Firmware mit 
FreeRTOS zu bauen. Meine Komponenten sind in C++ Objektorientiert und 
haben die folgende Struktur:
1
*Websocket*
2
/\ send()
3
| 
4
| 
5
| 
6
\/ receive()
7
*JSONProtocolHandler*
8
/\ sendPayload()
9
| 
10
|
11
| 
12
\/ handlePayload()
13
*ApplicationSpecific*
14
/\ sendData()
15
| 
16
|
17
| 
18
\/ handleCommand()
19
*MainClass*  <-------- *Sensor*
20
|
21
|
22
| 
23
\/changeOutput()
24
*Output*

Etwas zur Erklärung: Der Controller hat eine Websocket-Verbindung und 
JSONProtocolHandler baut auf dieser Verbindung ein JSON-Protocol auf. 
Einige protokollspezifische Nachrichten werden dort direkt verarbeitet, 
andere dagegen über MainClass bspw. an den Output weitergeleitet. 
Außerdem sendet Sensor ebenfalls über MainClass und ApplicationSpecific 
Daten über den Websocket.

Output und Sensor habe ich bereits als Task implementiert. Worüber ich 
mir derzeit aber am meisten den Kopf zerbreche ist, wie ich den Pfad zum 
Websocket am Besten in Tasks aufteile.

Macht es Sinn tatsächlich jede Komponente als eigenen Task anzusehen?

Danke und Grüße

von PittyJ (Gast)


Lesenswert?

Ich würde alles mit nur einem Task machen. Wo wäre der Vorteil bei 
mehreren?

von moep (Gast)


Lesenswert?

Eine Task brauchst du dann wenn du etwas zu entkoppeln hast.
Das ist vor allem dann der Fall wenn deine Komponente "längere" Zeit 
blockiert. Dies kann z.B. bei der Verwendung von Sockets oder sonstigen 
IO-Zugriffen passieren.
Alles was nur Standard-Funktionalität enthält die beim Aufruf einfach 
durchläuft braucht erstmal keine eigene Task sein.

Den JSON-Handler in einer Task laufen zu lassen bringt dir keine 
Vorteile. Der braucht eben so lange wie er braucht.

Ich würde die ganze Kommunikation (WS, JSON, ApplicationSpecific) in 
eine Comm-Task packen.

von fghghjr56zrthftrrrzrtrtzrtzrtzrtzrtzrtzr (Gast)


Lesenswert?

ich habe sowas ähnliches.

ein Task macht den websocket + TLS + empfang und weiterleiten der 
payload an einen anderen Task


der andere Task bearbeitet die payload durch und schickt die antwort.
( und macht noch zuig andere applikationspezifische sachen)
wichtig bei solchem zeug ist das das senden am besten nur durch einen 
Task erfolgt.

von Sascha (Gast)


Lesenswert?

PittyJ schrieb:
> Ich würde alles mit nur einem Task machen. Wo wäre der Vorteil bei
> mehreren?

Ich arbeite auf einem Dualcore ESP32. Da derzeit ab und zu einige 
Latenzen auftreten, erhoffe ich mir durch eine Aufteilung der Arbeit auf 
beide Cores eine bessere Performance.

Ich verwende ESP-IDF als Plattform, die Websocket API davon (die ich in 
der Websocket-Klasse verwende) erzeugt intern einen eigenen Task. Wenn 
nun Daten eintreffen, führt dieser Task u.U. den gesamten Code bis zum 
Output aus. In dieser Zeit kann der Task dann natürlich keine weiteren 
Events bearbeiten. Eine ähnliche Situation habe ich dann auch mit 
Bluetooth LE Sensoren, deren Events im Bluetooth Task dann Websocket 
Funktionen ausführen. Klingt für mich irgendwie nicht "richtig".

Da die Kommunikation auf drei Klassen verteilt ist, scheint es auch 
erstmal schwierig, genau diese in einen Task zu packen.

Meine Ideen wären daher:

- Die Websocket-Klasse als einen Task definieren und alle Events von der 
IDF websocket API bzw. alle send() Aufrufe der Applikation zur API in 
eine Queue einzureihen.

Oder

- In MainClass einen Task verwalten, der alle Events von Sensoren und 
Anforderungen an Output durch eine Queue von der Kommunikation zu 
entkoppeln. Nachteil wäre hier jedoch, dass der interne Websocket Task 
immer noch Applikationsspezifisches Protokol Handling ausführen muss.

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.