Hallo zusammen,
ich habe ein Problem, das mich langsam in den Wahnsinn treibt. Vielleich
fällt dem Einen oder Andern ja etwas ein, was ich noch checken könnte.
Also:
Ich habe ein Makefile-basiertes STM32-C++Projekt in Eclipse neu
aufgesetzt.
crt0 und linker Script von ST, modifiziert von Matrin Thomas. Makefile
auch von der selben Quelle.
Das hat mal ganz ordentlich funktioniert, zumindest insofern, dass die
statischen Konstruktoren ausgeführt wurden. Malloc von Newlib konnte ich
auch einbinden, alles wunderbar. Dann habe ich FreeRTOS eingebaut (hat
in einem anderen Projekt perfekt funktioniert).
Und jetzt habe ich plötzlich folgendes Problem:
crt0 wird ausgeführt, aber beim Aufruf von main() springt der mir an die
total falsche Stelle. Will heissen: main() ist laut Map- und Listfile an
einer bestimmten Adresse A zu finden. crt0 springt aber an 'ne total
(wirklich völlig) andere Adresse B. Wenn ich den Debuger vor dem
main()-Aufruf stoppe und von Hand die Adresse A in's R3-Register
schreibe, springt er dahin, wo er hinsoll, nämlich zu main().
Was ich schon versucht habe: Neues Projekt aufsetzen und alle Files neu
einlesen. Natürlich make clean, mindestens ein Dutzend Mal gecheckt,
dass alle Object Files gelöscht sind, main mit extern "C" deklariert,
main mal als c-File statt cpp compiliert (natürlich im Makefile
angepasst), Code-Optimierungen rausgenommen. Wenn ich main.cpp ganz
lösche, moost der Linker, er fände main() nicht. Also sollte da auch
keine Leiche rumliegen.
So. Ich weiss, das schreit jetzt nach der Kristallkugel. Ich erwarte
natürlich auch keine Antwort im Sinne von: "Hey, diesen Knopf musst Du
drücken", sondern eher Tipps, in welche Richtung man denn eventuell noch
suchen könnte (z.B. irgendwelche Projekt-Einträge im Eclipse???)
Gruss
Simon
Simon Huwyler schrieb:> crt0 springt aber an 'ne total> (wirklich völlig) andere Adresse B.
Wohin denn? Kannst du über die Symboltabelle rausfinden, was an
dieser Stelle ist?
Ansonsten bleibt dir wohl nicht viel anderes übrig als zu analysieren
(auf Ebene des Disassemblers), was genau bis zu diesem Punkt passiert.
Das ist ja gerade das Merkwürdige: Er springt irgendwo hin, wo weit und
breit kein Symbol ist. Ich weiss gerade nicht auswendig, in welchches
Modul, aber eben, einfach mittig irgendwo hinein.
Auf Ebene des Disassemblers ist alles wunderbar nachvollziehbar. Er lädt
R3 mit 'ner Adresse, die er für die richtige Einsprungadresse hält und
springt diese dann an. Im List-File lügt er mich sogar fadengerade und
explizit an, dass das die Adresse von "main" sei. Und im selben
List-File steht main an einer total anderen Adresse.
Irgendwie schon seeeeeehr merkwürdig...
Ich bin fast überzeugt, dass irgendwo irgendeine Leiche rumliegt. Nur -
was ausser den Object-Files kann ich noch bereinigen?
hmmm, ja. Was mir noch eingefallen ist: Der Linker kann ja angewiesen
werden, Code, "versetzt" abzulegen, z.B. den Code in's Rom ablegen, aber
Referenzen dazu in's Ram zeigen zu lassen, in der Hoffnung, dass die
crt0-Fee den Code nach dem Startup rüberkopiert (>RAM at >ROM).
Vielleicht ist da ausversehen irgendein Schalter umgelegt worden, ohne
dass ich's gemerkt habe. Merkwürdig ist nur, dass der Sprung ins Flash
geht und nicht ins RAM. Da müsste das Linkerscript (das ja für STM32
gebaut wurde) schon ziemlich durcheinander geraten sein...
Muss das mal checken, wenn ich zu Hause bin.
Vielen Dank schon mal!
Simon
Grrrrrr, es wird immer merkwürdiger! Schaut Euch mal diesen Screenshot
an und sagt mir, was das denn soll!?!
Ich habe zweimal einen Aufruf von __init_Data(), und der Lümmel springt
zweimal wo anders hin (siehe Disassembly)!
Ich kann mir das schlicht nicht mehr erklären! Da kann ich doch machen,
was ich will, ein Label sollte doch immer die gleiche Adresse haben?
Kann sich jemand von Euch so was auf irgendeine Art erklären?
Übrigens: Weder die erste Adresse noch die zweite stimmt - zumindest
insofern ist der Linker konsistent! ;-)
GRRRRR.... Ich tat dem Linker unrecht!
/* Initialize data and bss */
__Init_Data();
8000068: f240 0395 movw r3, #149 ; 0x95
800006c: f6c0 0300 movt r3, #2048 ; 0x800
8000070: 4798 blx r3
__Init_Data();
8000072: f240 0395 movw r3, #149 ; 0x95
8000076: f6c0 0300 movt r3, #2048 ; 0x800
800007a: 4798 blx r3
.
.
.
void __Init_Data(void) {
8000094: b480 push {r7}
Die Adresse stimmt (bis auf das LSB, das ist für THUMB).
Warum zum Geier aber sagt mir de Debugger was anderes??
Optimierung?
Da passt dann IMHO nichts mehr zusammen, weil teilweise Fuunktionen
sogar in falscher Reihenfolge als im C++ Code ausgeführt werden.
Gruß
Roland
Jup, das hatte ich zuerst. Sah lustig aus, wie der rumhopste! :-)
Aber die habe ich ausgeschaltet.
Merkwürdig ist, dass der Prozi wirklich an die falsche Stelle springt
(es sei denn, der Debugger lügt mich EXTREM dreist an).
---> List File stimmt. Debugger "sieht" das aktuelle File (den doppelten
Aufruf von __init_Data(). Im Flash steht tatsächlich ein doppelter
bx-Befehl, wo er stehen sollte. Aber mit einer anderen Adresse als im
List-File.
Was also inzwischen klar ist: Im Prozi-Flash steht was, was da nicht
stehen sollte. Aber nur etwas ganz bischenbischen anderes. Nur die
Adressen sind falsch....
..... inzwischen fange ich an, zu glauben, dass das Flash durch ist...
ok, ich sehe das Problem... naja, es ist jetzt zumindest nicht mehr
soooo merkwürdig.
Meine letzte Aussage stellte sich als falsch heraus. Da ist halt doch
etwas GANZ anderes im Flash als im Ram. Nämlich "alter" Code. Der wird
gar nicht neu geflashed. Dann muss ich mal schauen, warum. Auf jeden
Fall klärt das, warum der Sprünge an Adressen macht, die laut
Source-File, Linker-Script und Map-File völlig falsch sind.
Nichts für Ungut
Simon