Forum: Mikrocontroller und Digitale Elektronik malloc und free für zrtos


von Matthias (ahamatta)


Lesenswert?

Ich versuche mich ja gerade an einem RTOS was nicht so einfach ist, wenn 
man bei vorherigen Projekten immer Gigabyteweise RAM zur Verfügung 
hatte. Ich lade nach und nach die Bausteine hoch...

Wäre schön, wenn einer Zeit und Lust hat vorab die malloc/free 
Implementation zu testen und Optimierungsvorschläge zu machen!

https://github.com/ykat-UG-haftungsbeschrankt/zrtos

: Verschoben durch Moderator
von Oliver S. (oliverso)


Lesenswert?

Lizenz:
„/*
 * Copyright (c) 2024 ykat UG (haftungsbeschraenkt) - All Rights 
Reserved
 *
 * Permission for non-commercial use is hereby granted,
 * free of charge, without warranty of any kind.
 */
„

Das teste mal schön selber…

Oliver

von Frank K. (fchk)


Lesenswert?

Aha. Da erfindet jemand das Rad also zum x-ten Mal.

fchk

von Harald K. (kirnbichler)


Lesenswert?

Das ist der hier:

Beitrag "ATmega328P Funktionsadresse in Register speichern und aufrufen"

Der Sinn von "Projekte und Code" scheint auch nicht so recht verstanden 
worden zu sein - die Aufforderung, irgendwelche Software zu testen, hat 
hier in diesem Forenbereich einfach überhaupt gar nichts verloren.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Matthias schrieb:
> Optimierungsvorschläge

Einfach mal andere Implementierungen anschauen. Andere Leute haben da 
schon mehr Geist rein gesteckt in sowas. ;-)

Bei einer Implementierung, die nur Chunks gleicher Größe recyceln kann, 
wirst du ratz-batz unter Speicherfragmentierung leiden. Du solltest also 
als Allermindestes freie Bereiche wieder zusammenfassen.

Shameless plug: eine kleine malloc-Implementierung habe ich vor Jahren 
der avr-libc beigesteuert, das war damals gewissermaßen mein Einstieg in 
diese Bibliothek. Ich weiß nicht, wie groß deine Zielplattform ist, aber 
das Teil steht unter BSD-Lizenz, wenn du eine 16-Bit-Plattform hast, 
könnte das nachnutzbar sein.

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Warum gehört malloc in ein RTOS? Ist das nicht eher Teil der C-Library? 
Das RTOS sollte von dynamischer Speicherverwaltung unabhängig sein. Die 
Anwendung kann selber entscheiden ob sie das braucht.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Niklas G. schrieb:
> Warum gehört malloc in ein RTOS?

Man könnte das zum Beispiel pro Task realisieren und limitieren wollen.

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Jörg W. schrieb:
> Niklas G. schrieb:
>> Warum gehört malloc in ein RTOS?
>
> Man könnte das zum Beispiel pro Task realisieren und limitieren wollen.

Würde man dann nicht eher sowas wie SBRK implementieren? Die Tasks 
fordern nur ganze Pages, oder nur einen großen kontinuierlichen 
Adressraum an. Jede Anwendung kann dann selber entscheiden ob sie malloc 
nutzt oder nicht. Unter POSIX ist malloc auch reine Anwendungssache, der 
Kernel weiß da nichts von.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Niklas G. schrieb:
> Die Tasks fordern nur ganze Pages

Wenn du über Pages redest, setzt du glaub ich schon zu viel voraus.

Typisch für ein RTOS ist schon, dass es Teile der Standardbibliothek 
realisiert.

Aber der TE schrieb nichts über die Plattform, auf der es laufen soll 
und wie groß diese ist (oder ich habe es auf Anhieb nicht gesehen).

von Arduino F. (Firma: Gast) (arduinof)


Lesenswert?

Beim überfliegen sind mir 2 Punkte aufgefallen, wo gegen das Prinzip der 
geringsten Verwunderung verstoßen wird.
Nicht, dass die Stellen unbedingt falsch wären, aber seltsam sind sie 
doch.

Die Erste:
> for(;usValue < 0x32;){
https://github.com/ykat-UG-haftungsbeschrankt/zrtos/blob/main/cpu/atmega328p.h#L177C2-L177C24
Da frage ich mich doch warum dort ein for zu finden ist....

Die Zweite:
> pxTopOfStackTmp[-5] = 0;
https://github.com/ykat-UG-haftungsbeschrankt/zrtos/blob/main/cpu/atmega328p.h#L188C2-L188C26
Ein richtiger LeseStopper für mich.
Ist mir doch ein negativer Index eher ein rotes Tuch.
Erst nach untersuchen der äquivalenten Schreibweisen zeigt sich, was es 
wirklich tut, bzw. tun soll.
1
pxTopOfStackTmp[-5] = 0; // so stehts im Code
2
-5[pxTopOfStackTmp] = 0; // gleichwertig, aber nicht hübscher
3
*(pxTopOfStackTmp-5) = 0; // das ist wohl gemeint und drückt es am klarsten aus


Danach habe ich aufgehört weiter zu lesen!
Mein Hunger nach Ostereier suchen ist gestillt.

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

PS: Unter Cortex-M geht das wie erwähnt alles viel geschmeidiger. Allein 
schon weil Adressberechnungen effizienter sind... Die Wahrscheinlichkeit 
dass jemand anders ein AVR-RTOS einsetzen will ist ziemlich gering. Bei 
Cortex-M ist es deutlich sinnvoller und wahrscheinlicher.

Wenn man wirklich eine Herausforderung haben möchte macht man das für 
Cortex-A, z.B. die TI Sitara. Die kann man Bare Metal programmieren. Da 
hat man dann auch eine MMU, virtuellen Speicher und Cache und Leistung 
ohne Ende. Und natürlich auch Multicore-Varianten. Ein Multicore-RTOS 
für Cortex-A, mit Speicherschutz zwischen den Tasks und pthreads-API, 
Secure Boot via TrustZone, vielleicht auch Virtualisierung - das wärs 
doch!

von Matthias (ahamatta)


Lesenswert?

Jörg W. schrieb:
> Matthias schrieb:
>> Optimierungsvorschläge
>
> Einfach mal andere Implementierungen anschauen. Andere Leute haben da
> schon mehr Geist rein gesteckt in sowas. ;-)
>
> Bei einer Implementierung, die nur Chunks gleicher Größe recyceln kann,
> wirst du ratz-batz unter Speicherfragmentierung leiden. Du solltest also
> als Allermindestes freie Bereiche wieder zusammenfassen.
>
> Shameless plug: eine kleine malloc-Implementierung habe ich vor Jahren
> der avr-libc beigesteuert, das war damals gewissermaßen mein Einstieg in
> diese Bibliothek. Ich weiß nicht, wie groß deine Zielplattform ist, aber
> das Teil steht unter BSD-Lizenz, wenn du eine 16-Bit-Plattform hast,
> könnte das nachnutzbar sein.

Das ist eigentlich für kleine Chips ohne MMU und sehr wenig RAM.

Es wird auch nicht mehr viel dazukommen.

Ich baue gerade noch bissl an der alternativen Speicherverwaltung für 
die Tasks, dann noch eine Funktion für einen manuellen Taskwechsel und 
dann ist das mehr oder weniger, wenn alle Bugs draußen sind, fertig.

Das malloc ist eigentlich nur dafür da, dass man es notfalls hat, falls 
man am Start irgendwas dynamisch erzeugen will.

Wenn man irgendwo Speicherblöcke gleicher Größe hat, kann man mit den 
gleichen Funktionen dafür einen eigenen Heap anlegen und beliebig oft 
ohne Speicherfragmentierung malloc und free aufrufen.

Speicherblöcke zusammenfassen ist ohne MMU und Paging praktisch 
unmöglich, das habe ich überhaupt nicht erst versucht.

von Arduino F. (Firma: Gast) (arduinof)


Lesenswert?

