www.mikrocontroller.net

Forum: Compiler & IDEs ATmega2561 Problem mit WinAVR


Autor: Maik Scholz (maikscholz)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
ich möchte ethernut auf einen ATmega2561 laufen lassen.
Wenn ich ca. 100kByte code übersetzte und linke ist alles
ok.
Wenn ich aber den Code vergrößere (~200kB), dann bekomme
ich sehr viele Linker Warnungen wie:
  C:/subver/homenet/sw/ethernut/nut/crt/vfprintf.c:65: warning: internal
    error: out of range error
  C:/subver/homenet/sw/ethernut/nut/crt/vfprintf.c:65: warning: internal
    error: out of range error

Was kann ich dagegen unternehmen?

Der Linkeraufruf:
avr-gcc -x assembler-with-cpp -c -mmcu=atmega2561 
-Wa,-amhls=strstr_P.lst -DETHERNUT1 -DARTHERNET1 -D__HARVARD_ARCH__ 
-DARTHERCPLDSPI=0x1200 -DARTHERCPLDSTART=0x1100 -Os -gdwarf-2 strstr_P.S 
-o strstr_P.o
avr-gcc main.o http/httpserv.o can/canserv.o can/can.o can/mcp2515.o 
adc/adc.o pwr/powersupply.o db/sqlite3.o strstr_P.o  -mmcu=atmega2561 
-Wl,--defsym=main=0,-Map=homeserver.map,--cref 
-Lc:\subver/homenet/sw/app/station/nutbld 
-Wl,--section-start=.bootldrinfo=0x3eff8 -Wl,--start-group 
c:\subver/homenet/sw/app/station/nutbld/nutinit.o -lnutpro -lnutos 
-lnutarch -lnutdev -lnutarch -lnutnet -lnutfs -lnutcrt -lm 
-Wl,--end-group -o homeserver.elf

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Maik Scholz wrote:

>   C:/subver/homenet/sw/ethernut/nut/crt/vfprintf.c:65: warning: internal
>     error: out of range error
>   C:/subver/homenet/sw/ethernut/nut/crt/vfprintf.c:65: warning: internal
>     error: out of range error
>
> Was kann ich dagegen unternehmen?

Vielleicht als allererstes mal gucken, was da auf Zeile 65 steht?

Ich fürchte, Ethernut macht hier irgendwas, was man eher nicht tun
sollte.

Autor: Harald Kipp (Firma: egnite GmbH) (haraldkipp) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Möglicherweise liegt es an der Übergabe eines Function pointers als 
Parameter. Dann hilft es evtl., wenn man im Makefile die LIBS Einträge 
anders anordnet.

