Strategien zur Verwaltung der Codegröße – PIC18 XC8

Ich bin neu in der eingebetteten C-Entwicklung und suche nach allgemeinen Grundsätzen/Richtlinien für die Verwaltung der Größe des generierten Codes.

In meinem konkreten Beispiel verwende ich XC8 auf einem PIC18F4550. Mein Code verwendet bisher etwa 13% des Speicherplatzes. Sobald ich "time.h" und 1/2 Funktionen davon verwende, springt die Nutzung auf 45%! Mir ist klar, dass der kostenlose XC8-Compiler nicht optimiert, aber ich bin immer noch sehr überrascht zu sehen, wie viel Speicherplatz verwendet wird.

Was suche ich nach Tipps/Ansatzpunkten in der Art von

  • Alternativen zu den Standardbibliotheken, die kleine gezielte Teilmengen der Funktionalität implementieren. ZB ein Datum/Uhrzeit lib. dh gibt es Neupositionen, aus denen ich nützliche Routinen bekommen kann?
  • So sehen Sie, was den ganzen Platz belegt. (Listing/Map-Dateien - und Tipps zu deren Analyse)
  • Alle anderen Tipps / Ressourcen.

BEARBEITEN : Ich habe hier eine nette Implementierung ohne Verwendung von stdlib gefunden: https://codereview.stackexchange.com/questions/38275/convert-between-date-time-and-time-stamp-without-using-std-library-routines

Die generelle Frage bleibt aber bestehen. Gibt es Richtlinien, gute Repository-Quellen etc

Ist Opt-Level 1 nicht erlaubt? Für etwas mehr können Sie eine der neueren pic32-Linien mit viel mehr Blitz bekommen. Es scheint, dass xc8 eingeschränkter ist als die Compiler 16 und 32.
@ErikFriesen Danke, ich werde auf jeden Fall später die pic32-Reihe ausprobieren. Im Moment möchte ich versuchen, es mit dem pic18 zum Laufen zu bringen. Das interessiert mich aber auch allgemein. Das heißt, es wird immer eine gewisse Platzbeschränkung geben und ich würde gerne Wege finden, die Dinge zu verbessern
Wir haben eine Lizenz von XC8 pro, die unser Haupt-Firmware-Typ verwendet. Der Rest von uns entwickelt mit der kostenlosen Version für kleinere Sachen, und er zieht und kompiliert bei Bedarf zur Optimierung. Es scheint mir, dass der Compiler die gesamte Optimierung in der kostenlosen Version anwendet, aber eine Reihe von Verzweigungsanweisungen einfügt. Die Demontage von Pro- und Free-Version sieht also gleich aus, bei der Free-Version hüpfen nur eine ganze Reihe von Ästen herum. Sie können jede gewünschte Funktionalität aus der Zeitbibliothek nehmen und Ihre eigene entwickeln. Da lässt sich fast immer Platz sparen.
Danke @MattYoung, ja, ich denke, die Antwort für die Bibliotheken wird so ziemlich nur Google für vorhandene Lösungen / andere stdlibs sein und von dort aus modifizieren. Es scheint, dass die Platzersparnis erheblich sein wird. Ich bin überrascht, dass es nicht mehr Unterschiede zwischen den kostenlosen und den Pro-Ausgängen gibt. Ich habe viele gegenteilige Kommentare/Beschwerden gesehen. Sehr interessant.
Ich habe die beiden nur in einigen Anwendungen ausführlich verglichen, bei denen das Timing entscheidend war, aber das waren meine Erkenntnisse. Weiterlesen lohnt sich auf jeden Fall.
@ Matt Junge. Ich denke, sie sagen, dass die älteren Versionen die zufälligen Sprünge machen, sind Sie auf der neuesten Version von xc8?
@ErikFriesen Das letzte Mal, als ich es angeschaut habe, war 1.21.
Die prozedurale Abstraktion ist eine Standardtechnik für die Codedichte. Leider ist dies auf C-Sprachebene aufgrund von Standard-ABIs weniger nützlich. Wenn der Funktionsaufruf-Overhead auf eine aufrufende Anweisung und eine aufgerufene Anweisung begrenzt werden kann, können sogar kurze Anweisungssequenzen mit nur wenigen Aufrufern profitieren. Dies bedeutet, dass mehr Anweisungen ausgeführt werden (einige möglicherweise für bestimmte Pfade nutzlos), aber durch das Ersetzen der erforderlichen Anweisungen durch einen Funktionsaufruf wird die Anzahl der statischen Anweisungen reduziert.
@ErikFriesen For little more you can get one of the newish pic32 line with much more flash. It seems that xc8 is more limited than the 16 and 32 compilersWovon redest du? Es geht nicht um die Mikrocontroller-Familie. Es geht um die kostenlose Version des Compilers, die auf alle Arten von PICs beschränkt ist
@m.Alin. Hast du beide Compiler benutzt? Wenn Sie möchten, können Sie eine alte Version von c32 erhalten, die Ihren Code vollständig optimiert, jedoch nicht die mc-Bibliotheken. xc8 wird das nicht tun.
Außerdem wird xc32 0 und 1 Opt-Level ausführen, xc8 hat nur 0? Es hat einige andere Kuriositäten, die ich nicht wirklich mochte, also half ich bei einem Projekt, eine Migration von der 18er-Linie wegzuschieben.
Eine Sache, die zu berücksichtigen ist, ist, von der am wenigsten effektiven MCU auf dem Markt zu etwas Modernem zu wechseln. Mikrochips sind wahrscheinlich sowieso innerhalb von 5 Jahren tot, also je früher Sie das sinkende Schiff verlassen, desto besser.
Niemand tritt einen toten Hund.

