Hallo,
ich bin gerade dabei ein Programm für den LPC1768 fertig zustellen.
Jetzt möchte ich aber herausfinden, wie viel ROM und RAM denn mein
Programm vertilgt. Wie kann ich das herausfinden? Ich seh z.B. am ende
des LPC1768_RAM.ld Scripts folgendes:
1
/*
2
* The ".stack" section is our stack.
3
* Here this section starts at the end of the ram segment.
4
*/
5
_estack = ORIGIN(RAM) + LENGTH(RAM);
Bedeutet LENGTH(RAM) die komplette Größe meines RAMs oder nur die der
globalen Variablen? (Also alles, was nicht auf dem Stack landet).
Hat jemand einen Vorschlag wie ich das bewerkstelligen könnte?
Grüße, Harald
Werner schrieb:> gcc-size application.elf>> Dem gcc stellst du noch den Crosscompilerprefix voran und die elf-Datei> ist dein Programm.
Hallo Werner,
dass meine elf-Datei mein Programm ist weiß ich ja (kann aber nicht ins
ROM geladen werden, dafür ist bin zuständig).
Leider find ich auf dem Arbeits-PC kein gcc-size und habe keine
root-Rechte. Und das mit dem Crosscompilerprefix versteh ich leider auch
nicht so recht.
Wenn du mir das näher erläutern könntest wäre das spitze.
Grüße, Harald
Harald schrieb:> Leider find ich auf dem Arbeits-PC kein gcc-size und habe keine> root-Rechte. Und das mit dem Crosscompilerprefix versteh ich leider auch> nicht so recht.
Wie rufst du deinen GCC auf? Vermutlich mit "arm-none-eabi-gcc"? Dann
ist "arm-none-eabi-" dein Prefix, und dein "size" ist
"arm-none-eabi-size". Detaillierter ist aber "arm-none-eabi-readelf -S
programmdatei.elf".
Hätte hierzu auch mal eine Frage.
Mein Board hat 64kB an Speicher zur Verfügung. In der .map Datei des
kompilierten Programms stehen die Sektoren wie .text, .data und .bss.
Wenn ich die mir so anschaue stehen da Sachen wie:
1
.text 0x00000000 0xd678
2
0x00000000 __cs3_region_start_rom = .
3
0x00000000 _stext = .
4
5
...
6
7
*fill* 0x0000d525 0x3 00
8
9
...
10
11
.data 0x10000000 0x848 load address 0x0000d680
12
13
...
14
15
.bss 0x10000848 0x75b8 load address 0x0000dec8
16
17
...
18
19
COMMON 0x1000347c 0x2dec ./src/can.o
20
21
...
22
23
.heap 0x10007e00 0x100 load address 0x0000dec8
24
0x10007e00 . = ALIGN (0x8)
25
*(.heap)
26
0x10007f00 . = (. + HEAP_SIZE)
27
*fill* 0x10007e00 0x100 00
28
0x10007f00 . = ALIGN (0x8)
29
30
.stack 0x10007f00 0x100 load address 0x0000dec8
31
0x10007f00 . = ALIGN (0x8)
32
*(.stack)
33
0x10008000 . = (. + STACK_SIZE)
Leider kann ich so eine .map Datei schlecht interpretieren. Kennt jemand
einen Link der alles gut erklärt? Ich könnt z.B. raten, dass die zweite
Hex-Zahl bei .text die Länge des ROMs ist. Aber was COMMON sein soll
usw. ist mir schleierhaft. Oder das fill...
Nachtrag:
Mittels arm-none-eabi-size habe ich herausgefunden, dass das Programm
knapp 37 kB Speicher benötigt. Wenn ich aber in meinem Source-Code einen
Array erzeuge, der 64kB-37kB = 27kB = 0x6c00 groß ist (uint8_t
arr[0x6c00]), meldet mir arm-none-eabi-gcc, dass der RAM überläuft. In
Wirklichkeit darf ich aber lediglich 10436 Bytes (0x28c4) noch belegen
bevor die Fehlermeldung eintritt. Das bedeutet doch, dass mein Programm
in Wirklichkeit 55098 = 0xD731 Wieso? Liegt es an irgendwelchen dubiosen
Debug-Optionen wo noch extra Speicher benötigt wird?
Lt. Manual hat der LPC
- 32/16 kB of SRAM on the CPU with local code/data bus for
high-performance CPU access.
- Two/one 16 kB SRAM blocks with separate access paths for higher
throughput. These SRAM blocks may be used for Ethernet, USB, and DMA
memory, as well as for general purpose CPU instruction and data storage.
/* Linker script for mbed LPC1768 */
GROUP(-lstdc++ -lsupc++ -lm -lc -lnosys -lgcc)
/* Linker script to configure memory regions. */
MEMORY
{
FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 512K
RAM (rwx) : ORIGIN = 0x100000C8, LENGTH = 0x7F38
USB_RAM(rwx) : ORIGIN = 0x2007C000, LENGTH = 16K
ETH_RAM(rwx) : ORIGIN = 0x20080000, LENGTH = 16K
}
Das hab ich jetzt mal bei der Suche nach LPC1768 Linker Script gefunden.
Sieht so aus, als ob die 64k RAM nicht fortlaufend addressierbar sind.
Damit kann Dir alles, was > 16k ist prinzipiell Probleme machen.
RSp
Das ist ja wirklich knifflig.
So hab jetzt ein paar Berechnungen gemacht.
Bin die .map Datei durchgegangen und habe folgendes zusammen gezählt:
Es werden momentan (THEORETISCH) 22217 Bytes gebraucht, bei 32 kB RAM
sind also noch 10551 Bytes frei. Dabei habe ich die Sektoren .data,
.bss, .heap, .stack und .iap zusammengezählt, plus alles, was so an
padding betrieben wird.
Dann habe ich im Code einen Array erzeugt, um die fen freien RAM
auszutesten.
Dabei kam heraus, dass 10436 Bytes frei sind. Das sind 131 Bytes
weniger! Von wo kommen die?
An den 16kB kanns nicht liegen, da 10436 Bytes < 16kB.
Ich habe dann probiert, den Speicher vom USB und Ethernet zu benutzen,
also die Kommentarzeichen zu entfernen, kriege beim kompilieren immer
noch denselben Fehler. Dann habe ich mir das Script für den Linker
angeschaut, und entdeckt, dass sowas z.B. drinnen steht:
Bedeutet das denn nicht, dass der Linker dann versucht alles von .data
und .bss NUR in ram rein zu tun? ram1 und ram2 scheint er
offentsichtlich ausser Acht zu lassen. Muss man denn dem Linker sagen
dass ram1 und ram2 auch RAM sind und er da Variablen reinpacken kann?
Oder erkennt er das automatisch mittels (rwx) in MEMORY{...}?
Und wenn ich den arm-none-eabi-size verwende (Input: elf-Datei des
kompilierten Programms), sagt er mir das hier:
1
text data bss dec hex filename
2
54912 2120 24348 81380 13de4 /xxx...
.data stimmt mit meiner Berechnung überein, aber wieso ist .bss so viel
größer als meine Berechnung?
Wenn du mehr Infos über den Speicherverbrauch brauchst dann ist:
arm-none-eabi-objdump -ax appl.elf
hilfreicher. Falls bei dir vorhanden kannst du mit:
arm-none-eabi-objdump -ax appl.elf | sort
direkt die Adressen sortieren.
Gas schrieb:> Bedeutet das denn nicht, dass der Linker dann versucht alles von .data> und .bss NUR in ram rein zu tun? ram1 und ram2 scheint er> offentsichtlich ausser Acht zu lassen. Muss man denn dem Linker sagen> dass ram1 und ram2 auch RAM sind und er da Variablen reinpacken kann?> Oder erkennt er das automatisch mittels (rwx) in MEMORY{...}?
Du musst dem Linker das mit angeben. Die Frage ist aber, ob der Speicher
zur Startzeit schon "vorhanden" ist oder erst die Periphery
eingeschaltet werden muss. Du könntest versuchen bss z.B. in ram1 zu
legen.
Hallo,
ich kenne arm und gcc nicht, aber Linker-Scripte aus anderen Umgebungen.
In denen wäre es so dass Du wenn Du USB_RAM (ram1) und ETH_RAM(ram2)
nutzen willst im Code entsprechende Anweisungen geben musst "leg das in
die spezielle RAM-section"
(z.B. nutzen dann die einen Quellcode-Module ram, die anderen ram1 usw.)
Das kann man beispielsweise machen, indem man eigenen Section-Namen
vergibt und im Linker-Script entsprechende Anweisungen einführt.
Man muss dann halt vorher ungefähr wissen wer wieviel RAM braucht.
Die RAM-bereiche sind ja offenbar auch adresstechnisch nicht
fortlaufend, ich weiss nicht, ob der gcc es unterstützt dass man im
Linker-Script definiert "fuer .bss und .data benutze ram und wenn voll
dann laufe über in ram1 und ram2"
bei anderen Toolketten geht das leider nicht auch wenn man es bräuchte
...
Gruß Erik
Eine eigene Frage?
Dieser Thread ist über 13 Jahre alt.
Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.