Autor: Gunter Weisbrod (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
"Möglicherweise liegt es an der Übergabe eines Function pointers als
Parameter."

Jau!
Tatsächlich scheint der gcc-Compiler / Assembler ein Problem mit der 
Unterscheidung von pointern auf Funktionen (word) und flash-Daten 
(bytes) zu haben. Den 'internal error: out of range error' gibt es daher 
auch, wenn man eine ungerade(!) Anzahl Datenbytes im .text-Segment.
Abhilfe: Daten im .progmem -Segment plazieren.

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Gunter Weisbrod wrote:

> Den 'internal error: out of range error' gibt es daher
> auch, wenn man eine ungerade(!) Anzahl Datenbytes im .text-Segment.
> Abhilfe: Daten im .progmem -Segment plazieren.

Ja klar.  Eine ungerade Anzahl von Datenbytes in .text ist schlicht
nicht zulässig.  Warum kommt man auch auf so'ne Idee?  Der Compiler
selbst macht das ja nicht...  Genau dafür ist ja progmem da, dort
kümmert sich der Linkerscript nötigenfalls um das Padding.  Der
zweite Vorteil ist, dass progmem immer vor dem eigentlichen text
platziert wird, damit es (nach Möglichkeit) unterhalb der 64-KiB-
Grenze landet, innerhalb derer man mit den diversen _P-Funktionen
auf die Flash-Daten zugreifen kann.  Oberhalb 64 KiB muss man dann
umständlich manuell mit den pgm_..._far()-Funktionen arbeiten.

Autor: Harald Kipp (Firma: egnite GmbH) (haraldkipp) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn der Compiler das nicht macht, wäre die Frage: Wie bekommt man das 
dann hin?

Wie viele Bytes im Text Segment sind, ist aber doch eigentlich 
belanglos. Wichtig ist lediglich, dass alle Elemente auf Wortgrenzen 
beginnen, oder?

Noch als Info: Nut/OS verwendet, wenn es für AVR gebaut wird, die Linker 
Skripts von avrlibc. Explizite .text Segmente werden nur für den 
ImageCraft Compiler definiert, beim avr-gcc beschränken wir uns auf 
pgmspace.h. Also kein Voodoo oder andere Tricks, bis auf die für's 
Multithreading nötigen Stack-Manipulationen. Die o.g. Routine ist 
übrigens klein:

 int vfprintf(FILE * stream, CONST char *fmt, va_list ap)
 {
   return _putf(_write, stream->iob_fd, fmt, ap);
 }

Als Problem vermutete ich, dass der erste Parameter, ein 
Funktionspointer auf die _write() Routine (ganz normale stdio _write 
Funktion, aber nicht aus avrlibc) das Problem verursacht.

Die Geschichte mit ungeraden Bytes im .text Segment hat mich jetzt 
irgendwie verunsichert. @Gunter: Woraus schließt Du das? Map File? Wenn 
ja, wleches Modul?

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Harald Kipp wrote:

> Wenn der Compiler das nicht macht, wäre die Frage: Wie bekommt man das
> dann hin?

Der Compiler packt normalerweise nach .text nur generierten Code,
keine Konstanten.  Da beim AVR alle Befehle Vielfache von 16 Bits
lang sind, kann dabei immer nur eine gerade Zahl von Bytes
entstehen.

Wo ggf. die ungerade Zahl herkommt, musst du dir schon selbst
ansehen.  Die Vermutung liegt nahe, dass es irgendwie mit NutOS
zu tun haben könnte, denn ich habe ansonsten noch nie eine
derartige Fehlermeldung berichtet gehört.

> Die o.g. Routine ist
> übrigens klein:
>
>  int vfprintf(FILE * stream, CONST char *fmt, va_list ap)
>  {
>    return _putf(_write, stream->iob_fd, fmt, ap);
>  }

Das kann gut und gern schief gehen.  NutOS hat formal kein Recht,
Teile der normalen C-Bibliothek (mit den dort standardisierten
Namen) neu zu implementieren.  Der C-Standard verbietet dies
ausdrücklich und gibt gleichzeitig dem Compiler damit die Möglich-
keit, sein internes Wissen darüber, was die Funktionen der
Standardbibliothek machen, für Optimierungen zu nutzen.

Autor: Jens Berkemeyer (kaeptnahab)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Zusammen,

auch ich habe Probleme von ATmega128 auf 2561 zu gehen.
Mit Optimierungen (-Os/-O2) ist alles ok.

mit Optimierung (-O1) nicht mehr Warnings, aaaber Funktionspointereien 
scheinen schief zu gehen,

ohne Optimierung (-O0) plötzlich knapp 400 Warnings, z.B.:

(.text+0x4): warning: internal error: out of range error
c:/user/tools/winavr20090313/bin/../lib/gcc/avr/4.3.2/../../../../avr/li 
b/avr6\libc.a(sprintf.o):  In function `sprintf':

oder

menucfg.o:(.progmem.data+0x3d48): warning: internal error: out of range 
error

Eigentlich hatte ich ja gehofft, mit dem CPU-Wechsel mehr als 128k 
nutzen zu können, aber so einfach scheints ja nicht zu gehen.
Was gibts denn da als Lösung oder workaround?

CU
KäptnAhab

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.