Wie semi-komplexe Firmware in FreeRTOS-Tasks aufteilen?

Gast #6184373
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
Gast #6184466
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.
Gast #6184467
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.
Gast #6190602
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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren