Diesen Code habe ich in eine .S-Datei geschrieben und in das Projekt
eingebunden, um einen Anfang für eine Assembler-ISR zu haben, die später
optimiert werden soll.
Die C-ISR habe ich auskommentiert. Das Ergebnis im LST-File:
Bis auf die neue Adresse der ISR und eine andere Verteilung der
Konstanten am Ende sind sie identisch. Das Problem: wenn ich die
Variante mit der .S-Datei flashe, dann lande ich im Hard Fault. Ich sehe
nicht woran es liegen könnte.
Was noch auffällt: die Sprungadresse in der Tabelle im
funktionierenden Code, 08004b7d, stimmt nicht mit dem Anfang der ISR
überein. Trotzdem funktioniert es. Die zweite Variante mit der .S-Datei
funktioniert nicht...
Tycho B. schrieb:> Der passende Ausschnitt aus dem LST-File:> [...]> Diesen Code habe ich in eine .S-Datei geschrieben und in das Projekt> eingebunden,
Umständlich.
Einfacher ist, mit etwas anzufangen, das assemblierbar ist; etwa mit
-save-temps compilieren und das temporäre s-File als Startpunkt
hernehmen.
Tycho B. schrieb:> Was noch auffällt: die Sprungadresse in der Tabelle im> funktionierenden Code, 08004b7d, stimmt nicht mit dem Anfang der ISR> überein.
Das muss so. Beim ARM gibt das unterste Bit einer Sprung-Adresse an, ob
im Thumb-Mode (1) oder ARM-Mode (0) ausgeführt werden soll. Die Cortex-M
haben nur den Thumb-Mode, daher muss beim Springen das unterste Bit
immer 1 sein. Die tatsächliche Adresse muss onehin immer ein Vielfaches
von 2 sein, weswegen das unterste Bit keine Auswirkung auf die
tatsächliche Adresse hat. Wenn bei der nicht funktionierenden Variante
das unterste Bit der Adresse 0 ist, funktionierts nicht. Schreibe mal
".thumb" an den Anfang der Assembler-Datei, dann macht der Compiler das
vermutlich automatisch richtig.
Tycho B. schrieb:> Was noch auffällt: die Sprungadresse in der Tabelle im> funktionierenden Code, 08004b7d, stimmt nicht mit dem Anfang der ISR> überein.
Die Adresse ist absichtlich "falsch" und deswegen funktioniert es :D
Das liegt daran, dass die ARM CPUs zwei verschiedene Modi besitzen: ARM
oder Thumb. Ist die Sprungadresse einer Funktion gerade, d.h. das LSB
ist 0, wird im ARM-Modus ausgeführt, ist die Sprungadresse ungerade
(LSB==1) wird im Thumb-Modus ausgeführt. Im Flash selbst liegen die
Funktionen in beiden Fällen an geraden Adressen, d.h. das LSB der
Sprungadresse wird für den eigentlichen Sprung ignoriert und ist
lediglich für die Unterscheidung der Modi da.
An deiner funktionierenden Variante sieht man schön, dass zwar die
Funktion selbst an einer geraden Adresse liegt aber der Vektor auf eine
ungerade Adresse zeigt. In der nicht funktionierenden Variante sind
sowohl Adresse im Flash, als auch der Vektor gerade.
Damit der Linker den Vektor richtigerweise auf eine ungerade Adresse
zeigen lässt musst du dem die passende Information mit auf den Weg
geben. Dafür ist das
1
.thumb_func
da, was du im Listing deiner C-Variante sicher finden dürftest und was
sehr wahrscheinlich in deiner Assembler-Variante fehlt.
Edit: Dr. Sommer war schneller. Hinzufügen würde ich noch, das .thumb
und .thumb_func nicht das gleiche bezwecken. Man benötigt beides, wobei
durch .thumb_func implizit auch .thumb gesetzt wird.
Christopher J. schrieb:> Edit: Dr. Sommer war schneller. Hinzufügen würde ich noch, das .thumb> und .thumb_func nicht das gleiche bezwecken. Man benötigt beides, wobei> durch .thumb_func implizit auch .thumb gesetzt wird.
Da hat mir ja nur ganz wenig an Info gefehlt, um selbst drauf zu kommen)
.thumb hatte ich schon drin, allerdings nicht .thumb_func.
Damit funktioniert es. Danke)