Wie kann ich einen PIC verwenden malloc()
und free()
funktionieren? Ich habe den stdlib.h
Header überprüft und es werden sie nicht erwähnt. Ich benutze MCC18.
Musste jemand sie benutzen?
Ich brauche sie, weil ich eine Bibliothek von Windows XP auf den PIC portiere. Die Portierungsanleitung sagt zu
Passen Sie die spezifischen Funktionen des Betriebssystems an meine PIC-Funktionen an
Aber ich weiß nicht, wie ich die malloc()
und free()
Funktionen "übersetzen" soll .
Antworten:
In vielen Anwendungen muss Speicher zugewiesen werden, es muss jedoch nichts freigegeben werden, während etwas beibehalten wird, das danach zugewiesen wurde. Auf einem solchen System muss lediglich der Linker verwendet werden, um ein Array mit dem gesamten verfügbaren RAM zu definieren, einen Zeiger auf den Anfang dieses Arrays zu setzen und dann eine nette einfache Malloc-Funktion zu verwenden:
Schön und einfach, und nur zwei Bytes Gesamtaufwand für eine beliebige Anzahl von Zuordnungen. Wenn Sie free () für einen Block aufrufen, wird die Zuordnung dieses Blocks und aller darauf folgenden Elemente aufgehoben.
Etwas kompliziertere Zuordnungsmuster können mithilfe von zwei Zeigern behandelt werden - einer, der Daten von der Unterseite des Speichers nach oben und eine von der Oberseite des Speichers nach unten zuordnet. Es ist auch möglich, einen komprimierenden Garbage Collector zu verwenden, wenn die Daten im Heap homogen sind und man weiß, wo sich alle externen Verweise darauf befinden.
quelle
malloc()
in Mikrocontrollern wird allgemein als "schlechte Sache" angesehen. Wenn Sie es jedoch unbedingt benötigen, sollten Sie eine Version eines Drittanbieters suchen.Wenn Sie Glück haben, hängt der zu portierende Code möglicherweise nicht von der Wiederverwendung von Speicherblöcken ab. In diesem Fall können Sie einen einfachen Allokator schreiben, der einen Zeiger in einen RAM-Puffer zurückgibt und den Zeiger dann um die angeforderte Blockgröße vorschiebt.
Ich habe diesen Ansatz bereits erfolgreich beim Portieren von PC-Bibliotheken auf Mikrocontroller verwendet.
Im Folgenden würden Sie den Allokator mit einrichten
my_malloc_init()
und Speicher mit zuweisenmy_malloc()
.my_free()
ist da, um die Abhängigkeit zu befriedigen, wird aber eigentlich nichts tun. Irgendwann wird Ihnen natürlich der Platz ausgehen.Damit dies funktioniert, müssen Sie den Speicherbedarf Ihres Codes im ungünstigsten Fall messen (dies möglichst auf einem PC tun) und dann entsprechend einrichten
HEAP_SIZE
. Rufen Sie an, bevor Sie den Teil Ihrer Bibliothek betreten, der dynamischen Speicher benötigtmy_malloc_init()
. Stellen Sie vor der Wiederverwendung sicher, dass noch nichts darauf zeigtheap
.(Hinweis: In der realen Welt müssen Sie möglicherweise die Zeigerausrichtung berücksichtigen, dh das Aufrunden
heap_ptr
um 2 oder 4 Byte.)Eine andere Möglichkeit besteht darin, eine einfachere Zuordnungsstruktur als
malloc()
gewöhnlich zu verwenden, wie z. B. eine FreeList . Auf diese Weise können Sie jedoch möglicherweise keine Blöcke mit variabler Größe zuweisen.quelle
Dies ist kaum eine Antwort auf Ihre Frage, aber die dynamische Speicherzuweisung wird in kleinen RAM-Umgebungen und in Abwesenheit eines Betriebssystems (z. B. in der Welt der Mikrocontroller) im Allgemeinen verpönt. Der in einer eingebetteten Umgebung verfügbare Heap-Speicherplatz ist normalerweise gemessen in Hunderten von Bytes ...
Das Implementieren von malloc und free ist im Wesentlichen die Pflege einer verknüpften Liste von "freien Segment" -Strukturen, und wie Sie sich vorstellen können, sind die mit freien Segmenten verknüpften Metadaten im Vergleich zu der normalerweise verfügbaren Speichermenge nicht unwesentlich ... das ist der "Overhead" "Das Verwalten eines dynamischen Speicherpools verbraucht einen erheblichen Teil der verfügbaren Ressourcen.
quelle
Ich weiß nicht, ob die C18-Standardbibliothek
malloc
und unterstütztfree
, aber der Microchip App Note AN914 zeigt, wie Sie Ihre eigenen implementieren können.Auf jeden Fall haben Thomas und andere Poster vorgeschlagen, dass die Verwendung von dynamischem Speicher auf PICs mit ihrem sehr kleinen RAM-Speicher mit Gefahren behaftet ist. Aufgrund des Mangels an fortschrittlicheren virtuellen Speichermanagern , die Ihnen von vollwertigen Betriebssystemen zur Verfügung gestellt werden, kann schnell der zusammenhängende Speicherplatz ausgehen , was zu fehlgeschlagenen Zuordnungen und Abstürzen führt. Schlimmer noch, es ist möglicherweise nicht deterministisch und wird wahrscheinlich ein Problem beim Debuggen sein.
Wenn das, was Sie tun, zur Laufzeit wirklich dynamisch bestimmt wird (selten für die meisten eingebetteten Dinge) und Sie nur zu ganz besonderen Anlässen Speicherplatz zuweisen müssen , könnte ich sehen
malloc
undfree
akzeptabel sein.quelle
Wie groß ist Ihr PIC in Bezug auf den Speicher?
malloc ist eine sehr ineffiziente Methode zum Zuweisen von Speicher. Das Problem dabei ist, dass der Speicher mit häufigen Freigaben und Mallocs fragmentiert werden kann und mit nur wenigen Kilobyte Speicher allzu häufig Zuordnungsfehler auftreten. Es ist sehr wahrscheinlich, dass bei Verwendung eines kleineren Chips oder eines früheren PIC18 Malloc nicht unterstützt wird, da Microchip die Implementierung entweder als sehr schwierig (oder in einigen Fällen sogar als unmöglich) ansah oder nicht ausreichend verwendet wurde es ist es wert. Ganz zu schweigen davon, aber es ist auch ziemlich langsam. Sie betrachten 1 Zyklus, um einen bereits verfügbaren statischen Puffer zu verwenden, und 100 bis 1000 Zyklen, um ein Malloc zu erstellen.
Wenn Sie statisch zuordnen möchten, erstellen Sie beispielsweise einen Puffer für Ihre Sprintf-Funktionen (falls vorhanden, ca. 128 Byte), einen Puffer für Ihre SD-Karte (falls vorhanden) usw., bis Sie Malloc nicht mehr benötigen. Im Idealfall verwenden Sie es nur dort, wo Sie es unbedingt benötigen und mit statischer Zuordnung nicht durchkommen können. Diese Situationen sind jedoch normalerweise selten und möglicherweise ein Zeichen dafür, dass Sie sich größere / leistungsstärkere Mikrocontroller ansehen sollten.
Und wenn Sie ein "Betriebssystem" auf dem PIC18 entwickeln / portieren und wenn es Mikrocontroller unterstützt, unterstützt es wahrscheinlich die statische Zuordnung. Beispielsweise unterstützt SQLite3 die statische Zuweisung - Sie weisen ihm ein großes Pufferarray zu und es verwendet dieses, wo dies möglich ist, auch wenn es nicht für Mikrocontroller geeignet ist. Wenn nicht, sind Sie sicher, dass es für einen kleinen PIC18 ausgelegt ist?
quelle
Wenn Sie überlegen,
malloc()
undfree()
für Ihre eingebettete Software schlage ich vor, dass Sie sich uC / OS-II undOSMemGet()
und ansehenOSMemPut()
. Währendmalloc()
Sie einen beliebigen Speicherblock zuweisen können, erhaltenOSMem*()
Sie einen Block mit fester Größe aus einem vorab zugewiesenen Pool. Ich finde diesen Ansatz ein gutes Gleichgewicht zwischen der Flexibilitätmalloc()
und der Robustheit der statischen Zuordnung.quelle
AFAIK, um dies richtig zu machen, müssen Sie sich wirklich ein Gerät mit einer Art Speicherverwaltungseinheit (MMU) ansehen. Es gibt zwar dynamische Zuweisungsmechanismen für die PIC18-Serie, aber sie werden nicht wirklich so solide sein - und als jemand, der an Firmware gearbeitet hat, die die Grenzen der PIC18-Serie überschreitet, kann ich sagen, dass Sie das nicht bekommen werden Eine umfangreiche Anwendung, wenn Sie den gesamten Aufwand für einen Speichermanager aufwenden.
Bessere Lösung: Versuchen Sie zu verstehen, was es tut und warum es eine dynamische Zuordnung benötigt. Überprüfen Sie, ob Sie es nicht neu faktorisieren können, um mit der statischen Zuordnung zu arbeiten. (Es kann vorkommen, dass dies einfach nicht möglich ist - wenn die Bibliothek / Anwendung so konzipiert ist, dass sie frei skalierbar ist oder keine Grenzen für die Menge an Eingaben hat, die sie akzeptieren kann.) Aber manchmal, wenn Sie wirklich nachdenken In Bezug auf das, was Sie versuchen, ist es möglicherweise möglich (und möglicherweise sogar recht einfach), stattdessen die statische Zuordnung zu verwenden.
quelle