Antworten (3)

Hier sind einige Dinge, die ich bei der Verwendung des Microchips C18-Compilers getan habe. Vielleicht gelten die Konzepte für Ihren Compiler: - Deklarieren Sie jeden String einmal. Fügen Sie eine separate .c-Datei ein und verwenden Sie eine .h-Datei, um darauf zu verweisen. Mit anderen Worten, duplizieren Sie Anzeigemeldungen nicht mehrmals. - Strings deklarieren, damit sie in ROM gehen. Dies hilft Ihnen nicht beim ROM (Code Space), spart jedoch Speicherplatz. - engen Code schreiben. Wenn mehrere Codezeilen dupliziert werden, fügen Sie sie in eine Funktion ein. Kopieren / Einfügen ist nicht erforderlich, ein bester Freund des eingebetteten Programmierers. - Wie Sie bereits gedacht haben, implementieren Sie Ihre eigenen Funktionen, anstatt eine Bibliothek einzubinden. Ich habe einmal eine Menge Platz gespart, indem ich meine eigene Funktion itoa() erstellt habe. Versuchen Sie, printf nicht zu verwenden.

Ich habe mich ein wenig umgesehen und hier sind die Tipps, die ich finden kann

  1. Schreiben Sie besseren Code. Codegröße und -geschwindigkeit müssen bei jedem Schritt berücksichtigt werden.
  2. Der C-Compiler/Linker verwendet nur die Funktionen, die Sie tatsächlich verwenden. Das Einfügen einer .h-Datei sollte die Codegröße also nicht (viel) erhöhen.
  3. Standardfunktionen sind jedoch oft allgemeiner als Sie benötigen. Es ist möglich, kleinere Versionen zu schreiben, die nur das tun, was Sie benötigen
  4. Freigegebene Zeichenfolgen gemäß der Antwort von @BrianK

Dann gibt es einige Alternativen, die das Kernproblem der Codegröße nicht ansprechen, aber möglicherweise in Betracht gezogen werden müssen, wenn alles andere fehlschlägt

  1. Verwenden Sie ein PIC mit mehr Platz
  2. Verwenden Sie einen optimierenden Compiler, zB MPLAB Pro
  3. Verwenden Sie Assembler für einen Teil oder den gesamten Code

Ich hätte immer noch gerne eine einfache Möglichkeit zu sehen, welche Funktionen und enthaltenen Funktionen den meisten Platz beanspruchen. Ich werde hier aktualisieren, wenn ich einen einfachen Weg finde, dies zu tun.

Es kann hilfreich sein, eine eigene Version von Standardfunktionen zu implementieren, anstatt die gesamte Bibliothek einzubinden. Es gibt eine Million kleinerer, spezifischerer Optimierungen, die Sie durchführen können, aber eine gute Referenzsammlung dieser Art von Tricks ist das Buch Hacker's Delight . Es ist sehr praktisch (insbesondere für Bit-Twiddling, wie Sie es oft auf einem Mikrocontroller tun) und ich empfehle es.

Ich habe die erste Ausgabe von Hacker's Delight (und liebe es). Irgendwelche Ideen, was die Unterschiede in der zweiten Ausgabe sind? Lohnt es sich zu kaufen, wenn ich das erste habe?
Ich habe die erste Ausgabe nicht, aber ich glaube, dass die zweite Ausgabe eine Menge neues Material sowie einige Verfeinerungen des Originals hinzufügt.
Ein „Einbinden der gesamten Bibliothek“ gibt es nicht, nur die von Ihnen genutzten Funktionen werden mit dem Programm verknüpft. Denken Sie daran, dass die std-Bibliothek für Ihren Compiler möglicherweise für das spezifische Ziel optimiert ist. Es scheint unwahrscheinlich, dass das Schreiben Ihrer eigenen Version dieser Funktionen Platz spart. Eher wird es das Gegenteil bewirken.
@Lundin das stimmt. Das heißt, wenn ich strfmttime verwende, sehe ich einen großen Größenzuwachs gegenüber der Verwendung von gmtime usw. Ich stimme jedoch nicht der allgemeinen Aussage zu, dass das Schreiben eigener Bibliotheken nicht hilft. Es ist unwahrscheinlich, dass ich ein effizienteres Feature für den Feature-Ersatz erstellen kann. Allerdings benötige ich nur einen kleinen Prozentsatz der bereitgestellten Funktionalität. (Der Code für die Zeitzone usw. ist enthalten, da gmtime usw. davon ausgeht). Ich konnte eine kleine gezielte Teilmenge der Funktionalität schreiben und 20 % des Speicherplatzverbrauchs einsparen. Es ist also möglich, eine minimale Teilmenge zu schreiben. Guter Punkt über das Verlinken. Danke