Forum: Mikrocontroller und Digitale Elektronik Mysteriöser Atmega 2560 Crash bei >128kB


von Christian (Gast)


Lesenswert?

Hallo Zusammen!

Ich verwende einen Atmega 2560 in einem grösseren Projekt 
(Prozessmessgerät für  diverse chemische Parameter). Bisher seit einem 
Jahr lief die Entwicklung ohne grössere Probleme. Der reine Binärcode 
hat jetzt eine Grösse von ca. 136 kB. Als Compiler verwende ich den 
WinAVR/GCC 20070525. Doch auf einmal kommen komische Effekte.:

Beim Dazu-Linken der scanf_float library oder einbinden eines grösseren 
Moduls (5kB) stürzt das Programm an einer bestimmten STelle ab. Das ist 
aber die Stelle der neu eingebundenen Teile. Diese werden da noch 
garnicht angesprochen, also sind diese wohl nicht die (direkte) Ursache 
für den Absturz. Ich hatte diese Teile auch schon mal früher eingebunden 
gahabt, als das ganze Projelt noch kleiner war, und das lief es. Die 
Kompilierung läuft übrigens ohne Probleme, nur zur Laufzeit hängt sich 
das Program auf oder es resettet sich.

Ich habe folgende böse Vermutung:
----------------------------------
Das Problem ist Objektcode, der vom Linker an die 128kB-Grenze im Flash 
allokiert wird. Diese Code hat vielleicht Sprungbefehle, die nicht 
korrekt verarbeitet werden, weil die 128kB-Grenze nicht berücksichtigt 
wird. Wenn der Compiler die Objektdateien erzeugt, kann er ja noch nicht 
wissen, wo der Linker diese mal hinversetzt. Dazu habe ich mir mal das 
Map-File angeschaut. Hier ein Ausschnitt daraus:

                0x0001feda                srand
 .text          0x0001fef0      0x1b0     libc.a(ftoa_engine.o)
                0x0001fef0                __ftoa_engine
 .text          0x000200a0        0xe     libc.a(strcpy_P.o)
                0x000200a0                strcpy_P

Das sieht man das die wohl wichtige Formatierungsfunktion 'ftoa_engine' 
genau auf die 128kB-Grenze gelinkt wird. Wenn in dieser Funktion nun 
SPrungbefehle drin sind, dann springt das Programm an eine völlig 
falsche Stelle, weil der Wechsel zu den oberen 128kB nicht 
berücksichtigt wird. --> Absturz. Mit den Standard-16Bit Pointern des 
GCC lassen sich nur 128kB direkt adressieren.
Ein verwandtes Problem ist übrigens die Warnung vor den 'Linker Stubs'.

Meine Frage No.1: Weiss jemand eine  Lösung zu dem Problem?
-----------------------------------------------------------

Ich habe auch schon einen Lösungsansatz: Man müsste die Linker sagen, 
dass er irgendwas unbedeutendes an die 128kB-Grenze linken sollte, z.B. 
ein paar Dummy-Bytes, und den übrigen Code drumherum. Nur wie stelle ich 
das an?
Ich habe mich schon etwas mit Linkerskripten beschäftigt. Die Sektion 
.text beinhaltet alle Funktionen des Programms. Diese geht bei mir auch 
bis ca 136kB. Ich habe mit Linkerskripten geschafft, Objekte oder Bytes 
VOR oder NACH .text einzubauen. Aber ich brauche das Dummy-Objekt bei 
128kB - INMITTEN des .text Codes.

Meine Frage No.2: Wie geht das? oder geht das überhaupt?
----------------------------------------------------------

Ich habe ein kleines Testprojekt aufgesetzt um das zu prüfen. Hier ein 
Ausschnitt aus dem Linkerskript: (basierend auf avr6.x) Geht sowas?

  .text :
  {
   ........(gekürzt)

    *(.text)
    . = ALIGN(2);
    *(.text.*)
    . = ALIGN(2);

  . = 0x0110;
  dummy.o

    *(.text)
    . = ALIGN(2);
    *(.text.*)
    . = ALIGN(2);

    ........(gekürzt)
  }  > text

Ich will das Objekt Dummy.o in mitten des sonstigen COdes an einer 
festen Adresse unberbringen. Wenn ich die Adresse von Dummy innerhalb 
des Codebereich setze, kommt die Fehlermeldung:
ld_skript.x:305 cannot move location counter backwards (from 00000130 to 
00000110)

Logisch eigentlich. Aber was kann ich tun, um ein Code-Objekt an eine 
feste Stelle innerhalb von .text zu linken?

Ich wende mich an Euch, da ich trotz tagelangem Suchen und Probieren 
nichts gefunden habe. Vielleicht habe Ihr eine Ahnung. Danke schon 
mal...

Schönen Gruß
Christian aus Berlin

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.