www.mikrocontroller.net

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


Autor: Alexander I. (daedalus)
Datum:

Bewertung
0 lesenswert
nicht 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
#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.

Autor: holger (Gast)
Datum:

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

Autor: Alexander I. (daedalus)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
OK, dauert paar Minuten.

Autor: Alexander I. (daedalus)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hier ist es ...

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jetzt schmeisst du mal ganz schnell

#define _AVR_ATmega128_ 1

aus demo.c raus.

Autor: Alexander I. (daedalus)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ist raus. Fehler bleibt weiterhin.

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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); }

Autor: Alexander I. (daedalus)
Datum:

Bewertung
0 lesenswert
nicht 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 ...

Autor: holger (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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.

Autor: Alexander I. (daedalus)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: holger (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Habs gerade mal ausprobiert. Mit ATMega32.

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

Autor: Alexander I. (daedalus)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Uwe Nagel (ulegan)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Alexander I. (daedalus)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Uwe,

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

Autor: Andreas Paulin (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Alexander I. (daedalus)
Datum:

Bewertung
0 lesenswert
nicht 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 ...

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Alexander I. (daedalus)
Datum:

Bewertung
0 lesenswert
nicht 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...

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.