Forum: Compiler & IDEs AVRgcc mit AVRLib und WinAVR Unerklärliche Linker Probleme


von Alexander I. (daedalus)


Lesenswert?

Hallo zusammen,

bei mir drückt der Schuh ziemlich, ich muß mit meinem Kollegen zusammen 
eine Sammlung von Testprogrammen für die Procyon AVRLib schreiben. Und 
zwar:

- LEDs blinken lassen und Taster nutzen
- UART-Testprogramm mit Hello World-Ausgabe an RS232
- SD-Kartenleser ansteuern
- Kommunikation mit einem FTDI FT232BM-Chip (USB) aufbauen
- LCD-Text-Display ansteuern

Das Ganze wird auf einem bereits existierendem und getesteten Board mit 
einem AT90CAN128 und ISP-Programmer entwickelt.

Wir haben dafür 4 Tage Zeit, was ich an sich schon utopisch finde, da 
ich zwar vorher schon mit diversen ARMs und MSP430 zu tun hatte, aber 
nie mit den AVRs und vor allem nicht mit ISP-Programmern sondern bisher 
immer den Luxus von JTAG-Debugging hatte. Tatsache ist, dass wir 
kommenden Freitag 13:00 eine Präsentation halten müssen und nichts geht, 
ausser die LEDs und die Taster. Ich zähle echt auf eure Hilfe!

Zum Problem:
Die Testprogramme die die LIB-C verwenden funktionieren einwandfrei. 
Wenn ich z.B. die Funktion delay_ms() von /utils/delay.h aufrufe, klappt 
dies einwandfrei. Soweit so gut.

Nehmen wir an, ich definiere eine Funktion MyFunc() mit beliebigem 
Inhalt, z.B. einen LED-Blinker. Diese Funktion platziere ich zunächst in 
derselben Datei in der ich auch die main() drin habe. Nach der 
Kompilierung und dem Upload mit PonyProg funktioniert alles prima.

Nehme ich nun MyFunc() und lagere diese in eine andere Datei aus, z.B. 
"funcs.h" und inkludiere sie mit
1
#include "funcs.h"
, dann jammert zunächst Make herum, dass es die Referenz in der Main auf 
MyFunc() nicht erkennt. Der Eintrag "SRC += funcs.c" im Makefile löst 
das Problem. Make läuft ohne Probleme durch und bringt auch keinerlei 
Warnings oder Errors.

Nach dem Upload des Hexfiles läuft der Prozessor exakt BIS zum Aufruf 
von MyFunc(); danach stürzt er ab. Er führt weder den Code innerhalb 
MyFunc() noch den nachfolgenden Code aus.

Ich habe es mehrfach getestet, es klappt einfach nicht. Dann habe ich 
die erzeugte main.lst analysiert. Dort zeigt sich im Assembler-Code, 
dass er das Symbol MyFunc nicht linken konnte. Ganz unten steht dort:

UNDEFINED SYMBOLS
MyFunc

Nun ist mir schon klar, dass er bei call MyFunc irgendwo ins Nirvana 
rennt, aber warum ist das so?? Wie bringe ich dem Linker bei, dass er 
MyFunc in der funcs.h findet? Und vor allem: Warum zeigt mir Make bei 
der Kompilierung keinerlei Fehler an? Das ist nicht nur bei meinen 
externen include's so, sondern auch bei den includes von der Procyon 
AVRLib. Lediglich die LIB-C includes wie stdio.h usw. funktionieren 
einwandfrei.

Betriebssystem: Win XP
ISP-Programmer: Parallel
Software: WinAVR, MFile und PonyProg (AVRStudio und AVR Dude stürzen 
beide ab). Alles jeweils in der neusten Version.

Ich hoffe ihr könnt mir etwas helfen. Vielen Dank schonmal vorab.

von holger (Gast)


Lesenswert?

Gib doch mal ein komplettes Projekt mit allen Sourcecodes
rüber. So rein im Kopf kann das doch keiner nachvollziehen !

von Alexander I. (daedalus)


Lesenswert?

OK, dauert paar Minuten.

von Alexander I. (daedalus)


Angehängte Dateien:

Lesenswert?

Hier ist es ...

von holger (Gast)


Lesenswert?

Jetzt schmeisst du mal ganz schnell

#define _AVR_ATmega128_ 1

aus demo.c raus.

von Alexander I. (daedalus)


Lesenswert?

Ist raus. Fehler bleibt weiterhin.

von holger (Gast)


Lesenswert?

>The maximal possible delay is 262.14 ms / F_CPU in MHz.

