AVR-gcc kennt keine Adresslimits?

Gast #5220031
Lesenswert?

Ähm gerade fällt mir zum ersten Mal auf, daß mein avr-gcc munter 
Fantasieadressen über die RAM-Grenzen hinaus produziert. Man merkts nur 
daran, daß das Programm dann nicht so toll läuft.

Blöde Frage aber ist das normal, daß man da selbst aufpassen muß, daß 
die data+bss-sections nicht größer als der vorhandene RAM des AVR 
werden?

Ich meine bei Überschreiten der text-section meckern ja sowohl avr-gcc 
wie auch avrdude aber beim RAM nix? Jetzt bin ich leicht verwirrt.

Aus dem .sym beim ATmega328p:
00800100 D __data_start
...
00800923 B __bss_end
00800923 B _end
Moderator Persönliche Seite #5220148
Lesenswert?

batman schrieb:
> oder läßt sich der Linker bei der Adressvergabe nicht reinreden?

Weder Compiler noch Linker lassen sich durch irgendeine Anordnung
von irgendwas innerhalb deines Quelltextes beeindrucken.

Du kannst natürlich im Linker eine Guard-Variable explizit hinter dem
Rest platzieren, indem du sie im Compiler in eine eigene Section
packst und im Linkerscript dann arrangierst, dass genau diese Section
am Ende des statisch allozierten RAMs liegt.
Gast #5220153
Lesenswert?

Kann man die RAM-Größe nicht im Linker-Script angeben? Genau wie die 
Größe des Flash? Mit dem arm-gcc geht's hier ungefähr so:
1
MEMORY
2
{  
3
   flash_boot    (rx) : ORIGIN = 0x08000000, LENGTH = 16K
4
   flash_display (rx) : ORIGIN = 0x08008000, LENGTH = 24K
5
   
6
   ram_boot      (rw) : ORIGIN = 0x2001c000, LENGTH = 1K
7
   ram_display   (rw) : ORIGIN = 0x2001f000, LENGTH = 2K
8
}
9

10
SECTIONS
11
{
12
  .text : ALIGN(16) SUBALIGN(16) {
13
     FILL (0xff)
14
     *(.text)
15
     *(.text.*)
16
     *(.rodata)
17
     *(.rodata.*)
18
     *(.gcc*)
19
     . = ALIGN(4);
20
text_end = .;
21
  } > flash_display
22

23
  .stack : {
24
stack = .;
25
    . += 768;
26
tos = .;
27
  } > ram_display
28

29
  .data : ALIGN(4) SUBALIGN(4) {
30
data_start = .;
31
     *(.data)
32
     *(.data*)
33
data_end = .;
34
  } > ram_display AT > flash_display
35

36
  .bss : ALIGN(4) SUBALIGN(4) {
37
bss_start = .;
38
     *(COMMON)
39
     *(.bss)
40
     *(.bss*)
41
bss_end = .;
42
  } > ram_display
43
}

Vielleicht funktioniert es deshalb, weil ich den Stack an den Anfang 
lege?
Moderator Persönliche Seite #5220159
Lesenswert?

eagle user schrieb:
> Kann man die RAM-Größe nicht im Linker-Script angeben?

Natürlich kann man.  AVR-GCC ist aber deutlich mehr „out of the box“
als ARM-GCC; einen Linkerscript gibt man dort daher normalerweise
nicht selbst an.  Die generischen Linkerscripts funktionieren gut
genug im Zusammenspiel mit dem Startup-Code der avr-libc, als dass
man das alles direkt benutzen kann.  Diese generischen Linkerscripts
sind aber eben, wie ich eingangs schrieb, nicht pro Device vorhanden,
sondern nur grob klassifiziert für jede eigene AVR-Klasse.

Gegen das genannte Problem der Kollision des Stacks mit den statisch
zugewiesenen Daten würde der Linkerscript ohnehin nicht helfen.  Es
bleibt damit immer beim Programmierer abzuschätzen, ob der nach dem
Linken vorhandene freie RAM aller Wahrscheinlichkeit nach ausreichend
für den Stack sein wird.
Gast #5220167
Lesenswert?

Absolut richtig. Ich hätte das Problem nur einen Tag früher erkannt, 
wenn es eine RAM-Overflow-Warnung gegeben hätte. Einen Overflow des (wg. 
RTOS) minimalen main-Stacks hatte ich nicht auf dem Schirm.
Moderator Persönliche Seite #5220182
Lesenswert?

batman schrieb:
> wenn es eine RAM-Overflow-Warnung gegeben hätte

Daher gab's bei WinAVR immer noch so einen Script, der nach dem
Compilieren den Füllstand der Speicher in % ausgegeben hat.  Hat
Eric Weddington dann als schrägen Hack ins "size"-Programm hinein
gelegt, aber es war von vornherein klar, dass dieser rein
AVR-spezifische Hack es niemals hätte (in dieser Form) in die Binutils
zurück gemacht.

Die Shellscript-Variante bliebe natürlich nach wie vor.

Vorteil ist, dass man auch die Sache mit dem Stack dann schnell
abschätzen lernt.
Persönliche Seite #5220417
Lesenswert?

Jörg W. schrieb:

Und wozu ist das ganze Geraffel dann gut, dass crt.o nach .note.gnu.avr 
packt?
1
    .section .note.gnu.avr.deviceinfo, "", @note
