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
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
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.
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.
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.
Niklas G. schrieb: > Warum gehört malloc in ein RTOS? Man könnte das zum Beispiel pro Task realisieren und limitieren wollen.
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.
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).
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.
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!
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.
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.
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.
Also, funktionstechnisch fertig. Optimierungen oder Codeänderungen wodurch der Compiler kleineren Code erzeugt, oder weniger RAM braucht, da geht natürlich sicher noch was...
> 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
Ich suche noch nach der C++ exception... Hoffe der watchdog startet dann einfach neu. ;)
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
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
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. ;-)
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
Matthias schrieb: > die malloc/free Implementation Mir stellt sich nur eine Frage: warum? Sind dir frei verfügbare Implementierungen nicht schlecht genug?
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?
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
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?
Matthias schrieb: > Mikrocontrollerprogrammierung ist ja eher so ein Schüler Ding? Bereitet so viel Unfug nicht eigentlich irgendwie Schmerzen?
Matthias schrieb: > Mikrocontrollerprogrammierung ist ja eher so ein Schüler Ding? Womit arbeiten denn Profis?
Niklas G. schrieb: > Womit arbeiten denn Profis? Heute Quantencomputer oder Serverfarmen für KI Anwendungen.
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.
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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.