Das verdammte _delay_ms() :(

Versuch mal:

 for(i=0; i<250; i++) { _delay_ms(1); }

von Alexander I. (daedalus)


Lesenswert?

Hab ich gemacht ... ändert nichts. wenn ich MyFunc(); auskommentiere 
blinkt das Teil auch munter vor sich hin und reagiert auf Tastendrücke 
wie gewollt ...

von holger (Gast)


Angehängte Dateien:

Lesenswert?

>MyFunc();

Naja, das heisst im Code immer noch myfunc().
Bei mir compiliert das ganze und gibt auch eine
HEX Datei. Dem Linker fehlt also nichts.

Versuch mal den Anhang. Wenn das nichts bringt
kann ich dir auch nicht weiterhelfen.

von Alexander I. (daedalus)


Lesenswert?

Hallo,

hab ich kompiliert. Es kommt auch (wie immer) eine .hex-Datei hinten 
raus, ohne Errors ohne Warnings. Geht aber trotzdem nicht. :(

Vielen Dank dir aber trotzdem für deine Hilfe.

von holger (Gast)


Angehängte Dateien:

Lesenswert?

Habs gerade mal ausprobiert. Mit ATMega32.

LED an PORTA3 blinkt fröhlich vor sich hin.
Auch mit myfunc() !

von Alexander I. (daedalus)


Lesenswert?

Hallo Holger,

Dein Sourcecode funktioniert einwandfrei, allerdings EXTREM langsam. LED 
blinkt ca. alle 5-7 Sekunden, bei mir wars vorher ca. alle 750ms. Aber 
gut, wenigstens geht es. Jetzt kommt das Interessante:

Funktionieren tut es NUR, wenn ich im Makefile das MCU = atmega32 habe. 
Setze ich dort den für mich korrekten Wert MCU = at90can128 oder auch 
MCU = atmega128 ein, dann funktioniert es NICHT.

Kannst du mit dieser Info etwas anfangen?

von Uwe N. (ulegan)


Lesenswert?

Nachdem du den Prozessortyp im Makefile änderst musst du ein 'make 
clean' machen und dann alles mit 'make all' neu übersetzen.
Sonst linkt der Linker munter die alten, für den anderen Prozessor 
übersetzten, Module zusammen. Das gibt keine Fehlermeldung!
Spätestens, wenn der Aufbau der Interruptvektoren sich ändert gibt das 
Probleme. Auch die Namen oder Adressen der angesprochenen Register 
könnten sich geändert haben.

Uwe

von Alexander I. (daedalus)


Lesenswert?

Hallo Uwe,

das habe ich schon so gemacht. Trotzdem kommt der Fehler.

von Andreas Paulin (Gast)


Lesenswert?

Ohne jetzt alles verstanden zu haben:
@ Uwe Nagel: d'accord.
Wenn der Fehler hartnäckig bleibt, obwohl er inzwischen weg sein MÜSSTE,
.... liegts allemal daran, dass der Programmer munter irgendein altes 
oder einfach falsches .hex-File flasht... mal checken, bzw. löschen.

von Alexander I. (daedalus)


Lesenswert?

Zur Erklärung:

Ich benutze idR immer "make clean" bevor ich das Zeug auf den µC flashe. 
Im Programmverzeichnis sind dann tatsächlich blos noch die C-Sourcen. 
Die .hex-Datei ist garantiert die richtige, da ich sie im PonyProg 
selbst mit der Maus auswähle und auch immer mal wieder 2-3 LEDs 
miteinander vertausche um die Wirkung der Änderung zu sehen (natürlich 
immer bevor der µC sich ins Nirvana verabschiedet).

Der Prof hat uns jetzt immerhin genehmigt alles in eine C-Datei 
hineinzuquetschen, damit wir zumindest irgendwelche Ergebnisse bekommen. 
Aber so wirklich die Lösung ist das natürlich auch nicht ...

von holger (Gast)


Lesenswert?

So, habs jetzt auch noch mal für ATMega128 compiliert
und mit ATMega128 ausprobiert. Klappt perfekt. LED3 blinkt so im
Sekundentakt. Bist du sicher das du deine Fuses
richtig gesetzt hast ? Interner Osci 8MHz und CKDIV8 falsch
gesetzt könnte das zu langsam blinken erklären.

Wie ja oben bereits gesagt wurde solltest du folgende
Reihenfolge einhalten:

make clean
Prozessor im makefile ändern
make all
Prommerprogramm starten und HEX Datei laden, oder
wenn Prommerprogramm noch läuft HEX-Datei "Neu" laden.
"Neu" laden ist wichtig weil das Prommerprogramm sonst
evtl. die alten Daten noch im Speicher behält.
Fuses richtig einstellen
Prommen

Das Programm ist so einfach, das kann sich gar
nicht aufhängen ! Es sei denn _delay_ms() bleibt stehen.

von Alexander I. (daedalus)


Lesenswert?

Hallo zusammen,

es läuft! Das Mysterium ist geklärt. Es lag an den Fuse-Settings und 
PonyProg welches selbige falsch gesetzt hat: Ich darf nicht die 
Fuse-Settings für den AT90CAN128 brennen, sondern muß die für den 
ATmega128 wählen die wohl geringfügig anders sind (obwohl ein AT90CAN128 
eingelötet ist!). PonyProg hat aber keinerlei Fehler angezeigt und immer 
brav gemacht.

Die Fuse-Settings stimmen jetzt also und die Programme lassen sich 
problemlos kompilieren, uploaden und das Wichtigste: auch in externe 
Funktionen in anderen C-Dateien springen.

Vielen Dank an euch, ihr habt mir wirklich ziemlich geholfen. Vielleicht 
wirds mit einer Nachtschicht ja doch noch was mit ner kleinen 
Präsentation morgen...

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.