Forum: Mikrocontroller und Digitale Elektronik LPC2378 - region RAM is full


von ARMdran (Gast)


Angehängte Dateien:

Lesenswert?

Hallo Forum,

ich erweitere gerade ein Programm auf einem LPC2378 und benutze den 
arm-elf-gcc (GCC) 4.3.2

Nun bekomme ich folgende Fehlermeldung:
1
c:/yagarto/bin/../lib/gcc/arm-elf/4.3.2/../../../../arm-elf/bin/ld.exe: region RAM is full (programm.elf section .stack)

Vor der letzten Änderung (Anlegen einer Variablen) klappte noch alles 
und ich bekam die Ausgabe:
1
Size after:
2
   text     data      bss      dec      hex  filename
3
 137996     5720    13660   157376    266c0  programm.elf
4
5
fat_mci_demo.elf  :
6
section             size         addr
7
.text             137996            0
8
.data               5720   1073741824
9
.initdata           5720       137996
10
.bss               13660   1073747544
11
.stack             13312   1073761208
12
.comment            2142            0
13
.debug_aranges      8208            0
14
.debug_pubnames    23543            0
15
.debug_info       201246            0
16
.debug_abbrev      45111            0
17
.debug_line        53422            0
18
.debug_frame       20024            0
19
.debug_str         36631            0
20
.debug_loc         98745            0
21
.ARM.attributes       16            0
22
.debug_ranges      12736            0
23
Total             678232

Meine Hoffnung ist, dass vielleicht irgendwelche ungenutzten Sections im 
Ram liegen, aber durch die startup.S und ROM.ld steige ich nicht so 
richtig durch. Ich hänge beide Dateien mal an.

Der Controller hat 32kB Ram.
Wenn ich da aber nicht völlig falsch liege, dann bin ich mit .data + 
.bss + .stack = 32692 ziemlich am Anschlag, oder?

Dann habe ich ein Problem...

Es gibt aber noch extra Ram für Ethernet, USB und RTC.
Ich weiß nicht genau, ob es genutzt wird und ob es überhaupt anderweitig 
genutzt werden kann.

Ich hoffe ihr könnt mir helfen!

von ARMdran (Gast)


Lesenswert?

Mir kommt die .stack section sehr groß vor...

von ARMdran (Gast)


Lesenswert?

Wie kann ich mir das MAP file sortiert nach Variablengröße ausgeben 
lassen?
Nach Adressen sortiert ist das sehr schwer zu überblicken.

Und kann mir jemand sagen, wo hier direkt am Anfang mal eben 1kB 
verschwinden?
.data           0x40000000     0x1658 load address 0x00021b7c
                0x40000000                _data = .
 *(.vectmapped)
                0x40000000                . = ALIGN (0x4)
 *(.fastrun)
                0x40000000                . = ALIGN (0x4)
                0x40000000                . = ALIGN (0x4)
 *(.data)
 .data          0x40000000      0x404 
c:/yagarto/bin/../lib/gcc/arm-elf/4.3.2/../../../../arm-elf/lib/thumb/in 
terwork\libc.a(lib_a-impure.o)
                0x40000000                _impure_ptr
 .data          0x40000404        0x4 
c:/yagarto/bin/../lib/gcc/arm-elf/4.3.2/../../../../arm-elf/lib/thumb/in 
terwork\libc.a(lib_a-ctype_.o)
                0x40000404                __ctype_ptr

Irgendwas könnte das mit der thumb Option zu tun haben...

Und im Linkerscript, was werden hier für Zahlen abgezogen?
/* Memory Definitions */
MEMORY
{
  ROM (rx) : ORIGIN = 0x00000000, LENGTH = (512k-4k)
  RAM (rw) : ORIGIN = 0x40000000, LENGTH = (32k-32)
}

von ARMdran (Gast)


Lesenswert?

Also anscheinend kann das Ethernet RAM auch als "normales" RAM genutzt 
werden, wenn man es richtig konfiguriert.
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.faqs/ka11495.html

Ich benutze aber die Ethernetschnittstelle.
Wird dann das Ethernet RAM automatisch dafür genutzt, oder wie wird das 
verwendet?

von holger (Gast)


Lesenswert?

.data               5720   1073741824
.bss               13660   1073747544
.stack             13312   1073761208

= 32692

Hmm, irgendwo saust du da richtig heftig mit RAM rum.

>Mir kommt die .stack section sehr groß vor...

Mir auch;)

von ARMdran (Gast)