Matthias schrieb:
> Speicherblöcke zusammenfassen ist ohne MMU und Paging praktisch
> unmöglich, das habe ich überhaupt nicht erst versucht.

Ein System welches nicht in der Lage ist benachbarte Blöcke zusammen zu 
fassen  ist recht wertlos.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Matthias schrieb:
> Speicherblöcke zusammenfassen ist ohne MMU und Paging praktisch
> unmöglich, das habe ich überhaupt nicht erst versucht.

Sorry, das ist Unfug. Die AVR-Implementierung (die inzwischen schon 20 
Jahre alt sein dürfte) beweist das Gegenteil.

Arduino F. schrieb:
1
*(pxTopOfStackTmp-5) = 0; // das ist wohl gemeint und drückt es am klarsten aus

Da gehe ich allerdings nicht mit. Ein negativer Index ist da durchaus 
OK, allerdings würde ich den nicht als "magische Zahl" dahin schreiben, 
sondern einen Makro dafür nehmen. In dessen Definition steht dann, warum 
das so ist.

Dass man Verwaltungsinformationen vor dem eigentlichen Speicherblock 
ansiedelt, ist nicht ungewöhnlich. Wenn ich dann ein free() dafür 
bekomme, muss ich logischerweise von dieser Adresse zurück rechnen, also 
einen negativen Index anwenden.

von Matthias (ahamatta)


Lesenswert?

Also, funktionstechnisch fertig.

Optimierungen oder Codeänderungen wodurch der Compiler kleineren Code 
erzeugt, oder weniger RAM braucht, da geht natürlich sicher noch was...

von Vanye R. (vanye_rijan)


Lesenswert?

> Das ist eigentlich für kleine Chips ohne MMU und sehr wenig RAM.

Hauptsache du hast eine brilliante Strategie wenn dein Embedded
System beim malloc ein "kein Speicher mehr da" zurueckliefert
bekommt. Einfach booten oder "Wasser in Laufwerk A" Fenster
aufmachen geht ja schlecht.

Vanye

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Rote LED blinken lassen. :-)

von Matthias (ahamatta)


Lesenswert?

Ich suche noch nach der C++ exception... Hoffe der watchdog startet dann 
einfach neu. ;)

von Steve van de Grens (roehrmond)


Lesenswert?

Jörg W. schrieb:
> Aber der TE schrieb nichts über die Plattform, auf der es laufen soll
> und wie groß diese ist

Hat er in seinem anderen Thread geschrieben. Es geht um einen ATmega328 
(nicht lachen). Mal abgesehen vom RTOS, warum er nun auch noch 
malloc/free neu erfinden will, anstatt deine Standard-Funktionen zu 
verwenden, ist mir ein Rätsel.

: Bearbeitet durch User
von Marci W. (marci_w)


Lesenswert?

Steve van de Grens schrieb:
> warum er nun auch noch
> malloc/free neu erfinden will, anstatt deine Standard-Funktionen zu
> verwenden, ist mir ein Rätsel.

möchte für sein Programm womöglich ne andere Lizenz verwenden.

ciao

Marci

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Marci W. schrieb:
> möchte für sein Programm womöglich ne andere Lizenz verwenden.

'ne andere als 3-Clause BSD?

Sehe ich wenig Sinn drin. Aber ja, kann man machen, wenn man eine gut 
debuggte Version durch neue eigene Bugs ersetzen möchte. ;-)

von Michael B. (laberkopp)


Lesenswert?

Niklas G. schrieb:
> Warum gehört malloc in ein RTOS? I

Siehe GlobalAlloc von Windows.

Matthias schrieb:
> und Optimierungsvorschläge zu machen!

Du verwaltest eine lineare Liste. Da darf man nicht viele malloc/free 
machen bis das langsam wird.vWie wäre es mit einem nach Blockllänge 
sortierten B-baum ? Ich weiss, kostet einen pointer mehr im chunk.

Zudem redest du von RTOS, da würde ich Mutexe beim Zugriff auf die 
Speicherverwaltung erwarten. Obwohl ich nicht weiss, was das jeweilige 
this addressiert. Aber ein this pro task fände ich nutzlos.

