Servus allerseits
Mein Problem: das von der StdPerLib benutzte assert_param führt beim
Build zu Errors.
Arbeitsumgebung:
Em::Blocks vers 2.0
GCC vers. 4.7.3 20130226
STM32F407
StdPerLibF4: vers 1.3.0
Compiler Defines:
debug_print("assert_failed in file: %s, line: %ld\n",file,line);
5
while(1);
6
}
7
#endif
Solange ich keine Dateien der StdPerLib einbinde und nur mit den eigenen
arbeite, kann ich in irgendeiner Datei die Zeile
1
assert_param(4>5);
einfügen und ich kriege prompt per Semihost die korrekte Fehlermeldung.
Sobald ich aber auf irgendeine Datei der StdPerLib zugreife, kriege ich
ein Stakkato der Fehlermeldung wie z.Bsp.
D.h., der Praeprozessor löst assert_param korrekt nach assert_failed
auf, aber der Linker kann damit nichts anfangen.
Aber wie gesagt: nur bei den StdPerLib-Dateien. Bei meinen eigenen hat
der Linker damit kein Problem.
Wenn ich dasselbe Szenario mit dem EWARM-Kickstart von IAR durchspiele,
funktioniert alles ohne irgendwelche Fehler.
Hat irgendwer 'ne Idee, woran das liegen könnte?
Ich vermute, daß die Datei, in der assert_failed definiert ist, vor den
zu StdPerLib gehörenden gelinkt wird. Die muß in der
Linker-Kommandozeile danach stehen, damit der Linker das auflösen kann.
Servus Rolf
Dein Tip hat mir zwar nicht eingeleuchtet, aber seit einigen Stunden bin
ich eh schon im "Probieren geht über Studieren" Modus :)
Da Em:Blocks kein make-file hat:
Hab also die Funktion assert_failed() in der Datei main.cpp gelöscht und
es an das Ende der Datei stm32f4xx_gpio.c gehaengt.
Hab' nicht schlecht gestaunt, als jetzt das assert_failed() in der
Nicht-StdPerLib-Datei als undefined reference reklamiert wurde: das
Stakkato an Fehlermeldungen der StdPerLib-Dateien war weg.
Also habe ich die Funktion assert_failed() in die main.cpp kopiert und
erwartet, dass jetzt der Linker über diese Redefinition meckern würde.
Von wegen: jetzt habe ich zwar keine Fehlermeldungen mehr und auch das
Program reagiert wie es sollte ...
Nur: ich steh wieder wie zuvor vor dem Bildschirm und kratz mich am
Kopf.
Wie kann es sein, dass der Linker 2 gleichnamige Funktionen, die nicht
static sind, nicht beanstandet?
Und wieso ist beim Linken die Reihenfolge der Module wichtig? Es ist
doch gerade dies eine der Aufgaben des Linkers, unter all den
kompilierten Modulen die Funktionen herauszufischen und sie zu einem
ausführbaren Program zusammenzufügen.
Mehmet Kendi schrieb:> Und wieso ist beim Linken die Reihenfolge der Module wichtig?
Der Linker bindet nur die Symbole aus Libraries ein, von denen er weiß,
daß sie benötigt werden.
In der Linker-Kommandozeile muß deswegen das Objekt, das den Bedarf hat,
zuerst auftauchen.
Das kann u.U. (wenn kein ranlib auf die Lib ausgeführt wurde) sogar dazu
führen, daß man ein und dieselbe Library mehrfach angeben muß.
Vermutlich habe ich eine falsche Faehrte gelegt, da ich davon ausging,
die "Standard Peripherals Library" von STMicroelectronics sei jederman
bekannt. Sorry!
Wenn ich StdPerLib schreibe, dann meine ich nicht eine Library im
üblichen Sinne. Das Ding heisst zwar Library, besteht aber aus einzelnen
Dateien.
Mehmet Kendi schrieb:> Und wieso ist beim Linken die Reihenfolge der Module wichtig? Es ist> doch gerade dies eine der Aufgaben des Linkers, unter all den> kompilierten Modulen die Funktionen herauszufischen und sie zu einem> ausführbaren Program zusammenzufügen.
Ja, und dazu geht er die zu linkenden Dateien eine nach der anderen
durch. Wenn er mit einer Datei fertig ist, hat er eine Liste von noch
nicht aufgelösten Symbolen. Diese Liste merkt er sich. Wenn er die
nächste Datei öffnet, schaut er nach, ob er hier Symbole auflösen kann
und tut das dann. Ggf. kommen neue noch nicht aufgelöste Symbole hinzu.
So geht er alle Dateien durch, und die Liste der unaufgelösten Symbole
wird jedesmal angepasst. Am Schluss müssen alle Symbole aufgelöst sein,
sonst gibt der Linker für jedes noch in der Liste vorhandene Symbol eine
Fehlermeldung aus.
Wenn nun ein Object-File ein Symbol definiert, das bisher nirgends
benötigt wird, verwirft der Linker es. Wenn es dann später in einem
anderen Object-File benötigt wird, ist es nicht mehr da.
Rolf, mit dem 1. Abschnitt bin ich einverstanden. Aber der 2. Abschnitt
leuchtet mir nicht ein.
Werde mir mal bis morgen darüber ein paar Gedanken und ein paar Tests
machen.
Problem gelöst. Die Quelle des Problems lag so um die 90cm vom
Bildschirm entfernt. Wie immer.
Ich arbeite mich seit 2 Tagen in Em::Blocks ein und war dabei, mir ein
Template für den von mir benutzten MCU zu erstellen. Ging auch alles
glatt vonstatten ... bis ich entdeckte, dass man mit Ctrl-H zwischen
Source und Header springen konnte. Geil! Nur setzte die IDE als
Header-Extention h und nicht hpp voraus.
Mit den paar Headern die ich hatte war's ein Schnelles, sie von hpp auf
h zu aendern. Und dabei vergass ich, diese in
1
#ifdef __cplusplus
2
extern"C"{
3
#endif
4
..
5
#ifdef __cplusplus
6
}
7
#endif
einzubetten.
Asche auf mein Haupt! Und sorry für das unnötige Forums-Rauschen.