Lesenswert?

Ich habe zum Beispiel im Map file gesehen, dass meine fast 2kB an 
Parametern die eigentlich im Battery buffered RAM liegen sollen, auch im 
SRAM liegen.
Muss das sein, oder kann man auch direkt aus dem battery buffered RAM 
wie mit SRAM arbeiten?

von ARMdran (Gast)


Lesenswert?

ARMdran schrieb:
> Und kann mir jemand sagen, wo hier direkt am Anfang mal eben 1kB
> verschwinden?
> c:/yagarto/bin/../lib/gcc/arm-elf/4.3.2/../../../../arm-elf/lib/thumb/in
> terwork\libc.a(lib_a-impure.o)
>                 0x40000000                _impure_ptr
>  .data          0x40000404        0x4
> c:/yagarto/bin/../lib/gcc/arm-elf/4.3.2/../../../../arm-elf/lib/thumb/in
> terwork\libc.a(lib_a-ctype_.o)
>                 0x40000404                __ctype_ptr
>
> Irgendwas könnte das mit der thumb Option zu tun haben...

Ich habe auch noch mal ohne die Option "Thumb" kompiliert, dann ändert 
sich der Pfad im obigen Auszug. Aber es gibt immer noch diesen Sprung 
von 0x40000000 auf 0x40000404, was 1kB entspricht...

von scherieh (Gast)


Lesenswert?

ARMdran schrieb:
> Ich habe zum Beispiel im Map file gesehen, dass meine fast 2kB an
> Parametern die eigentlich im Battery buffered RAM liegen sollen, auch im
> SRAM liegen.

"auch"? Oder NUR im SRAM?
Ich vermute das zweite.

> Muss das sein, oder kann man auch direkt aus dem battery buffered RAM
> wie mit SRAM arbeiten?

Vermutlich, ich kenne den LPC nicht.
Eigene Sections für das buffered RAM definieren
und die Variablen entsprechend zuweisen, ähnlich wie das Dein
Linkerscript für das normale RAM macht. Einfach die
RAM Sections duplizieren und Kopie entsprechend umbenennen.
RAM Adressen der Kopie anpassen.

Beachten, dass der Startup Code diese Sections auch geeignet
initialisieren muss.

Für die GNU Binutils gibt es ein schönes Manual, da wird das 
beschrieben.

von ARMdran (Gast)


Lesenswert?

Da muss ich wohl irgendwie alleine durch...

Zumindest etwas weiter bin ich:
1. Der LPC2388 hat doppelt so viel SRAM und ist pinn- und 
funktionskompatiblen, löst damit also mein Problem mit der 
Holzhammermethode
2. Liefert mir der Befehl:
1
arm-elf-nm --size-sort --print-size $(TARGET_OUTPUT).elf
eine nach Größe sortierte Ausgabe der Symbols
3. Damit habe ich dann schnell gesehen, dass mir z.B. ein Font mal eben 
4kB SRAM geklaut hat, weil er nicht "const" war

Was mich noch interessiert:
1. Warum ist die .stack Section auf 13312 Byte fest genagelt?
2. Wie bekomme ich das Parameterarray in den Battery Buffered RAM?
3. Wie nutze ich den Ethernet SRAM als normales RAM bzw. geht das 
überhaupt, wenn ich Ethernet nutzen möchte?
4. Immer noch die Frage: Was werden hier für Zahlen abgezogen?
1
/* Memory Definitions */
2
MEMORY
3
{
4
  ROM (rx) : ORIGIN = 0x00000000, LENGTH = (512k-4k)
5
  RAM (rw) : ORIGIN = 0x40000000, LENGTH = (32k-32)
6
}

von ARMdran (Gast)


Lesenswert?

ARMdran schrieb:
> 1. Warum ist die .stack Section auf 13312 Byte fest genagelt?

Ok, im ganz oben verlinkten File "startup_gnu.S" steht folgendes, was 
13312 Byte ergibt...
1
.equ UND_Stack_Size,     0x00000000
2
.equ SVC_Stack_Size,     0x00000200
3
.equ ABT_Stack_Size,     0x00000000
4
.equ FIQ_Stack_Size,     0x00000000
5
.equ IRQ_Stack_Size,     0x00000A00
6
.equ USR_Stack_Size,     0x00002800
7
8
.equ Stack_Size,        (UND_Stack_Size + SVC_Stack_Size + ABT_Stack_Size + FIQ_Stack_Size + IRQ_Stack_Size + USR_Stack_Size)

