Hat AVR-GCC Probleme mit grossen Dateien?

Hallo zusammen!

Sind beim AVR-GCC Probleme mit großen Dateien (>2.500 Zeilen Code) bekannt? Ich bin im Moment an einem Punkt, wo ich eine Quelldatei nicht mehr kompilieren kann, wenn weiterer Code hinzukommt. Wenn man dann andere Teile auskommentiert, geht es wieder. Die Datei läßt sich aber auch nicht ohne weiteres aufsplitten, weil sie im Wesentlichen eine komplexe Menüstruktur enthält.

Ich arbeite mit der Version von 20050214 (GCC 3.4.3).

Die Fehlermeldungen, die dabei auftauchen, sehen aber so aus, als wäre der Compiler schon durch und die Probleme würden beim Assemblieren auftauchen:

"make.exe" all avr-gcc -g -O1 -Wall -Wstrict-prototypes -Wa,-ahlms=main.lst

-mmcu=atmega128 -c -o main.o main.c In file included from main.c:37: menu.c: In function `menu_automatik': menu.c:407: warning: 'x' might be used uninitialized in this function menu.c:407: warning: 'y' might be used uninitialized in this function C:\DOKUME~1\ost_dri\LOCALS~1\Temp/cc8qaaaa.s: Assembler messages: C:\DOKUME~1\ost_dri\LOCALS~1\Temp/cc8qaaaa.s:57758: Error: value of

66300 too large for field of 2 bytes at 16 C:\DOKUME~1\ost_dri\LOCALS~1\Temp/cc8qaaaa.s:65751: Error: value of 65848 too large for field of 2 bytes at 10227 C:\DOKUME~1\ost_dri\LOCALS~1\Temp/cc8qaaaa.s:65769: Error: value of 65848 too large for field of 2 bytes at 10247 ... C:\DOKUME~1\ost_dri\LOCALS~1\Temp/cc8qaaaa.s:72333: Error: value of 66300 too large for field of 2 bytes at 14 make.exe: *** [main.o] Error 1
Process Exit Code: 2

Gruß Thorsten

Reply to
Thorsten Ostermann
Loading thread data ...

Thorsten Ostermann schrieb:

Das sieht aus wie z.B. ein Sprungbefehl, der nur in einem Bereich von 64 kB zulässig ist, verbunden mit einem Überschreiten dieser Grenze durch die Menüstruktur. Das sieht nicht nach einem Fehler des Compilers aus, oder einer zu großen Quelldatei. Also mal nachsehen, wie groß die übersetzte Menüstruktur wird und wie die Verzweigungen realisiert sind. Vielleicht muß die Menüstruktur in Blöcke aufgeteilt werden, die innerhalb von 64k-Grenzen liegen.

Gruß,

Ed

Reply to
Edzard Egberts

Hallo Edzard!

OK, ich sehe mir das mal an. Aber eigentlich sollte der Compiler doch selbst wissen, mit welchen Sprungbefehlen er wie weit springen kann, oder?

Gruß Thorsten

Reply to
Thorsten Ostermann

^^^ Ist der Fehler ohne Optimierung (-O0) immer noch da?

Micha

Reply to
Michael Baeuerle

Thorsten Ostermann schrieb:

Ja, das "weiß" er und deshalb gibt er einen Fehler aus, wenn der verwendete Befehl nicht passt. Der Programmierer muß wissen, welcher Befehl für welchen Bereich benötigt wird - dass der Compiler anfängt, selber Befehle auszutauschen, will man eigentlich nicht. In meinen Augen hängt hier alles davon ab, wie genau das Menü programmiert ist und welche Grenzen der Erweiterung vorgesehen sind, > 2500 Zeilen Code für eine Menüstruktur erscheint mir schon recht groß. Aber ohne den Code zu sehen, kann man nur raten "sieht so aus".

Gruß,

Ed

Reply to
Edzard Egberts

Er weiß aber möglicherweise nicht, wie groß die Befehle sind.

AVR kenne ich jetzt nicht, aber manche Architekturen haben eben Sprung- befehle, die nur eine bestimmte Entfernung weit kommen. Für größere Entfernungen muss man die Zieladresse explizit in ein Register laden, und das ist natürlich eine aufwändigere, längere Codesequenz. Die Info- seite von diesem Cygwin-gcc hier nennt z.B. für M32R entsprechende Optionen (-mmodel=...) und Attribute.

Du kannst natürlich auch einfach mal mit -S Assemblercode erzeugen und nachsehen, was er an der angemeckerten Stelle eigentlich will.

Stefan

Reply to
Stefan Reuther

Der Atmega 128 hat nur 64k x 16 Flash. Vielleicht ist das Programm einfach nur zu groß für den Chip?

Reply to
Andreas Koch

Praktisch alle derzeit relevanten Architekturen kennen verschieden große absolute und zusätzlich noch verschieden große relative Sprünge.

Ein Compiler, der vorgibt, für ein gegebenes Zielsystem Code erzeugen zu können, sollte nicht nur alle Varianten kennen, sondern auch noch die jeweils "optimale" wählen können. ("optimal" ist deshalb in Anführungsstrichen gesetzt, weil es mindestens zwei Optimierungsrichtungen gibt: Codegröße und Laufzeiteffizienz. Nicht immer ist der kürzere Befehl auch der schnellere)

Ein Compiler, der das nicht im vollen Umfang beherrscht, ist jedenfalls unbrauchbarer Vollschrott. Denn er fügt der Komplexität der Wahlmöglichkeiten für die Instruktionen die Unwägbarkeit seiner eigenen Idiotie hinzu (vielmehr diejenige seiner inkompetenten Entwickler).

Dann lieber gleich Assembler. Deshalb ist das auch meine bevorzugte Sprache. Jedenfalls für µC-Programmierung.

Reply to
Heiko Nocon

Auf x86 hast du "jmp ZIELADRESSE" mit 5 Bytes, und kannst damit den kompletten 4G-Adressraum ansprechen. Der Assembler kann optional eine kürzere Version mit 2 Bytes einsetzen, muss aber nicht.

Wenn du aber mit "jmp ADRESSE" nur bspw. 64k oder 16M weit kommst, musst du alles darüber hinaus umständlicher codieren, z.B. la $v0, ADRESSE jr $v0 (müsste MIPS-Syntax sein). Der Compiler weiß halt einfach nicht, ob ein normaler Sprung reicht, und will nicht immer die ineffiziente Variante wählen. Also wählt er die effiziente, die meistens reicht. So großer Code doch eher selten, oder? Ich würde jedenfalls erwarten, dass, wenn dies das Problem ist, es eine Option zum Umschalten auf die umständliche Version gibt.

Stefan

Reply to
Stefan Reuther

Thorsten Ostermann schrieb:

Übersetz das Ganze doch mal in die zugehörige Assemblerdatei (-c durch

-S ersetzen) und schau nach, was in den entsprechenden Zeilen denn an Code steht.

--
cheers, J"org               .-.-.   --... ...--   -.. .  DL8DTL

http://www.sax.de/~joerg/                        NIC: JW11-RIPE
Never trust an operating system you don't have sources for. ;-)
Reply to
Joerg Wunsch

Heiko Nocon schrieb:

Ich stimme Dir zu, aber genau in den letzten Klammern steht die Sache, die mich da unsicher gemacht hat: Der OP hat scheinbar eine fertige Menüstruktur verwendet, z.B. aus irgendeiner Bibliothek. Da kann dann durchaus eine "Optimierung" vorhanden sein, die dem Compiler eine eigene Optimierung verwehrt. Im Moment würde ich aber darauf tippen, dass der Beitrag vom Andreas das Rätsel löst - das Programm ist wahrscheinlich zu groß für den vorhandenen Adressraum, da bleibt dem Compiler sowieso nur die Möglichkeit einer Fehlermeldung.

Gruß,

Ed

Reply to
Edzard Egberts

Hallo Andreas!

Kann ich mir eigentlich nicht vorstellen, aber ausschließen kann ich es auch nicht.

avr-size --target=binary main.bin spuckt mir nach erfolgreicher Kompilierung 77222 für data aus. Sind das jetzt Bytes oder Words? Soviel ist jetzt nicht auskommentiert, dass das Binary auf 128kB anwachsen würde.

Gruß Thorsten

Reply to
Thorsten Ostermann

Thorsten Ostermann schrieb:

Was soll ein Word denn sein? 8 bits (ist ja eine 8-bit-CPU), 16 bits (weil der ROM für Befehlslesezugriffe so organisiert ist -- Datenlesezugriffe kann er 8-bittig ausführen), 32 bits (weil das die native word size der derzeit meisten PCs auf dieser Welt ist) oder 64 bits (weil das die größte gängige word size ist)?

Es sind also Bytes, alles andere hat für portable Tools keinen Sinn.

Was du dabei einfach komplett ignoriert hast: diese Zahl da oben bezieht sich auf das *Daten*segment, also den RAM. Der kann, selbst wenn man externen RAM anstöpselt, immer nur weniger als 64 KiB fassen.

Du hast also die 4 KiB RAM deines ATmega128 bereits x-fach überbelegt...

(Außerdem bedeutet data, dass es sich um initialisierte Daten handelt, die brauchen also nochmal gleichermaßen viel ROM dazu, um die initializer unterzubringen.)

Mir scheint, du solltest dich mal mit der Organisation deiner Datenmengen im progmem befassen. Aber selbst da gilt für AVR-GCC, dass er derzeit nur < 64 KiB verwalten kann, wenn man die diversen ..._P()-Funktionen nehmen möchte, da diese kein RAMPZ verwalten (die Zeiger sind einfach nur 16 bit groß, sie wüssten also nicht, woher sie die Information nehmen sollen, dass RAMPZ jetzt angefasst werden muss).

--
Jörg Wunsch

"Verwende Perl. Shell will man können, dann aber nicht verwenden."
				Kristian Köhntopp, de.comp.os.unix.misc
Reply to
Joerg Wunsch

Hallo Thorsten,

so richtig habe ich das auch noch nicht verstanden, wie AVR-GCC neben dem reinen Speicher des Prozessors in der Gr=F6=DFe beschr=E4nkt ist. Nat=FCrlich beschr=E4nkt dein =B5C mit seinem Speicher die Gr=F6=DFe des Daten- und Programmspeichers. Wenn die voll sind, kann der Prozessor einfach nicht mehr leisten. Das steht jetzt nicht in direktem Bezug zur Zeilenanzahl, sondern was dann wie belegt wird. Ich habe um die 2.000 Zeilen Code mit AVR-GCC f=FCr den Atmega32 noch kompilieren k=F6nnen. Ein Bekannter sch=E4tzt die H=F6chstgrenze an Codezeilen auf 32.000 ab. Das sind jetzt auch nur ungef=E4hre Angaben, aber mal ne Hausnummer.

Gru=DF,

Uwe

Thorsten Ostermann schrieb:

Reply to
Uwe Stickelmann

s

Code ist halt nicht gleich Code. Wenn der im wesentlichen aus Variablen- Deklarationen und -initialisierung besteht, weil irgendwelche gigantische statische Strukturen abgebildet werden sollen (und "komplexe Menustruktur= ", wom=F6glich noch ungeschickt abgelegt h=F6rt sich danach an), ist halt ir= gendwannmal Tuck. Code, der vor allem in Maschineninstruktionen umgesetzt wird, erzeu= gt=20 dann halt viel weniger pro Quellcode-Zeile.

Martin

Reply to
martin

Hallo Joerg!

Im Zweifelsfall 16 bit, weil die Befehle beim AVR ja 2 Byte breit sind?! OK, also sind es Bytes. Das sollte also noch ins Flash passen...

Ich habe externes RAM angeschlossen. Das sind insgesamt 256kB, die in mehrere Bänke aufgeteilt sind. Allerdings sollte der Code nicht im RAM landen.

Das hatte mich auch schon gewundert, aber für "program" gibt es keine extra Angabe: text=0, data=77222, bss=0, dec=77222, hex=12da6

Gerne, aber dafür müßte ich erstmal wissen, welche Daten wo landen. Leider habe ich den zugrunde liegenden Code nicht selbst erstellt und kann daher an einigen Stellen nur raten :(

Gruß Thorsten

Reply to
Thorsten Ostermann

Es geht nicht darum, was du angeschlossen hast. Der reguläre Daten- Addressraum ist 16 Bit. Damit kann dein Datensegment maximal 64KB groß werden. Punkt.

Das heißt auch nicht "program", sondern "text". Ganz offensichtlich enthält deine Quelldatei nicht ein einziges Bit Code, sondern lediglich globale Variablendefinitionen.

Die Initialisierung des Datensegments (vulgo: Kopieren aus dem Flash ins RAM) macht das CRT (C RunTime) Modul, das ist das crtXXXX.o, das zu allen deinen Programmen dazu gelinkt wird.

Da die Gesamtgröße des Datensegments und die dafür bestimmten Daten erst beim Linken feststehen, erzeugt auch erst der Linker die Kopie der Daten die ins Flash kommen.

Das ist schlecht. Du hast aber nur diese zwei Möglichkeiten. Entweder den ganzen Kram soweit verstehen, daß du das unter 64KB drücken kannst oder einen größeren Prozessor nehmen.

XL

Reply to
Axel Schwenke

Hallo Axel!

Das ist klar. Das RAM ist ja auch nur für DATEN da, deswegen schrieb ich, dass ich es in Bänken organisiert habe (die dann im Programm gezielt umgeschaltet werden).

Hmm, kann ich mir nicht vorstellen, immherin ist es ausführtbar. Allerdings wird das File auch über einen speziellen Bootloader auf den uC geschoben. Ich muss mich wohl doch nochmal mit dem Autor des Codes zusammensetzen...

Tut mir leid, aber hier kann ich dir nichtmehr ganz folgen. Der Code sollte eigentlich überhauptkeine Daten enthalten, wenn überhaupt dann nicht mehr als max. 1kB.

Wie gesagt, dass File mit den 77222 Bytes Data ist lauffähig. Erst wenn mehr Code dazukommt, wird es zuviel.

Gruß Thorsten

Reply to
Thorsten Ostermann

Thorsten Ostermann schrieb:

Argl. Jetzt erst fällt mir dein Fehler auf. Aus dem reinen Binärimage kann das avr-size-Kommando natürlich beim besten Willen nicht mehr ermitteln, zu welchem Segment die Bytes nun gehören, daher wird alles als "data" bezeichnet.

Mach das mal bitte auf dem ELF-File, aus dem du das .bin generierst.

--
cheers, J"org               .-.-.   --... ...--   -.. .  DL8DTL

http://www.sax.de/~joerg/                        NIC: JW11-RIPE
Never trust an operating system you don't have sources for. ;-)
Reply to
Joerg Wunsch

"Uwe Stickelmann" schrieb:

Finger in die Luft gehalten?

Ich wüsste nicht, warum es eine Zeilenzahlgrenze irgendwie geben sollte... Entscheidend ist wirklich nur die endgültige Speicherbelegung des Compilats. Ansonsten haben GCCs auf dieser Welt wohl bereits Projekte mit sehr viel größerer Gesamtzeilenzahl an Quellcode zu verarbeiten gehabt.

--
cheers, J"org               .-.-.   --... ...--   -.. .  DL8DTL

http://www.sax.de/~joerg/                        NIC: JW11-RIPE
Never trust an operating system you don't have sources for. ;-)
Reply to
Joerg Wunsch

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.