PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : relocation truncated to fit



Bumbum
12.12.2012, 11:05
Hallo,

ich habe ein seltsames Problem und kann es mir nicht erklären. Folgender Code:



#define MSG_off 9
//...
void LCD_Text_EEPROM (U16 Offset)
{
U8 Zeichen = eeprom_read_byte ((uint8_t *)(uint16_t)Offset);
while (Zeichen != 0)
{
LCD_Zeichen (Zeichen);
Offset++;
Zeichen = eeprom_read_byte ((uint8_t *)(uint16_t)Offset);
}
}
//...
void LCDMsg (U8 Msg)
{
U16 Addr = Msg<<4;
LCD_Text_EEPROM (Addr);
}
//...
int main (void)
//...
switch (GSM_Status)
{
case 0: { LCDMsg (MSG_off);
//...


Wenn ich das compiliere erhalte ich als Fehlermeldung: P:\AVR\test.c:1186: relocation truncated to fit: R_AVR_7_PCREL against `no symbol'
Zeile 1186 ist dabei die switch-Zeile.

Bei Google habe ich herausgefunden, dass es was mit der Reihenfolge der eingebundenen Bibliotheken zu tun haben könnte. Die Funktionen LCD_Text_EEPROM und LCD_Zeichen sind tatsächlich in einer externen Bib. Aber egal an welche Reihenfolge ich diese Bib einbinde, der Fehler bleibt. Seltsam ist dass das Programm fehlerfrei compiliert wird und läuft, wenn ich die Zeile LCDMsg (MSG_off); auskommentiere. Seltsamerweise sind davor und danach aber auch aufrufe von LCDMsg. Es scheint nur ein Problem an dieser einen Stelle zu geben. Wie komme ich dem Problem auf die Schliche?

Viele Grüße
Andreas

PicNick
13.12.2012, 08:37
Du, mit den geschweiften Klammern im "int main()" komm' ich nicht klar ?

Bumbum
13.12.2012, 14:22
Hallo PicNick,

die int main besteht mittlerweilse aus fast 500 Zeilen. Ich habe zur Übersichtlichkeit deshalb nur den relevanten Teil gezeigt. Hier ist etwas mehr Code:



LCD_Cursor (1, 4);
LCDMsg (MSG_GSM);
switch (GSM_Status)
{
case 0: { LCDMsg (MSG_off); break;}
case 1: { LCDMsg (MSG_boot); break;}
case 2: { LCDMsg (MSG_config); break;}
//...noch ein paar mehr...
}


Es funktioniert alles, bis auf die Zeile bei case 0. Ich kann auch den Wert der Konstanten LCD_off von 9 auf einen anderen Wert ändern, es hilft alles nichts.

Wenn ich in die Zeile statt dessen folgendes schreibe:



LCD_Text_EEPROM (144);


funktioniert alles. Ein seltsames Problem wie ich finde. Zwei Zeilen vorher funktioniert der Aufruf, zwei Zeilen nachher, nur genau an dieser Stelle erhalte ich die komische Fehlermeldung. Ich habe den Teil mit dem switch bereits in eine Funktion gepackt und auch diese etwas im Programm hin und hergeschoben. Das hat aber leider auch nicht geholfen.

Viele Grüße
Andreas

PicNick
13.12.2012, 15:36
Tscha. Bin ich für Einkreisen.
1) lass beim "Case" die geschweiften weg, also einfach

case 0: LCDMsg(MSG_off); break;
2) den "call" aus dem "switch" testweise rausnehmen (davor)


LCD_Cursor (1, 4);
LCDMsg (MSG_GSM);
LCDMsg(MSG_off);
switch (GSM_Status)
{
etc

nur um festzustellen, obÄs um den function-call geht, oder ob es was mit dem "Switch-case" zu tun hat.

Wie sind denn U16 und U8 deklariert ? mit oder ohne * ?

Bumbum
13.12.2012, 17:14
Ich habe es jetzt gerade noch mal probiert und jetzt läuft es. Das Programm ist schon ein paar Tage fertig und funktioniert, ich bin zur Zeit nur noch am Feinschliff und Optimieren. Es wurden inzwischen eine handvoll Codezeilen an verschiedenen Stellen geändert und nun taucht der Fehler nicht mehr auf. Seltsam!

Vorschlag 2 hatte ich bereits probiert, das hat nicht zum Erfolg geführt.

Welche U16 bzw. U8 meintest du genau?

SprinterSB
23.12.2012, 13:55
Das Problem ist ein zu großer Offset in einem relativen Spring, vermutlich wegen inline assembler.

Wie sieht das mit -save-temps erzeugte Präcompilat (i-File) und das s-File aus?

Bumbum
24.12.2012, 11:11
Guten Morgen SprinterSB,

danke für deine Erklärung. Ich nutze kein inline assembler. Woran hätte es dann noch liegen können?

Wie lange dürfen denn die Sprünge sein, bzw. entscheidet nicht der Compiler bzw. Linker, ob er einen relativen oder absoluten Sprung machen muss?

Mein Controller ist fast voll (>99%). Ich nutze eine eigene Bibliothek (LCD). Die Funktionen daraus werden überall im Programm verwendet. Da der Fehler auch beim Aufruf einer Funktion aus dieser Bibliothek aufgetreten ist, und du sagst dass ein Sprung zu lange ist vermute ich das die Bibliothek nicht "in der Mitte" des Programms gelinkt werden konnte und somit vielleicht der Fehler aufgetreten ist.

Leider kann ich den Fehler nicht mehr reproduzieren. Ich hätte ein Backup vom "defekten" Stand machen sollen für weitere Analysen.
Aber die Hauptsache ist ja, dass es jetzt funktioniert. :-)

Viele Grüße
Andreas

SprinterSB
27.12.2012, 11:46
Dazu kann man nur eine Aussage machen, wenn man das nachvollziehen kann. Ansonsten ist's Rumgerate.

Evtl. war auch der µC voll und ein Spring ging zu dem Stück > 100%. Oder du verwendest Optionen wie -mshort-calls ohne zu wissen, was du tust ;-)