Beim free nicht nebenstehende leere Blöcke zu verschmelzen und nur genau 
passende Chunks wiederzuverwenden klingt auch nicht optimal.

Dein free-bit im length feld unterzubringen macht den code nicht 
lesbarer. Blöcke sollten wenigstens Vielfache der chunk-Grösse lang sein



.

: Bearbeitet durch User
von Klaus (feelfree)


Lesenswert?

Matthias schrieb:
>  die malloc/free Implementation

Mir stellt sich nur eine Frage: warum? Sind dir frei verfügbare 
Implementierungen nicht schlecht genug?

von Peter (pittyj)


Lesenswert?

Im Original K&R von 1978 ist doch schon ein Beispiel dafür vorhanden.
Dann nimm das doch, das ist seit über 40 Jahren bekannt, und getestet.

Oder mußte einfach das Rad neu erfunden werden?

von Matthias (ahamatta)


Lesenswert?

Das ist eigentlich für die Tasks, kann aber auch eine normale 
Speicheranforderung.

https://github.com/ykat-UG-haftungsbeschrankt/zrtos/blob/main/examples/mem.h

Mikrocontrollerprogrammierung ist ja eher so ein Schüler Ding?

Es ist ja kein riesen Schinken und ich bin am überlegen, ob man nicht 
nach Fertigstellung der RC zur Taschengeldlaufbesserung für jeden 
Änderungsvorschlag der zur Verkleinerung des Compilats führt eine kleine 
Belohnung auszahlt? So 5-10 Euro vllt.?

Würde sich denn da jemand finden, oder haben die alle ihr Taschengeld in 
Bitcoin angelegt und jetten um die Welt? ;)

: Bearbeitet durch User
von Matthias (ahamatta)


Lesenswert?

Sinnvoll wäre es wahrscheinlich, da es ja immer schwieriger wird, wenn 
man mit einem kleinen Betrag anfängt und das nach jeder Änderung (nicht 
Assembler, nur das was in C ist) anhebt?

von Harald K. (kirnbichler)


Lesenswert?

Matthias schrieb:
> Mikrocontrollerprogrammierung ist ja eher so ein Schüler Ding?

Bereitet so viel Unfug nicht eigentlich irgendwie Schmerzen?

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Matthias schrieb:
> Mikrocontrollerprogrammierung ist ja eher so ein Schüler Ding?

Womit arbeiten denn Profis?

von Michael B. (laberkopp)


Lesenswert?

Niklas G. schrieb:
> Womit arbeiten denn Profis?

Heute Quantencomputer oder Serverfarmen für KI Anwendungen.

von J. S. (jojos)


Lesenswert?

Matthias schrieb im Beitrag
> Wäre schön, wenn einer Zeit und Lust hat vorab die malloc/free
> Implementation zu testen und Optimierungsvorschläge zu machen!

Gerade in diesem Fall sind automatische Tests sinnvoll, mit 
verschiedenen Fällen von kleinen/großen/gemischten Blöcken.

von Matthias (ahamatta)


Lesenswert?

Denke ich mir schon, dass es noch recht buggy ist.

Versuche heute mal die Integration von zrtos_mem.h in zrtos_task.h, ohne 
alles umzuschreiben.

von Matthias (ahamatta)


Lesenswert?

Harald K. schrieb:
> Matthias schrieb:
>> Mikrocontrollerprogrammierung ist ja eher so ein Schüler Ding?
>
> Bereitet so viel Unfug nicht eigentlich irgendwie Schmerzen?

So war das nicht gemeint. Klar gibt es Profis, die das hauptberuflich 
auf höchstem Niveau machen und sich überlegen wie man den Chips im All 
noch eine Zusatzfunktion verpassen kann.

Diese Zielgruppe wird sich aber wahrscheinlich kaum damit 
beschäftigen...

Aber in der FH, wenn man da einen Kurs macht, bekommt man doch als 
erstes so ein Teil und lässt eine LED blinken oder dimmen.

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.