Ich habe die Antwort für Flash-Speicher, aber die RAM-Frage entzieht sich mir immer noch.
Arduino hat diese super nette Funktion, die die Flash- und RAM-Nutzung direkt zur Kompilierzeit anzeigt. Ex. In der Abbildung unten sehen Sie, dass dieses Arduino-Programm 2084 Byte Flash (6 %) verwendet und dass globale und statische Variablen 188 Byte (9 %) des dynamischen Speichers oder SRAM verwenden.
Wenn ich ein einfaches Blinkprogramm auf einem STM32F103RB Nucleo-Entwicklungsboard in der System Workbench IDE kompiliere, möchte ich dasselbe wissen: Wie viel Flash und RAM wird verwendet und wie viel bleibt übrig?
Wenn der Bau abgeschlossen ist, zeigt System Workbench Folgendes an:
Generating binary and Printing size information:
arm-none-eabi-objcopy -O binary "STM32F103RB_Nucleo.elf" "STM32F103RB_Nucleo.bin"
arm-none-eabi-size "STM32F103RB_Nucleo.elf"
text data bss dec hex filename
2896 12 1588 4496 1190 STM32F103RB_Nucleo.elf
Wenn ich mir die binäre Ausgabedatei "SW4STM32/Debug/STM32F103RB_Nucleo.bin" ansehe, sehe ich, dass es 2908 Bytes sind, was die Summe von text
+ ist data
. Daher muss das meine Flash-Nutzung sein! Da ich 128 KB Flash habe, bedeutet das, dass ich 2908/(128*1024) = 2 % des gesamten Flash-Speicherplatzes verwende.
Aber wie finde ich heraus, wie viel SRAM meine globalen und statischen Variablen verwenden und wie viel für lokale Variablen verfügbar ist (wie Arduino zeigt)?
Ich habe noch keine Ahnung, was diese Dinge bedeuten, aber wenn dies hilfreich ist, um Ihnen zu helfen, mir zu helfen , hier ist die Ausgabe von objdump -h STM32F103RB_Nucleo.elf
:
$ objdump -h STM32F103RB_Nucleo.elf
STM32F103RB_Nucleo.elf: file format elf32-little
Sections:
Idx Name Size VMA LMA File off Algn
0 .isr_vector 0000010c 08000000 08000000 00010000 2**0
CONTENTS, ALLOC, LOAD, READONLY, DATA
1 .text 00000a1c 0800010c 0800010c 0001010c 2**2
CONTENTS, ALLOC, LOAD, READONLY, CODE
2 .rodata 00000028 08000b28 08000b28 00010b28 2**0
CONTENTS, ALLOC, LOAD, READONLY, DATA
3 .init_array 00000004 08000b50 08000b50 00010b50 2**2
CONTENTS, ALLOC, LOAD, DATA
4 .fini_array 00000004 08000b54 08000b54 00010b54 2**2
CONTENTS, ALLOC, LOAD, DATA
5 .data 00000004 20000000 08000b58 00020000 2**2
CONTENTS, ALLOC, LOAD, DATA
6 .bss 00000030 20000004 08000b5c 00020004 2**2
ALLOC
7 ._user_heap_stack 00000604 20000034 08000b5c 00020034 2**0
ALLOC
8 .ARM.attributes 00000029 00000000 00000000 00020004 2**0
CONTENTS, READONLY
9 .debug_info 00006795 00000000 00000000 0002002d 2**0
CONTENTS, READONLY, DEBUGGING
10 .debug_abbrev 000013b2 00000000 00000000 000267c2 2**0
CONTENTS, READONLY, DEBUGGING
11 .debug_loc 00000d0f 00000000 00000000 00027b74 2**0
CONTENTS, READONLY, DEBUGGING
12 .debug_aranges 000002e0 00000000 00000000 00028888 2**3
CONTENTS, READONLY, DEBUGGING
13 .debug_ranges 00000378 00000000 00000000 00028b68 2**3
CONTENTS, READONLY, DEBUGGING
14 .debug_macro 00001488 00000000 00000000 00028ee0 2**0
CONTENTS, READONLY, DEBUGGING
15 .debug_line 00003dcc 00000000 00000000 0002a368 2**0
CONTENTS, READONLY, DEBUGGING
16 .debug_str 00066766 00000000 00000000 0002e134 2**0
CONTENTS, READONLY, DEBUGGING
17 .comment 0000007f 00000000 00000000 0009489a 2**0
CONTENTS, READONLY
18 .debug_frame 00000610 00000000 00000000 0009491c 2**2
CONTENTS, READONLY, DEBUGGING
size
Ausgabe vom „sysv“-Format ( size --format=sysv my_executable
) in das „berkeley“-Format ( size --format=berkeley my_executable
)Die Informationen, die Sie benötigen, sind alle in der Ausgabe von size
(auch bekannt als arm-none-eabi-size
):
text data bss dec hex filename
2896 12 1588 4496 1190 STM32F103RB_Nucleo.elf
text
ist die Größe des gesamten Codes in Ihrer Anwendung.
data
ist die Größe initialisierter globaler Variablen. Es zählt sowohl zum Flash-Speicher als auch zum RAM, da es beim Start vom Flash in den RAM kopiert wird.
bss
ist die Größe globaler Variablen, die auf Null initialisiert werden (oder nicht initialisiert sind und daher standardmäßig auf Null gesetzt sind). Sie werden nur im RAM gespeichert.
dec
und hex
sind die Summe von text + data + bss
dezimal und hexadezimal. Dieser Wert sagt auf einem Mikrocontroller nicht wirklich viel aus und sollte daher ignoriert werden. (In Umgebungen, in denen ein Programm vor der Ausführung in den Speicher geladen werden muss, wäre dies der gesamte Speicherbedarf des Programms.)
Um die RAM-Nutzung Ihres Programms zu berechnen, addieren Sie die Spalten data
und bss
zusammen.
SRAM = data + bss
Um die FLASH-Nutzung Ihres Programms zu berechnen, fügen Sie text
und hinzu data
.
FLASH = text + data
dec
und hex
die Größe meiner ELF-Datei sind, ist meine ELF-Datei tatsächlich 616876 Bytes groß. Irgendeine Idee warum?arm-none-eabi-size STM32F103RB_Nucleo.elf
.text
, .rodata
. .data
und .bss
. Wird oben durch die Summe dessen data
angezeigt , was in und im Linker-Skript ist?
arm-none-eabi-size
.rodata
.data
.rodata
das alles?(In environments where a program must be loaded into memory before running, it would be the total memory footprint of the program.)
... Sie meinen wie auf einem normalen Computer, oder? Ich versuche jetzt, diese Werte für ein Programm auf einem normalen Computer zu sehen, anstatt auf einem Mikrocontroller. Scheint also size name_of_executable
die Antwort zu sein. Bsp.: size a.out
.Wenn Sie möchten, dass ein schnelles Linux-Bash-Skript die Flash- und SRAM-Nutzung automatisch für Sie berechnet, lesen Sie meine andere Antwort hier .
Springen Sie direkt nach unten zur "Zusammenfassung" ganz unten.
@duskwuff -inactive- hat den Kern meiner Frage in ihrer/seiner Antwort hier beantwortet , aber ich möchte einige zusätzliche Einblicke hinzufügen und auch meine eigenen Folgefragen beantworten, die ich in den Kommentaren unter seiner Antwort geschrieben habe.
Zunächst einmal war der Abschnitt "Grundlegende Linker-Skriptkonzepte" des GNU Linker-Handbuchs , der vollständig in meinem Abschnitt "Referenzen" unten enthalten ist, der Schlüssel zum Erlernen dieser Informationen. Siehe unten in dieser Antwort unten.
Weitere Informationen zu einigen Aspekten dieser Antwort finden Sie auch in meiner anderen Antwort auf eine verwandte Frage, die ich hier zu Stack Overflow gestellt habe .
Es stellt sich heraus, dass die Informationen von objdump -h STM32F103RB_Nucleo.elf
die gleichen, spezifischeren Ausgabeunterabschnitte enthalten wie der arm-none-eabi-size -x --format=sysv "STM32F103RB_Nucleo.elf"
Befehl, der die size
Ausgabe im sysv
Format statt im Standardformat anzeigt berkeley
.
Hier ist noch einmal die Ausgabe im Berkeley-Format des Befehls size
( arm-none-eabi-size
für STM32 mcus):
arm-none-eabi-size "STM32F103RB_Nucleo.elf"
text data bss dec hex filename
2896 12 1588 4496 1190 STM32F103RB_Nucleo.elf
Beachten Sie, dass dies arm-none-eabi-size "STM32F103RB_Nucleo.elf"
äquivalent zu ist arm-none-eabi-size --format=berkeley "STM32F103RB_Nucleo.elf"
, da --format=berkeley
dies die Standardeinstellung ist.
In der objdump -h STM32F103RB_Nucleo.elf
Ausgabe, die ich in meiner Frage gepostet habe, finden sich alle Informationen, die wir zur Beantwortung meiner Frage benötigen, nur in einem viel detaillierteren Format.
Wie das GNU-Linker-Handbuch erklärt (siehe unten), bedeutet VMA "Virtual Memory Address" und LMA bedeutet "Load Memory Address". Die VMA-Adressen befinden sich dort, wo sich die Daten zur Laufzeit befinden (was sich im flüchtigen SRAM befinden könnte, da einige Daten beim Booten vom Flash in den SRAM kopiert werden), und in der LMA befinden sich die Daten, wenn das Gerät ausgeschaltet ist, und auch vor dem Laden beim Booten (also darf es nur im nichtflüchtigen Flash-Speicher sein ). Einige Daten werden beim Booten vom Flash (LMA-Adresse) zum SRAM (VMA-Adresse) kopiert.
Bei diesem STM32-Mikrocontroller beginnt der Flash-Speicher bei der Adresse 0x08000000
und der SRAM bei der Adresse 0x20000000
. Alle Ausgabeabschnitte in der objdump -h
Ausgabe, die eine VMA (Laufzeitadresse) von 0 haben, sind daher unbenutzt (auch nicht auf dem Mikrocontroller) und können sofort verworfen werden. Dadurch wird die zweite Hälfte der objdump -h
Ausgabe, von der die meisten Debug-Informationen sind, aus dem .ARM.attributes
Ausgabeabschnitt bis .debug_frame
einschließlich Ausgabeabschnitt eliminiert, sodass wir nur diese sysv-Ausgabeabschnitte haben, die uns interessieren :
Sections:
Idx Name Size VMA LMA File off Algn
0 .isr_vector 0000010c 08000000 08000000 00010000 2**0
CONTENTS, ALLOC, LOAD, READONLY, DATA
1 .text 00000a1c 0800010c 0800010c 0001010c 2**2
CONTENTS, ALLOC, LOAD, READONLY, CODE
2 .rodata 00000028 08000b28 08000b28 00010b28 2**0
CONTENTS, ALLOC, LOAD, READONLY, DATA
3 .init_array 00000004 08000b50 08000b50 00010b50 2**2
CONTENTS, ALLOC, LOAD, DATA
4 .fini_array 00000004 08000b54 08000b54 00010b54 2**2
CONTENTS, ALLOC, LOAD, DATA
5 .data 00000004 20000000 08000b58 00020000 2**2
CONTENTS, ALLOC, LOAD, DATA
6 .bss 00000030 20000004 08000b5c 00020004 2**2
ALLOC
7 ._user_heap_stack 00000604 20000034 08000b5c 00020034 2**0
ALLOC
Wie Sie sehen können, wird jeder mit gekennzeichnete Abschnitt READONLY
nur im Flash-Speicher an den 0x08000000
Adressen auf -Ebene gespeichert und hat dieselbe LMA- und VMA-Adresse. Dies ist sinnvoll, da es nicht erforderlich ist, es in den SRAM zu kopieren, wenn es schreibgeschützt ist. Die markierten Abschnitte READONLY
bilden den text
Abschnitt im Berkeley-Format. Sie beinhalten:
.isr_vector
.text
.rodata
Wir wissen also:
.isr_vector + .text + .rodata = text
Dies kann durch Summieren ihrer Hex-Größen überprüft werden:
10c + a1c + 28 = b50
0xb50 ist dezimal 2896, was der Berkeley-Size-Ausgabe für den Abschnitt entspricht text
! Und wiederum, wie durch die 0x08000000
-Level-Adressen für LMA und VMA gezeigt, bedeutet dies, dass sich alle diese Abschnitte nur im Flash-Speicher befinden !
Hier ist meine Beschreibung dessen, was diese Abschnitte sind:
SYSV-ABSCHNITTE, DIE DEN BERKELEY-ABSCHNITT BILDEN text
UND DIE NUR IM FLASH-SPEICHER SIND:
.isr_vector
= die ISR (Interrupt Service Routine)-Vektortabelle. Es zeigt einfach auf alle ISR-Callback-Funktionen für alle möglichen Interrupts, die der Mikrocontroller verarbeiten kann..text
= Programmlogik; dh: der eigentliche Code..rodata
= Nur-Lese-Daten; dh: const
und constexpr
statische und globale Variablen, die schreibgeschützt sind.Als nächstes können wir sehen, dass die NON- READONLY
Abschnitte, die auch ALLOC
und LOAD
Abschnitte sind, Folgendes enthalten:
.init_array
.fini_array
.data
Wir wissen also, dass sie die Berkeley-Sektion bilden data
:
.init_array + .fini_array + .data = data
Dies kann durch Summieren ihrer Hex-Größen überprüft werden:
4 + 4 + 4 = c
0xc ist dezimal 12, was der Berkeley-Size-Ausgabe für den Abschnitt entspricht data
.
Ich weiß nicht, was die Abschnitte .init_array
oder .fini_array
bedeuten (wenn Sie es wissen, antworten Sie bitte oder posten Sie einen Kommentar), und ich bin verwirrt über ihren Standort, da ihre LMA- und VMA-Adressen identisch sind, was darauf hinweist, dass sie sich sowohl in Flash als auch in Flash befinden . Anhand der Adressen des .data
Abschnitts wird jedoch deutlich, dass er sowohl Flash-Speicher (bei LMA [Ladeadresse] = 0x08000b58) als auch SRAM-Speicher (bei VMA [Laufzeitadresse] = 0x20000000) belegt. Dies bedeutet, dass diese Daten vom Flash an den Anfang des SRAM kopiert werden. Dies geschieht während der Startroutine. .data
enthält NICHT-Null-initialisierte (dh mit etwas anderem als Null initialisierte) statische und globale Variablen. In Summe:
SYSV-ABSCHNITTE, DIE DEN BERKELEY- data
ABSCHNITT BILDEN UND DIE SOWOHL IN FLASH ALS AUCH IN SRAM SIND UND WÄHREND DES STARTS VON FLASH NACH SRAM KOPIERT WERDEN:
.data
= NICHT-Null-initialisierte (dh: mit etwas anderem als Null initialisierte) statische und globale VariablenSYSV-ABSCHNITTE, DIE DEN BERKELEY- data
ABSCHNITT BILDEN UND DIE ANSCHEINEND NUR IM FLASH-SPEICHER SIND?:
.init_array
= unbekannt.fini_array
= unbekanntDamit bleiben uns nur diese mit markierten Abschnitte ALLOC
und nichts anderes übrig:
.bss
._user_heap_stack
Wir wissen also, dass sie die Berkeley-Sektion bilden bss
:
.bss + ._user_heap_stack = bss
Dies kann durch Summieren ihrer Hex-Größen überprüft werden:
30 + 604 = 634
0x634 ist dezimal 1588, was der Berkeley-Size-Ausgabe für den Abschnitt entspricht bss
.
Das ist wirklich interessant! , da es zeigt, dass der Berkeley- bss
Abschnitt nicht nur den .bss
Ausgabeabschnitt (nullinitialisierte statische und globale Variablen) enthält, sondern auch den Ausgabeabschnitt ._user_heap_stack
, der vielleicht die Heap-Größe ist (oder mir eher so erscheint). Wir spezifizieren innerhalb der STM32Cube-Konfigurationssoftware. In beiden Fällen scheint es der SRAM zu sein, der sowohl für den Laufzeitstapel (für lokale Variablen) als auch für den Heap (für dynamisch zugewiesenen Speicher) vorgesehen ist. In Summe:
SYSV-ABSCHNITTE, DIE DEN BERKELEY-ABSCHNITT bss
BILDEN UND DIE NUR IN SRAM, ABER NICHT IN FLASH, PLATZ BEGINNEN:
.bss
= Null-initialisierte statische und globale Variablen; dieses SRAM wird beim Programmstart auf alle Nullen gesetzt.._user_heap_stack
= (glaube ich) vollständig nicht initialisierter SRAM, der für den Laufzeitstapel (für lokale Variablen) und Heap (für dynamisch zugewiesenen Speicher) vorgesehen ist.Hier ist die Aufschlüsselung, welche sysv-Ausgabeabschnitte aus der objdump -h STM32F103RB_Nucleo.elf
Ausgabe (ebenfalls mit weniger Details in der arm-none-eabi-size -x --format=sysv "STM32F103RB_Nucleo.elf"
Ausgabe dargestellt) welche Berkeley-Ausgabeabschnitte bilden.
In der folgenden Abbildung sehen Sie alle 3 Berkely-Ausgabeabschnitte, die in verschiedenen Farben eingerahmt sind:
[GELB] Die Ausgabeabschnitte im Berkeley-Format text
(schreibgeschützt, Programmlogik und konstante statische und globale Variablen) sind gelb umrandet .
.isr_vector + .text + .rodata = text
.isr_vector
[IN FLASH ONLY] = die ISR (Interrupt Service Routine)-Vektortabelle. Es zeigt einfach auf alle ISR-Callback-Funktionen für alle möglichen Interrupts, die der Mikrocontroller verarbeiten kann..text
[NUR IN FLASH] = Programmlogik; dh: der eigentliche Code..rodata
[IN FLASH ONLY] = Nur-Lese-Daten; dh: const
und constexpr
statische und globale Variablen, die schreibgeschützt sind.data
[BLAU] Die Ausgabeabschnitte im Berkeley-Format (Nicht-Null-initialisierte [dh: mit anderen Werten als Null initialisierte] statische und globale Variablen) sind blau umrandet .
.init_array + .fini_array + .data = data
.init_array
[NUR FLASH erscheint] = unbekannt..fini_array
[NUR FLASH erscheint] = unbekannt..data
[IN SOWOHL FLASH ALS AUCH SRAM] = NICHT-Null-initialisierte (dh: mit etwas anderem als Null initialisierte) statische und globale Variablen. Diese Werte müssen beim Start vom Flash in den SRAM kopiert werden, um ihre entsprechenden statischen oder globalen Variablen im SRAM zu initialisieren.bss
[ROT] Die Ausgabeabschnitte im Berkeley-Format (mit Null initialisierte statische und globale Variablen und anscheinend auch nicht initialisierter Stack- und Heap-Speicherplatz) sind rot umrandet .
.bss + ._user_heap_stack = bss
.bss
[NUR SRAM] = Null-initialisierte statische und globale Variablen; dieses SRAM wird beim Programmstart auf alle Nullen gesetzt.._user_heap_stack
[NUR SRAM] = vollständig nicht initialisierter (glaube ich) SRAM, der für den Laufzeitstapel (für lokale Variablen) und Heap (für dynamisch zugewiesenen Speicher) vorgesehen ist.[GRAU] Verworfene Sysv-Ausgabeabschnitte, die zu keinem der 3 Berkeley-Ausgabeabschnitte beitragen, sind grau umrandet .
Speicher Schlussfolgerungen:
text
+ berkeley data
.
.isr_vector
..text
..rodata
.bss
+ berkeley data
.
(.bss + .data)
. Beachten Sie die Punkte ( .
) vor jedem dieser Namen hier, im Gegensatz zu den fehlenden Punkten oben.._user_heap_stack
.SRAM_total - (berkeley bss + berkeley data)
.GNU Linker ( ld
) Handbuch, Abschnitt "3.1 Basic Linker Script Concepts": https://sourceware.org/binutils/docs/ld/Basic-Script-Concepts.html#Basic-Script-Concepts :
3.1 Grundlegende Linker-Skript-Konzepte
Wir müssen einige grundlegende Konzepte und Vokabeln definieren, um die Linker-Skriptsprache zu beschreiben.
Der Linker kombiniert Eingabedateien zu einer einzigen Ausgabedatei. Die Ausgabedatei und jede Eingabedatei haben ein spezielles Datenformat, das als Objektdateiformat bekannt ist . Jede Datei wird Objektdatei genannt . Die Ausgabedatei wird oft als ausführbare Datei bezeichnet , aber für unsere Zwecke nennen wir sie auch Objektdatei. Jede Objektdatei hat unter anderem eine Liste von Abschnitten . Wir beziehen uns manchmal auf einen Abschnitt in einer Eingabedatei als Eingabeabschnitt ; ebenso ist ein Abschnitt in der Ausgabedatei ein Ausgabeabschnitt .
Jeder Abschnitt in einer Objektdatei hat einen Namen und eine Größe. Die meisten Abschnitte haben auch einen zugeordneten Datenblock, der als Abschnittsinhalt bekannt ist . Ein Abschnitt kann als ladbar markiert sein , was bedeutet, dass der Inhalt in den Speicher geladen werden sollte, wenn die Ausgabedatei ausgeführt wird. Ein Abschnitt ohne Inhalt kann allokierbar sein, was bedeutet, dass ein Bereich im Speicher reserviert, aber nichts Besonderes dort geladen werden sollte (in einigen Fällen muss dieser Speicher auf Null gesetzt werden). Ein Abschnitt, der weder ladbar noch zuweisbar ist, enthält typischerweise irgendeine Art von Debugging-Informationen.
Jeder ladbare oder belegbare Ausgangsabschnitt hat zwei Adressen. Die erste ist die VMA oder virtuelle Speicheradresse. Dies ist die Adresse, die der Abschnitt haben wird, wenn die Ausgabedatei ausgeführt wird. Die zweite ist die LMA oder Ladespeicheradresse. Dies ist die Adresse, an der der Abschnitt geladen wird. In den meisten Fällen sind die beiden Adressen identisch. Ein Beispiel dafür, wann sie unterschiedlich sein könnten, ist, wenn ein Datenabschnitt in den ROM geladen und dann beim Programmstart in den RAM kopiert wird (diese Technik wird häufig verwendet, um globale Variablen in einem ROM-basierten System zu initialisieren). In diesem Fall wäre die ROM-Adresse der LMA und die RAM-Adresse der VMA.
Sie können die Abschnitte in einer Objektdatei anzeigen, indem Sie das
objdump
Programm mit der Option „-h“ verwenden.Jede Objektdatei hat auch eine Liste von Symbolen , die als Symboltabelle bekannt ist . Ein Symbol kann definiert oder undefiniert sein. Jedes Symbol hat neben anderen Informationen einen Namen und jedes definierte Symbol hat eine Adresse. Wenn Sie ein C- oder C++-Programm in eine Objektdatei kompilieren, erhalten Sie ein definiertes Symbol für jede definierte Funktion und globale oder statische Variable. Jede undefinierte Funktion oder globale Variable, auf die in der Eingabedatei verwiesen wird, wird zu einem undefinierten Symbol.
Sie können die Symbole in einer Objektdatei sehen
nm
, indem Sie das Programm verwenden oder indem Sie dasobjdump
Programm mit der Option „-t“ verwenden.
Meine eigene Antwort auf meine eigene Frage hier: Konvertieren Sie die binutils- size
Ausgabe vom „sysv“-Format ( size --format=sysv my_executable
) in das „berkeley“-Format ( size --format=berkeley my_executable
)
.init_array
und .fini_array
-- Bei globalen Variablen in C++ werden der Konstruktor und der Destruktor ausgeführt, bevor die Ausführung von main beginnt bzw. nach dem Beenden von main. Diese beiden Abschnitte enthalten (Zeiger auf) Konstruktions- und Zerstörungsfunktionen, die von der Laufzeitunterstützungsbibliothek aufgerufen werden müssen. Reiner ISO-Standard C hat so etwas nicht (Sie können eine globale C-Variable nicht mit einem dynamischen Ausdruck initialisieren), aber gcc fügt sie als Erweiterung zu C hinzu, indem Sie __attribute((constructor))__
and verwenden __attribute__((destructor))
.Als Erweiterung der beiden anderen Antworten, einschließlich meiner eigenen , ist hier ein 1-zeiliges Linux-Bash-Skript, mit dem Sie automatisch berechnen FLASH
und verwenden können SRAM
.
Dies setzt voraus, dass Ihr Befehl zum Anzeigen der Berkeley-Größeninformationen Ihrer .elf-Datei arm-none-eabi-size "STM32F103RB_Nucleo.elf"
. Aktualisieren Sie diesen Pfad zu Ihrer gewünschten .elf-Datei. Wenn Sie Linux-.elf-Dateien oder reguläre ausführbare Dateien anstelle von STM32-.elf-Dateien betrachten, verwenden Sie size
anstelle von arm-none-eabi-size
. Bsp.: size path/to/my_program.elf
.
Wie auch immer, hier ist das Skript:
size_info=$(arm-none-eabi-size "STM32F103RB_Nucleo.elf" | awk NR\>1); \
text=$(echo "$size_info" | awk '{print $1}'); \
data=$(echo "$size_info" | awk '{print $2}'); \
bss=$(echo "$size_info" | awk '{print $3}'); \
flash=$(($text + $data)); \
sram=$(($bss + $data)); \
echo "FLASH used = $flash bytes"; \
echo "SRAM used by global variables = $sram bytes"
Angenommen, das arm-none-eabi-size "STM32F103RB_Nucleo.elf"
zeigt dies:
text data bss dec hex filename
2896 12 1588 4496 1190 STM32F103RB_Nucleo.elf
...hier ist eine Beispielausgabe der Ausführung des obigen Skripts:
FLASH used = 2908 bytes
SRAM used by global variables = 1600 bytes
FLASH = text + data
SRAM = bss + data
text
= Programmdaten + ISR-Vektor + Rodata (Nur-Lese-Daten: const
und constexpr
statische und globale Nur-Lese-Variablen)data
= NICHT-Null-initialisierte (dh: mit einer anderen Zahl als Null initialisierte) statische und globale Variablen, + .init_array + .fini_arraybss
= Null-initialisierte statische und globale Variablen + Stack- und Heap-Platz, der vom Linker-Skript reserviert wirdWeitere Details finden Sie in meiner anderen, sehr detaillierten Antwort hier: Wie finde ich zur Kompilierzeit heraus, wie viel Flash-Speicher und dynamischer Speicher (SRAM) eines STM32 verbraucht sind?
awk
zum Entfernen der ersten Zeile eines Text-Blobs: https://superuser.com/questions/284258/remove-first-line-in-bash/284270#284270awk
Beispiel aus meinen eigenen Notizen , um mich daran zu erinnern, wie man es benutzt:du -h | tail -n 1 | awk '{print $1}'
Chris Stratton
Gabriel Staples