FreeRTOS Shared Memory

Gast #6742893
Lesenswert?

Hi,
ich würde gerne bei FreeRTOS einen Shared Memory einrichten, um Daten 
mehreren Tasks zur Verfügung zu stellen. 
https://www.keil.com/pack/doc/CMSIS/RTOS2/html/group__CMSIS__RTOS__PoolMgmt.html#details
Leider finde ich nirgends eine Doku oder ein passendes Beispiel wie das 
genau funktioniert.
So von meinen Überlegungen könnte ich mir das in etwa so vorstellen, 
dass ich eine globale Funktion schreibe, die allen Tasks zugänglich ist 
und welche mithilfe von Mutexes oder Semaphoren  den gleichzeitigen 
Zugriff auf den Speicher verhindert.

Allerdings verstehe ich schon das Beispiel in der Dokumentation nicht:
1
pMem = (MEM_BLOCK_t *)osMemoryPoolAlloc(mpid_MemPool, 0U);  // get Mem Block
2
    if (pMem != NULL) {                                         // Mem Block was available
3
      pMem->Buf[0] = 0x55U;                                     // do some work...
4
      pMem->Idx    = 0U;
5
 
6
      status = osMemoryPoolFree(mpid_MemPool, pMem);            // free mem block
Wieso wird der Memory Block gleich wieder freigegeben? Wie kann ich den 
Später wieder genau auf diesem Zugreifen?

Mehr Doku oder Beispiele wären schön! Danke euch!
#6742971
Lesenswert?

Mark schrieb:
> Wieso wird der Memory Block gleich wieder freigegeben?

Zwischen Allokieren und Freigeben steht doch im Kommentar "do some 
work".
Ist halt nur eine Demo, wie man es machen kann/soll.

In einem realen Beispiel wird da sicher mehr gemacht, aber nach Ende 
wohl auch wieder freigegeben, wenn man den Speicher nicht mehr braucht.

Nach dem Freigeben wird natürlich nicht drauf zugegriffen.
Gast #6742994
Lesenswert?

Ok, ist dann folgender schematischer Ansatz richtig? Ich habe 4 Tasks.
Task 1: Liest Sensorwerte vom ADC
Task 2: Statemaschine welche anhand dieser Werte den Status ändert
Task 3: Sendet die Werte über den UART zur weiteren Verwendung
Task 4: Zeigt die Werte auf einem Display

Ich dachte, es ist sinnvoll die Werte in einen Shared Memory zu 
schreiben und die 3 Tasks holen sie sich ab wen sie diese benötigen.

Ich schreibe eine globale Zugriffsfunktion zum Schreiben und Lesen auf 
diesen Memory in etwa so:

Schreiben:
- Memory Allokieren und Handler generieren. Der Handler ist nur in der 
Funktion bekannt.
- Mutex setzten
- Werte schreiben
- Mutex löschen

Lesen:
- Mutex setzen
- Werte lesen mit Handler.... Wie übergebe ich der Funktion den Handler 
am besten?
-Mutex löschen

Zur Laufzeit wird der Speicher nie mehr freigegeben. Ist das gut so?

Danke euch!
Gast #6743155
Lesenswert?

Der MemoryPool ist auch eher eine Speicherverwaltung wie malloc, dafür 
threadsafe und bei gleich großen Blöcken kann man Speicherzerstückelung 
vermeiden.
Um Werte von einem Thread in einen anderen zu schicken bieten sich 
Queues an. Durch die Q kommen dann alle Werte sicher an solange die Q 
nicht überläuft. Für ein GUI ist das nicht unbedingt nötig, da reicht 
oft ein asynchrones reingreifen in die aktuellen Werte (atomare 
Datentypen vorrausgesetzt). Änderungen kann man da auch durch Eventflags 
signalisieren. Das sind einfache Flags an denen ein Thread warten kann 
und man spart sich ein polling. Bringt natürlich nur was wenn sich die 
Werte selten ändern.
#6743384
Lesenswert?

Shared memory wird memory gemannt, welche zwischen mehreren Programmen 
geshart wird. Was du meinst ist in einem Programm - eine globale 
Variable, welche mit einem Semaphore geschuetzt wird. Das ist viel 
einfacher im Sinne, dass du nur eine Semaphore benoetigst und mit dir 
selbst ausmachen musst, wozu die gut ist. Indem die Variable zB nur per 
access procedure verwendet wird.
Gast #6744038
Lesenswert?

Daten tauscht man zwischen Tasks mit Queues aus.
Ein Task füllt die Queue, ein anderer bedient sich aus der Queue bei den 
ankommenden Daten. Die Queue ist FIFO, RTOS kümmert sich um die 
Kommunikation.
Natürlich kann man um das RTOS Konzept herumprogrammieren, in dem man 
Semaphoren und globale Variablen verwendet, aber jeder kann schliesslich 
so proggen wie er es für richtig hält.
Gast #6744458
Lesenswert?

Mucky F. schrieb:
> Wozu dann shared memory?

Wohin zeigt der Pointer denn sonst?

Aber wenn das Zielsystem keine MMU/MPU hat und Du nicht FreeRTOS-MPU 
benutzt, ist aller Speicher aus Sicht der Tasks shared. Da gibt es keine 
Prozessisolation wie z. B. bei Linux auf Architekturen mit MMU, wo man 
shared memory explizit mit mmap() oder shmget() anfordert und dann über 
Prozessgrenzen hinweg benutzen kann.
#6744524
Lesenswert?

ergo70 schrieb:
> Mucky F. schrieb:
>> Wozu dann shared memory?
>
> Wohin zeigt der Pointer denn sonst?

Einfach auf Speicher.

> Aber wenn das Zielsystem keine MMU/MPU hat und Du nicht FreeRTOS-MPU
> benutzt, ist aller Speicher aus Sicht der Tasks shared.

Da muss nix geshared werden, weil die sowieso alle auf den gesamten 
Speicher zugreifen können.

> Da gibt es keine Prozessisolation wie z. B. bei Linux auf Architekturen
> mit MMU, wo man shared memory explizit mit mmap() oder shmget() anfordert
> und dann über Prozessgrenzen hinweg benutzen kann.

Eben, deshalb gibt es da keinen "shared memory", sondern einfach nur den 
"memory".
Gast #6744698
Lesenswert?

>> Natürlich kann man um das RTOS Konzept herumprogrammieren, in dem man
>> Semaphoren und globale Variablen verwendet,
>Semaphoren sind Teil des RTOS-Konzepts.

um Signale zwischen Tasks auszutauschen, nicht Daten
z.B., Achtung, Task01 verwendet den einigen I2C Bus, alle anderen Tasks 
Finger weg von I2C
Gast #6744711
Lesenswert?

besseres Beispiel:
Daten von Task1 an Task2 über eine Queue schicken,
Task gibt eine Semaphore frei um Task2 zu signalisieren das neue Daten 
verfügbar sind. Task2 nimmt die Semaphore um zu signalisieren, das die 
Daten geholt + bearbeitet werden (es passt z.B. nur eine definierte 
Menge Daten in die Queue). Nach Abarbeitung gibt Task2 die Semaphore 
wieder frei um Task1 zu signalisieren das neue Daten entgegengenommen 
werden könnten.

Vorteil:
Task2 konsumiert keine Rechenzeit so lange es nichts zu tun gibt.
Task1 konsumiert keine Rechenzeit so lange Task2 am Arbeiten ist.
Gast #6744720
Lesenswert?

In dem Fall ist eine Semaphore unnötig, weil ein Task auch wartend auf 
Daten in der Q blockieren kann. Sowohl beim put als auch beim get.
Aber auch ein Speicherbereich ist eine Resource die man per Semphore 
schützen kann wenn ein Block konsistent sein soll, also z.B. eine 
Struktur enthält die ja in mehreren Schritten gelesen/geschrieben wird.
#6744729
Lesenswert?

drm schrieb:
>>> Natürlich kann man um das RTOS Konzept herumprogrammieren, in dem man
>>> Semaphoren und globale Variablen verwendet,
>>Semaphoren sind Teil des RTOS-Konzepts.
>
> um Signale zwischen Tasks auszutauschen, nicht Daten

Sie dienen zur Synchronisation, unter anderem von Zugriffen auf 
Ressourcen wie z.B. Speicher.

> z.B., Achtung, Task01 verwendet den einigen I2C Bus, alle anderen Tasks
> Finger weg von I2C

Oder: Achtung, Task01 verwendet die Variable X, alle anderen Tasks 
Finger weg von X.

Johannes S. schrieb:
> In dem Fall ist eine Semaphore unnötig, weil ein Task auch wartend auf
> Daten in der Q blockieren kann.

Kommt auf das Framework an. Aber ja, das gibt es. In dem Fall ist die 
Semaphore eben schon in der Queue eingebaut.
Gast #6744815
Lesenswert?

ergo70 schrieb:
> Mucky F. schrieb:
>> Wozu dann shared memory?
>
> Wohin zeigt der Pointer denn sonst?

Eben, was will der TE mit shared memory wenn das RTOS n besseres Konzept 
hat?

> Aber wenn das Zielsystem keine MMU/MPU hat und Du nicht FreeRTOS-MPU
> benutzt, ist aller Speicher aus Sicht der Tasks shared.

s.o. aber wenn er schon RTOS nutzt muss er sich nicht drum kümmern.

drm schrieb:
> Task gibt eine Semaphore frei um Task2 zu signalisieren das neue Daten
> verfügbar sind. Task2 nimmt die Semaphore

Das die Unterprogramme sich irgenwie einigen müssen wer was wann damit 
macht finde ich irgenwie selbstverständlich.

Warum da so ein unübersichtliches Semaphorengebastel sein muss verstehe 
ich aber eher weiniger. Da enstehen lokale interdependenzen die schwer 
zu tracken sind, zuminmest für mich.  Das kann man imo mit ner zentralen 
Statusvariable und enum einfacher lösen.
Gast #6744832
Lesenswert?

Was anderes habe ich doch auch nicht geschrieben. Da es keinen 
speziellen Speicherschutz gibt, ist aller Speicher geteilter Speicher. 
Und die Frage wohin der Pointer zeigt, sollte eigentlich nur darauf 
hinweisen, dass er auf Speicher zeigen sollte der auch allokiert ist.
#6744955
Lesenswert?

drm schrieb:
> Herausgeber ‏ : ‎ Packt Publishing (15. Mai 2020)
> Sprache ‏ : ‎ Englisch
> Taschenbuch ‏ : ‎ 496 Seiten
> ISBN-10 ‏ : ‎ 1838826734
> ISBN-13 ‏ : ‎ 978-1838826734
>
> igitt, nur englisch

;-)

Also das lässt sich nach einer durchgezechten Nacht noch locker so im 
Halbschlaf lesen. Sind sogar noch schöne Bildchen drin...
Kann ich echt empfehlen.

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