Ist das sinnvoll?

von ARMdran (Gast)


Lesenswert?

So, die Lernkurve war steil und ich kann mir jetzt fast alle Fragen 
selbst beantworten:

Zu 2. habe ich herausgefunden, dass mein Array über einen Pointer im 
Battery RAM landet:
1
volatile u32 *Param32Buffer  =(volatile u32 *)(0xE0084000); //RTC-RAM
Direkt dort hin legen konnte ich es jetzt nicht so einfach, da das 
Battery RAM nur einen word-wise (32bit) Zugriff erlaubt.
Das wird bei mir über eine Funktion geregelt.

Ich habe aber mein Array in den USB ram verschoben, da das ungenutzt 
ist.
1
s16 P16[PARAM16_COUNTMAX] __attribute__ ((section (".usbram")));
Dafür habe ich eine neue Section im Linkerscript angelegt.
1
/* Memory Definitions */
2
MEMORY
3
{
4
  ROM (rx) : ORIGIN = 0x00000000, LENGTH = (512k-4k)    /* Flash: 512k - boot code 4kbyte*/
5
  RAM (rw) : ORIGIN = 0x40000000, LENGTH = (32k-32)     /* SRAM: 64k - IAP work 32byte */
6
  /* added 22.03.2013 */
7
  URAM (rw): ORIGIN = 0x7FD00000, LENGTH = (8k)          /* USB RAM: 8k */
8
  //ERAM (rw): ORIGIN = 0x7FE00000, LENGTH = (16k)      /* Ethernet RAM: 16k */
9
  //BRAM (rw): ORIGIN = 0xE0084000, LENGTH = (2k)      /* Battery RAM: 2k */
10
}
Die Kommentare aus einem anderen Linkerscript erklären auch die Zahlen, 
die abgezogen werden. Ob das hier wirklich benötigt wird, ist aber wohl 
eine andere Frage...
Und weiter unten innerhalb von SECTIONS { } kommt dann noch:
1
/* .usbram .etherram and .batteryram added 22.03.2013 */
2
  /* memory space of etherram and batteryram is directly used via pointer in program without section */
3
  .usbram (NOLOAD) :
4
  {
5
      __usbram_start = . ;
6
      __usbram_start__ = . ;
7
      *(.usbram)
8
      . = ALIGN(4);
9
  } > URAM
10
  /*
11
  .etherram (NOLOAD) :
12
  {
13
      __etherram_start = . ;
14
      __etherram_start__ = . ;
15
      *(.etherram)
16
      . = ALIGN(4);
17
  } > ERAM
18
  
19
  .batteryram (NOLOAD) :
20
  {
21
      __batteryram_start = . ;
22
      __batteryram_start__ = . ;
23
      *(.batteryram)
24
      . = ALIGN(4);
25
  } > BRAM
26
  */
Die Sections für Ethernet RAM und Battery RAM habe ich auskommentiert, 
da die Adressbereiche über Pointer angesprochen werden und ich da nichts 
riskieren wollte.

Bleiben noch die Fragen, ob der feste Stack wirklich so groß sein muss 
und ob ein aktiviertes Ethernet oder USB noch irgendwas im 
entsprechenden eigenen Rambereich macht?

von ARMdran (Gast)


Lesenswert?

Damit habe ich jetzt durch die Analyse über 5kB SRAM frei gemacht und 
weiß, dass der Stack massig Platz hat.

Zum Vergleich:

vorher:
1
.data               5720   1073741824
2
.bss               13660   1073747544
3
.stack             13312   1073761208
4
5
= 32692

nachher:
1
.data               1624   1073741824
2
.bss               11836   1073743448
3
.stack             13312   1073755288
4
.usbram             1824   2144337920
5
6
.data + .bb + .stack = 26772

32692 - 26772 = 5920 Byte frei geschaufelt

Dazu sind mir noch einige sehr große Buffer aufgefallen, die ich mir 
noch mal genauer anschauen muss.

Hoffentlich funktioniert das mit dem USB RAM ohne Probleme.
Diese Pointer Zugriffe auf das Ethernet und RTC RAM sind mir auch etwas 
suspekt.

von ARMdran (Gast)


Lesenswert?

ARMdran schrieb:
> .stack             13312   1073761208

Kann mir jemand sagen, ob so eine .stack Section überhaupt standarmäßig 
genutzt wird, oder ob da einfach RAM für den Stack freigehalten wird?

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
Noch kein Account? Hier anmelden.