2
#define NOTE_NAME "AVR"
3
#ifdef __AVR_DEVICE_NAME__
4
    #define DEVICE_NAME STR(__AVR_DEVICE_NAME__)
5
#else
6
    #define DEVICE_NAME ""
7
#endif
8

9
    .long .L__note_name_end - .L__note_name_start
10
    .long .L__desc_end - .L__desc_start
11
    .long 1 ; Type 1 - this is the only known note type for AVR.
12
.L__note_name_start:
13
    .asciz NOTE_NAME
14
    .balign 4
15
.L__note_name_end:
16
.L__desc_start:
17
#ifdef FLASHSTART
18
    .long FLASHSTART
19
#else
20
    .long 0
21
#endif
22
#ifdef PROGMEM_SIZE
23
    .long PROGMEM_SIZE
24
#elif FLASHEND > 0
25
    .long FLASHEND + 1
26
#else
27
    .long FLASHEND
28
#endif
29
    .long RAMSTART
30
#ifdef RAMSIZE
31
    .long RAMSIZE
32
#elif RAMEND > 0
33
    .long RAMEND - RAMSTART + 1
34
#else
35
    .long RAMEND
36
#endif
37
#ifdef E2START
38
    .long E2START
39
#else
40
    .long 0
41
#endif
42
#ifdef EEPROM_SIZE
43
    .long EEPROM_SIZE
44
#elif E2END > 0
45
    .long E2END + 1
46
#else
47
    .long E2END
48
#endif
49
    /* String offsets table.
50
    Index 0 - Size of offset table in bytes
51
    Index 1 - Device name byte offset
52
    */
53
.L__stroffsettab_start:
54
.long .L__stroffsettab_end - .L__stroffsettab_start /* Size of index table in bytes */
55
.long .L__device_name_start - .L__strtab_start /* Byte offset of device name */
56
.L__stroffsettab_end:
57
    /* String table for storing arbitrary strings.
58
    Offsets are stored in the string offset table above */
59
.L__strtab_start:
60
    .byte 0
61
.L__device_name_start:
62
    .asciz DEVICE_NAME
63
.L__device_name_end:
64
    .byte 0

Aus: 
http://svn.savannah.nongnu.org/viewvc/avr-libc/trunk/avr-libc/crt1/gcrt1.S?view=markup

Ich hätte gedacht, dass dass ganau dafür eingeführt wurde?  Immerhin ist 
nie erforderliche Info da.
Gast #5220813
Lesenswert?

Die aktuelleln Versionen vom AtmelStudio geben immer noch einen Meldung 
aus:
1
        Program Memory Usage   :  140188 bytes   13,4 % Full
2
        Data Memory Usage     :  74200 bytes   56,6 % Full

Im automatisch genereierten Makefile kann man aber keinen Aufruf dafür 
erkennen.
Weiß jemand wie das funktioniert? Ich würde die Ausgabe gerne in meinen 
manuellen MakeFiles einbauen
Gast #5220843
Lesenswert?

Aber immer schon dran denken, dass avr-size nur den Speicherbedarf für 
statische Variablen berücksichtigt. Der Stack und dynamischer Speicher 
sind nicht mit drin. Ich würde daher stets dafür sorgen, dass mindestens 
64 Bytes frei bleiben. Wenn man printf benutzt, dann mindestens 100 
Bytes.
Gast #5220868
Lesenswert?

Hi,

aber man kann sich doch beliebige neue Speicherklassen im Linkerfile 
erzeugen, explizit seine Variablem lokatieren und diese Klassen auf 
Grösse überwachen. Dann spukt der Linker die entsprechenden Fehler 
aus...
1
  .calram (NOLOAD) :
2
  {
3
     PROVIDE (__calram_start = .) ;
4
    *(.calram*)
5
     PROVIDE (__calram_end = .) ;
6
  } > data
7
  .data    : AT (ADDR (.text) + SIZEOF (.text))
8
  {
9
     PROVIDE (__data_start = .) ;
10
    *(.data)
11
    *(.data*)
12
    *(.rodata)  /* We need to include .rodata here if gcc is used */
13
    *(.rodata*) /* with -fdata-sections.  */
14
    *(.gnu.linkonce.d*)
15
    . = ALIGN(2);
16
     _edata = . ;
17
     PROVIDE (__data_end = .) ;
18
  }  > data
19
  ASSERT((ADDR(.calram) + SIZEOF(.calram)) <= ADDR(.data), ".calram exceeds page size")

Grüße
Moderator Persönliche Seite #5220876
Lesenswert?

adkfsgksadf@gmx.de schrieb:

> aber man kann sich doch beliebige neue Speicherklassen im Linkerfile
> erzeugen,

Klar kann man das.  Aber nochmal: „normale“ AVR-Nutzer mögen sich
eher nicht um den Linkerscript kümmern, denn der, der mit der
Toolchain mitkommt, deckt einen Großteil der Bedürfnisse ab.

Wie schon ausreichend dargelegt worden ist, muss man sowieso extern
den Speicherfüllstand im Blick behalten, damit man ausreichend
Reserve für den Stack hat.  (Der Heap gibt sich selbst Mühe, immer
noch genügend Abstand zum Stack als Reserve zu haben.)

> Dann spukt der Linker die entsprechenden Fehler
> aus...

Na, hoffentlich spukt er nicht … Halloween ist ja schon vorbei. :)
Beitrag #5220899 wurde von einem Moderator gelöscht.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren