TIM2_IRQHandler() wird nur angesprungen, wenn ich die Funktion selber in
der main() aufrufe, sobald ich diese Anweisung entferne, wirft sie der
Linker aus dem Listing-File (Debug/List/****.map), sie wird also einfach
vom Compiler wegoptimiert da sie nie aufgerufen wird.
Normalerweise sollte doch für jeden Interrupt-Vektor eine entsprechende
Funktion in der Header-Datei vorhanden sein, warum ist das hier nicht
so?
2. Frage: Hier wird beschrieben, wie man sich die Register des uC
übersichtlich als Liste anzeigen lassen kann:
https://www.iar.com/support/resources/articles/debugging-with-microcontroller-registers/
das soll ab Version 7.5 möglich sein (also gehe ich davon aus, dass es
bei der aktuellen Version 8.22.2 immer noch möglich ist). Im Debug-Modus
finde ich den Punkt "View -> Register" allerdings nicht. Weiß jemand, wo
sich der in den neueren Versionen versteckt?
Sich händisch durch den auf den Adressbereich des M3 gemappten Speichers
der Peripherie zu wühlen ist nicht besonders komfortabel.
Max M. schrieb:> __irq void TIM2_IRQHandler (void) {
Spricht für C
Max M. schrieb:> void timer2_setup() {
Spricht für C++
Wenn es tatsächlich C++ ist, fehlt vermutlich das:
extern "C"
Dr. Sommer schrieb:> Max M. schrieb:>> void timer2_setup() {>> Spricht für C++
Nein, wie kommst Du darauf? Das fehlende void? das ist schon lange
erlaubt.
Und bei C++ (wenn er es konsequent durchzieht) hätte er wohl eher eine
Instanz einer Timer Klasse (vor allem wenn es mehrere Timer gibt) mit
einer setup() Methode. Das Pattern "klasse_methode()" mutet exrem c-isch
an.
---
Aber ich finde es sehr bemerkenswert daß die ganze IDE abschmiert wenn
das Target in einen Hardfault läuft.
Bernd K. schrieb:> Aber ich finde es sehr bemerkenswert daß die ganze IDE abschmiert wenn> das Target in einen Hardfault läuft.
Oops, Thread verwechselt, bitte 2. Teil ignorieren.
Ich glaub, ich hab da etwas vorschnell geglaubt, die IRQ würde außerhalb
meines einzelnen Aufrufs in der main() noch ein zweites bzw. weitere
Male aufgerufen werden: dem ist nicht so.
1
__rootvoidTIM2_IRQHandler(void){
2
TIM2->SR&=~TIM_SR_UIF;
3
GPIOC->ODR|=GPIO_ODR_ODR13;
4
}
so taucht die Funktion zwar noch im Listing-File auf, wird allerdings
beim Debuggen nicht mehr angesprungen. Ich hab heute Nachmittag schon
ewig gesucht und hab nichts dazu gefunden, wie man in IAR eine ISR
definiert. Anscheinend zumindest nicht so, wie ich es bisher versucht
habe.
Mein Timer-Setup dürfte soweit passen, denke ich.
Max M. schrieb:> Normalerweise sollte doch für jeden Interrupt-Vektor eine entsprechende> Funktion in der Header-Datei vorhanden sein, warum ist das hier nicht> so?
Bei gcc ist die Section mit der Vektortabelle mit keep markiert damit
sie (und alles was dran hängt) nicht wegoptimiert wird. Irgendwas
vergleichbares muss es doch auch bei IAR geben. Hast Du am Linkerscript
oder am Startup code rumgespielt?
Max M. schrieb:> Ich hab heute Nachmittag schon> ewig gesucht und hab nichts dazu gefunden, wie man in IAR eine ISR> definiert.
Es wird doch wohl Beispielcode geben? IAR ist ja jetzt auch nicht
gänzlich ungenutzt in der ARM-Szene.
Max M. schrieb:> so taucht die Funktion zwar noch im Listing-File auf, wird allerdings> beim Debuggen nicht mehr angesprungen.
Schau mal im Startup code nach der genauen Schreibweise.
Bernd K. schrieb:> Hast Du am Linkerscript> oder am Startup code rumgespielt?
Nein, ich hab nix gemacht.
Bernd K. schrieb:> Es wird doch wohl Beispielcode geben?
Möglicherweise bin ich auch unfähig vernünftig zu googlen, aber ich hab
echt nichts gefunden.
Bernd K. schrieb:> Schau mal im Startup code nach der genauen Schreibweise.
Hab ich.
Ist allerdings unter ROTS\SEGGER\ST\STM32F100, und nicht unter CMSIS wie
ich erwartet hätte.
Bernd K. schrieb:> Nein, wie kommst Du darauf? Das fehlende void? das ist schon lange> erlaubt.
Erlaubt ja. Aber fehlendes void bedeutet in C "Beliebig viele Parameter
beliebigen Typs". Da die Funktion aber nichts dergleichen tut, denke ich
das "gar keine Parameter" gemeint war. In C++ reicht dafür "()", in C
braucht's dazu "(void)". Daher die Vermutung, dass es C++ sein könnte.
Bernd K. schrieb:> Und bei C++ (wenn er es konsequent durchzieht) hätte er wohl eher eine> Instanz einer Timer Klasse
OOP ist nur ein von C++ unterstütztes Paradigma. Nur weil man C++
nutzt muss man noch lange kein OOP machen.
Max M. schrieb:> __irq void TIM2_IRQHandler (void) {
__irq ist für Cortex-M ungültig. Siehe Reference Manual.
Folglich wird die Funktion wohl garnicht gesehen und ausgeblendet.
Lass es einfach weg, dann klappt das auch!
m.n. schrieb:> Lass es einfach weg, dann klappt das auch!
Hast du das tatsächlich selbst ausprobiert? Bei mir klappt es nämlich
keineswegs.
m.n. schrieb:> Siehe Reference Manual.
Welches Reference Manual?
Unter Hilfe: C/C++ Development Guide
Das Schöne an Cortex-M ist doch gerade, daß eine C-Funktion als ISR
aufgerufen werden kann. Das mache ich "pausenlos".
Beispiel:
void TIM8_UP_TIM13_IRQHandler(void)
{
TIM8->SR = ~TIM_SR_UIF;
F1_ueberlauf += 0x10000;
}
Bis heute wußte ich garnicht, daß es __irq überhaupt gibt ;-)
dies ist bestimmt als MACRO ohne Inhalt deklariert.
Bei deinem Fehler schlägt am wahrscheinlichsten "name mangling" zu.
Das geht dann schief, wenn man die Datei als cpp benannt hat oder
in den iar settings eingstellt hat das auch .c dateien als c++ übersetzt
werden sollen.
hast du das denn schon mal probiert:
Dr. Sommer schrieb:> Wenn es tatsächlich C++ ist, fehlt vermutlich das:> extern "C"
m.n. schrieb:> Unter Hilfe: C/C++ Development Guide
"Your application can therefore
simply define its own exception function by just defining it using the
correct name from
the list above (cstartup_M.c)."
Hab ich doch?!
Zweig schrieb:> hast du das denn schon mal probiert:
Ich hab die Syntax gegoogled, aber anscheinend stimmt das nicht:
1
extern"C"voidTIM2_IRQHandler(void);
2
3
voidTIM2_IRQHandler(void){
4
TIM2->SR&=~TIM_SR_UIF;
5
GPIOC->ODR|=GPIO_ODR_ODR13;
6
}
1
Expected identifier (extern "C")
m.n. schrieb:> Das mache ich "pausenlos".
Ist dein nachfolgender Code IAR-kompatibel? Falls ja - woraus erschließt
sich die Bezeichnung für die ISR? Wie würde sowas für den Timer2 in
meinem Fall lauten?
Max M. schrieb:> Ist dein nachfolgender Code IAR-kompatibel? Falls ja - woraus erschließt> sich die Bezeichnung für die ISR? Wie würde sowas für den Timer2 in> meinem Fall lauten?
Ich verwende eine ältere IAR-IDE, die sollte schon in sich kompatibel
sein ;-)
Beim F4 (den verwende ich) heißt die Datei "startup_stm32F4xx.s".
Auszugsweise steht dort:
DCD TIM1_CC_IRQHandler ; TIM1 Capture Compare
DCD TIM2_IRQHandler ; TIM2
DCD TIM3_IRQHandler ; TIM3
DCD TIM4_IRQHandler ; TIM4
.....
PUBWEAK TIM1_CC_IRQHandler
SECTION .text:CODE:REORDER(1)
TIM1_CC_IRQHandler
B TIM1_CC_IRQHandler
PUBWEAK TIM2_IRQHandler
SECTION .text:CODE:REORDER(1)
TIM2_IRQHandler
B TIM2_IRQHandler
PUBWEAK TIM3_IRQHandler
SECTION .text:CODE:REORDER(1)
TIM3_IRQHandler
B TIM3_IRQHandler
PUBWEAK TIM4_IRQHandler
SECTION .text:CODE:REORDER(1)
TIM4_IRQHandler
B TIM4_IRQHandler
Beim F10x sollte es genauso aussehen.
Ich sags ja nur ungern aber wäre es vielleicht im Rahmen der
Möglichkeiten auf einen etwas weniger exotischen Compiler umzusteigen
mit deutlich mehr verfügbaren Erfahrungswerten und Support wie zum
Beispiel gcc?
Bernd K. schrieb:> auf einen etwas weniger exotischen Compiler
Ist IAR tatsächlich so exotisch? Das ist immerhin eine professionelle
Firma und so...
Aber mit EmBitz funktioniert der Code halt 1:1, warum sollte man für so
eine IDE (IAR) Geld bezahlen?
Mich würds trotzdem interessieren, warum es denn nun nicht funktioniert
Max M. schrieb:> Ist IAR tatsächlich so exotisch? Das ist immerhin eine professionelle> Firma und so...
Aber in der Summe doch nur ein verschwindender Marktanteil gegenüber dem
allgegenwärtigen gcc. Du siehst ja selbst wie schwer es ist da auf die
Schnelle jemanden zu finden der wissen könnte wo der Fehler liegen
könnte bei einem vergleichsweise trivial erscheinenden Problem.
Hättest Du ein ähnlich gelagertes Problem mit gcc würdest Du
wahrscheinlich binnen 10 Minuten mit hilfreichen Problemlösungen,
einschlägiger Doku und funktionierendem Beispielcode förmlich
überschüttet.
Bernd K. schrieb:> Ich sags ja nur ungern aber wäre es vielleicht im Rahmen der> Möglichkeiten auf einen etwas weniger exotischen Compiler umzusteigen
Da ist überhaupt nichts Exotisches.
m.n. schrieb:> Da ist überhaupt nichts Exotisches.
Du hast nicht zufällig eines von diesen günstigen STM32F103 Boards bei
dir und magst mal kurz mein Programm ausprobieren?
Wichtige Fragen die ich als nächstes klären würde:
* Wo springt er denn stattdessen hin wenn er nicht in Deine
Interruptfunktion springt? Wenn die Interruptfunktion vom Linker als
nicht existent betrachtet wird sollte er im entsprechenden
Defaul-Handler landen, die Endlosschleife im Startup-Code, setz da mal
einen Breakpoint. Oder schau wo er sich befindet wenn Du auf Pause
klickst.
* Wenn das nicht der Fall ist dann wird der Interrupt gar nicht
ausgelöst. Läuft der Timer überhaupt, muss man da eventuell noch den
Zähltakt separat einstellen? Hab ich schon gesehen bei einigen
Herstellern. Drück auf Pause und schau ins Zählregister des Timers ob er
läuft oder nicht.
* Wenn der Timer tatsächlich läuft und dennoch keinen Interrupt auslöst
dann studier nochmal ausführlich die Doku zu dem Timer im Reference
Manual, vielleicht hast Du noch irgendein blödes Bit irgendwo vergessen
zu setzen oder zu löschen und er ist im falschen Modus oder was auch
immer.
Max M. schrieb:> Exception occured at 0xb280840
und was ist bei 0xb280840, ist das Flash mit ausführbarem Programm? Die
Adresse kommt mir ziemlich krumm vor, mitten im Nirgendwo. Fangen die
ganzen STM32 nicht alle bei 0x8000000 oder so mit dem Flash an? Das
winzige Programm kann doch kaum länger als ein paar hundert Byte sein.
Überprüf mal Deine Taktkonfiguration. Das hab ich schonmal erlebt: Takt
viel zu hoch konfiguriert und bei einem indirekten Sprung sprang er ins
Nirwana an eine vollkommen absurde Adresse, man konnte sogar im Debugger
dabei zusehen im Einzelschritt. Setz mal einen Breakpoint auf den
Reset-Vektor im Startup code und steppe es komplett von Anfang an durch.
Und zwar im Instruction-Modus, also auf Assemblerebene, nicht auf
C-Ebene und genau beobachten wo er hinspringt und bei welchem
Maschinenbefehl es genau knallt.
Edit:
Wenn Du schon rausgefunden hast daß er bei NVIC_EnableIRQ() abstürzt
dann halte ihn dort kurz davor an, geh in den Instruction stepping modus
und steppe dann auf Assemblerebene weiter, ganz langsam und genau drauf
achten was er machen sollte und was tatsächlich passiert.
Danke für deine Hilfe.
Bernd K. schrieb:> ganz langsam und genau drauf> achten was er machen sollte und was tatsächlich passiert.
der Befehl an Adresse
1
0x8000058
produziert den Fehler, anstatt den nächsten Befehl bei 5C
auszuführen, springt er direkt an die BusFault_Handler-Adresse
(0x80000DA).
Bernd K. schrieb:> Setz mal einen Breakpoint auf den> Reset-Vektor im Startup code
Ich kenne das nur von Em-Bitz, da wird ein Assembler-Startup File
ausgeführt, bei IAR sehe ich das allerdings nicht bzw. ich weiß nicht,
wie ich darauf Zugriff bekomme.
Edit: Ich hab nun den Code-Teil, der die Takfrequenz für den Prozessor
festlegt, entfernt. Jetzt funktioniert das NVIC auch!
Beim Debuggen tritt die gleiche HardFault-Exception nach dem ich einen
Break gemacht habe bei Adresse "0x8000F3AE" auf, allerdings ist da auch
nix bzw. es wird zumindest im Disassembly nichts angezeigt.
Max M. schrieb:> da wird ein Assembler-Startup File> ausgeführt, bei IAR sehe ich das allerdings nicht bzw. ich weiß nicht,> wie ich darauf Zugriff bekomme.
In Eclipse würde ich einfach die betreffende Datei die den Startupcode
enthält in der IDE öffnen und dort einen Breakpoint setzten, der wird
dann respektiert. Notfalls kann man aber auch Breakpoints setzen indem
man manuell die Adresse angibt. Oder Du scrollst im Disassemblerfenster
dort hin und setzt den Breakpoint dort. Müsste eigentlich in IAR auch
gehen denk ich mal.
Aber wenn die fehlende Taktkonfiguration den Unterschied macht dann denk
ich hast Du den Fehler identifiziert. Läuft jetzt Dein Interrupt?
Als nächstes musst Du Dir das Reference-Manual vom STM nochmal
vorknöpfen und die Taktkonfiguration nochmal durchgehen (und auch die
Konfiguration der notwendigen wait states beachten). Notfalls ein
existierenden funktionierendes Beispiel betrachten (zum Beispiel eins
das von der Cube Software generiert wurde) und das mal anhand des
Reference Manuals Bit für Bit durchgehen um zu sehen und zu verstehen
was die alles einstellen und warum.
Max M. schrieb:> Beim Debuggen tritt die gleiche HardFault-Exception nach dem ich einen> Break gemacht habe bei Adresse "0x8000F3AE" auf
Da ist doch noch irgendwas faul. Wenn Du die Taktkonfiguration nicht
anfasst müsste er mit den Defaultwerten eigentlich fehlerlos laufen
können. Da muss noch was anderes faul sein.
Versuch jetzt mal rauszufinden ob er jetzt zumindest einmal in Deinen
Interrupt springt.
Und versuch mal was passiert wenn Du den Interrupt nicht enablest,
crasht er dann immer noch oder bleibt er friedlich in der while(1)?
Bernd K. schrieb:> Versuch jetzt mal rauszufinden ob er jetzt zumindest einmal in Deinen> Interrupt springt.
Nein, tut er immer noch nicht. Die Funktion wird vom Compiler
wegoptimiert.
Bernd K. schrieb:> crasht er dann immer noch oder bleibt er friedlich in der while(1)?
Nein, tatsächlich funktionieren Break und Continue dann einwandfrei.
Max M. schrieb:> Bernd K. schrieb:>> Versuch jetzt mal rauszufinden ob er jetzt zumindest einmal in Deinen>> Interrupt springt.>> Nein, tut er immer noch nicht. Die Funktion wird vom Compiler> wegoptimiert.
schreib das mal so:
1
__irq__armvoidTIM2_IRQHandler(void){
2
undsoweiter
3
}
__irq und __arm scheinen spezielle Schlüsselwörter für deren Compiler zu
sein, keine Makros. __arm braucht man wenn ich es richtig lese wenn
thumb code erzeugt wird womit wir es normalerweise zu tun haben. Wenn
nicht dann stell den compiler entsprechend ein daß er thumb code erzeugt
und verwende __irq __arm
https://www.iar.com/contentassets/e20cfa542d1a4734aa6b234bea42f11a/example-8.pdf
Bernd K. schrieb:> Max M. schrieb:>> Bernd K. schrieb:>>> Versuch jetzt mal rauszufinden ob er jetzt zumindest einmal in Deinen>>> Interrupt springt.>>>> Nein, tut er immer noch nicht. Die Funktion wird vom Compiler>> wegoptimiert.>> schreib das mal so:>>
1
>__irq__armvoidTIM2_IRQHandler(void){
2
>undsoweiter
3
>}
4
>
>> __irq und __arm scheinen spezielle Schlüsselwörter für deren Compiler zu> sein, keine Makros. __arm braucht man wenn ich es richtig lese wenn> thumb code erzeugt wird womit wir es normalerweise zu tun haben. Wenn> nicht dann stell den compiler entsprechend ein daß er thumb code erzeugt> und verwende __irq __arm>> https://www.iar.com/contentassets/e20cfa542d1a4734aa6b234bea42f11a/example-8.pdf
Dieses Dokument bezieht sich auf ältere ARM Versionen und nicht auf
Cortex-M mit thumb-only. Früher waren IRQ/FIRQ immer ARM-Code.
Cortex-M kennt nur thumb und die HW ruft Irqs mit C-Calling-Convention,
so daß man keine Spezial-Funktionen als Händler braucht.
Obigen Code (_irq _arm) darf der Compiler eigentlich nicht übersetzen.
Max M. schrieb:> Bernd K. schrieb:>> schreib das mal so:>> Das hatte ich tatsächlich auch schon mal so probiert, allerdings meldet> der Compiler:> Error[Ta098]: ARM mode is not available in this corehttps://www.iar.com/contentassets/e20cfa542d1a4734aa6b234bea42f11a/example-8.pdf
Das PDF liest sich auch so als ob das ziemlicher Krampf wäre. Angeblich
müssen dort alle IRQ zwingend als __arm definiert werden, können dann
aber keine normalen Thumb-Funktionen mehr aufrufen also muss alles was
die IRQ ihrerseits aufrufen will ebenfalls __arm sein, so ein
verkrampfter Krampf! Man will Thumb code haben auf so einem Controller!
Die Automobilbranche vielleicht mit ihren überdimensionierten Megabyte
Frameworks auf überdimensionierten CPUs, die sind alle schmerzbefreit
und merken nichts mehr weil sie eh schon lange nicht mehr wissen was sie
tun und nur noch auf meterdicken Abstraktionswolken aus generiertem Code
herumschweben den ganzen Tag lang, aber doch kein normaler Mensch!
Mein Rat: Nimm einen vernünftigen Compiler, schmeiß den Mist in die
Tonne.
Carl D. schrieb:> Obigen Code (_irq _arm) darf der Compiler eigentlich nicht übersetzen.
also dann muss er es so schreiben:
1
voidTIM2_IRQHandler(void){
2
undsoweiter
3
}
Und wenn der Linker funktioniert wie er soll dann findet er die Funktion
und ersetzt das schwache Symbol in der Vektortabelle mit einem Zeiger
auf diese Funktion und wirft sie nicht raus weil sie jetzt in der
Vektortabelle referenziert wird und die ganze Tabelle sollte KEEP sein
oder was auch immer das IAR-Äquivalent dazu ist.
@OP
Was steht denn im fertigen Kompilat in der Vektortabelle an der
betreffenden Stelle, ein Zeiger auf die Default-Endlosschleife oder ein
Zeiger auf Deine IRQ Funktion? Auch bei der Endlosschleife sollte er
nicht crashen.
Max M. schrieb:> wenn ich im Debug-Modus an diese Stelle gehe, ist da> aber ein NOP
Der versucht das zu disassemblieren, aber das sind Daten, kein Code.
Wenn ich das richtig sehe steht da die Adresse
0x8000f3af
Das kommt mir so bekannt vor! Nimm das Thumb bit am Ende weg und er
will nach
0x8000f3ae
springen, da hast Du Deine Hardfault-Adresse!
Beim Linken läuft irgendwas schief. Zeigen die alle nach 0x8000f3af?
Lass den Teil mal als Hexdump anzeigen dann sieht man es besser.
Bernd K. schrieb:> aber das sind Daten, kein Code.
Ich dachte, an der Stelle müsste ein entsprechender Jump auf die ISR
stattfinden (wenn alles normal funktionieren würde)?
Bernd K. schrieb:> da hast Du Deine Hardfault-Adresse.
Warum steht im STM Reference Manual "0x0000000C" als Adresse für
HardFault?
Max M. schrieb:> Bernd K. schrieb:>> aber das sind Daten, kein Code.>> Ich dachte, an der Stelle müsste ein entsprechender Jump auf die ISR> stattfinden (wenn alles normal funktionieren würde)?>> Bernd K. schrieb:>> da hast Du Deine Hardfault-Adresse.>> Warum steht im STM Reference Manual "0x0000000C" als Adresse für> HardFault?
Die Adresse der Adresse der Funktion!
Es wird der Inhalt von 0x0000000C in Register PC geladen.
PS: meine alten Augen haben vorhin die Adresse leicht modifiziert:
0x8000f3af, also thumb Mode 0x8000f3ae
Max M. schrieb:> Bernd K. schrieb:>> aber das sind Daten, kein Code.>> Ich dachte, an der Stelle müsste ein entsprechender Jump auf die ISR> stattfinden (wenn alles normal funktionieren würde)?>
Der Startup code wird gar nicht dazugelinkt, das sieht nicht aus wie ein
Hexdump der Vektortabelle.
Normalerweise muss da eine array aus long stehen mit Zeigern auf alle
Interruptfunktionen. Sticht normalerweise sofort ins Auge wenn man den
Hexdump betrachtet.
> Bernd K. schrieb:>> da hast Du Deine Hardfault-Adresse.>> Warum steht im STM Reference Manual "0x0000000C" als Adresse für> HardFault?
Das ist die Adresse des Arrayelements in dem steht wo er hinspringen
soll bei einem Hardfault.
Du hast oben gepostet da tritt ein Hardfault auf an Adresse 0x8000f3ae
und wenn er z.B. versucht den Timerinterrupt aufzurufen schaut er an
0x000000B0 nach und liest dort 4 Bytes welche ihm sagen wohin er
springen soll. Bei Dir steht da er soll nach 0x8000f3fe springen wo
natürlich nichts ist und dann krachts. Scroll mal hoch, Du hast gepostet
er meldet einen Hardfault bei 0x8000f3fe. Das ist der Grund.
Es sieht so aus als würde beim Linken der Startup code nicht mit
dazugelinkt. Überprüfe nochmal die build konfiguration, der Startup muss
assembliert und dazugelinkt werden, mach ihn Teil des Projekts oder wie
auch immer das bei IAR funktioniert.
Carl D. schrieb:> Die Adresse der Adresse der Funktion!
Ah, okay! Wie wird aus AFF3 die Adresse 8000F3AF? Liegt das an der
Little-Endian Notation?
An der Adresse ist aber auch nix.
Bernd K. schrieb:> Bei Dir steht da er soll nach 0x8000f3fe springen wo> natürlich nichts ist und dann krachts.
Achso, jetzt ist mir das klar, danke.
Max M. schrieb:> Little-Endian Notation?
Genau. Lies es rückwärts: dann steht da 8000F3AF. Dann noch das
niederste Bit löschen (das zeigt bei einem Sprung an daß das Ziel Thumb
code ist) und dann steht da 8000F3AE und das ist genau die selbe
Adresse an der es vorhin bei Dir gekracht hat weil da kein gültiger Code
steht.
Das ist sogar außerhalb des Flash, deshalb der bus error.
Es ist ein WUNDER daß er überhaupt losgelaufen ist. Zeig mal das
disassembly von Adresse 0 aus an (oder von 0x8000000 eigentlich) vor
allem was steht in den ersten 8 byte.
Und mach das Fenster bitte etwas größer daß man mehr als 2 zeilen sieht.
Bernd K. schrieb:> Zeig mal das> disassembly von Adresse 0 aus an (oder von 0x8000000 eigentlich) vor> allem was steht in den ersten 8 byte.
Es wird eine Vektor-Tabelle angelegt.
Ich hab leider gar keine Ahnung, woran das liegen könnte. Danke für
deine Hilfe bisher.
Ich hab die Linker-Einstellungen auf Default zurück gesetzt, hat nix
geholfen.
Die ist doch viel zu kurz!
Wenn der Eintrag für Timer Interrupt an Adresse 0xB0 stehen soll kann
doch die Tabelle nicht schon bei 0x3c enden!
Falscher Startup code gelinkt?
Nicht einfach nur irgendwelche Einstellungen blind resetten sondern in
die Projekteinstellungen gehen und gezielt schauen was alles kompiliert
und was alles gelinkt werden soll.
Jo mei,
im "EWARM_DevelopmentGuide.ENU.pdf" wird auf einer knappen Seite
erklaert, was bei Cortex-M Interrupts zu beachten ist.
Die sollte Mann vielleicht einfach mal lesen.
Ich will ja nicht schon wieder das Thema erwähnen aber ich hab recht
früh gemerkt daß man das mit Makefiles zigmal besser unter Kontrolle
halten kann was wann wie aufgerufen wird mit welchen Dateien und welchen
Optionen, nicht in zwölf verschachtelten Dialogen versteckt und in einer
anderen Sprache geschrieben als es später ausgeführt wird. Nur so am
Rande.
(º°)·´¯`·.¸¸.·´¯`·.¸¸.·´¯`·.¸¸.·´¯`·.¸¸.·´¯`·.¸¸.· schrieb im Beitrag
#5397954:
> im "EWARM_DevelopmentGuide.ENU.pdf" wird auf einer knappen Seite> erklaert, was bei Cortex-M Interrupts zu beachten ist.
Interrupts haben wir schon durch, danke. Guten Morgen.
Sagst Du uns noch kurz auf welcher Seite steht wie man einstellt wie der
richtige Startup code gelinkt werden soll?
Und dann postest Du vielleicht noch den Inhalt denn das von dir erwähnte
Paper ist hinter einer Paywall! Welcher vernünftige Mensch soll denn so
einen Schrott kaufen wenn man nicht mal vorher einen Blick in die
Bedienungsanleitung werfen darf? Ich bleibe bei meiner Meinung.
Aber du hast es ja schon gelesen, also hilf dem OP doch einfach oder
kannst Du das nicht? Dachte ich mir schon.
Will Mann in einem Projekt seinen eigenen Startup code verwenden,
fuegt Mann dem einfach dem Projekt hinzu. (Project -> Add Files)
Einstellen muss Mann da nichts.
Das doch einfach :-).
Das der dann natuerlich genaustens passen muss, versteht sich
wohl von selbst.
Also z.B.: startup_stm32l1xx_mdp.s
Braucht Mann fuer Interrupts aber eigentlich nicht,
weil die Symbole dort nur mit pubweak exportiert werden
und damit leicht mit eigenen Konstrukten ueberschrieben
werden koennen.
P.S.
Ich benutze regelmaessig eher eigenen Startupcode, damit
ich den Systeminit selber machen kann:
Reset_Handler
;; LDR R0, =SystemInit
;; BLX R0
LDR R0, =__iar_program_start
BX R0
und die Vectoren sehen etwa so aus:
DATA
__vector_table
DCD sfe(CSTACK)
DCD Reset_Handler ; Reset Handler
DCD NMI_Handler ; NMI Handler
DCD HardFault_Handler ; Hard Fault Handler
DCD MemManage_Handler ; MPU Fault Handler
...
DCD DMA2_Channel5_IRQHandler ; DMA2 Channel 5
DCD AES_IRQHandler ; AES
DCD COMP_ACQ_IRQHandler ; Comparator Channel Acquisition
dann folgen die schwachen Definitionen:
...
PUBWEAK SysTick_Handler
SECTION .text:CODE:REORDER(1)
SysTick_Handler
B SysTick_Handler
...
Will Mann selber einen SysTick_Handler schreiben, tut Mann
das einfach in einem seiner Quelltexte des Projekts.
Also Max, hast Du's gelesen? Versuch mal den richtigen Startup code
finden und zum Projekt hinzufügen (und natürlich evtl den falschen
entfernen).
Dann nochmal kompilieren und einen Blick auf das Disassembly werfen, die
Vektortabelle müsste deutlich länger sein mindestens bis 0x80000b0
reichen und dann sollte auch die IRQ-Funktion nicht mehr rausgeworfen
werden.
Und evtl brauchst Du auch noch das korrekte Linker script, ich weiß
nicht ob IAR das Konzept eines Linkerscripts kennt, aber wahrscheinlich
schon, anders gehts ja wohl kaum. Das muss man auch irgendwo einstellen
können.
Gibts da denn wirklich keine fertigen Projekt-templates oder
vorgefertigte Einstellungen für diesen Controller? So in der Art
Project->New->STMicrosystems->STM32-whatever und schwupps ist das
Grundgerüst da das man dann modifizieren kann? Das ist doch die
Vorgehensweise die die Zielgruppe bevorzugt, manche Tools machen es
einem extrem schwer dagegen anzukämpfen und vom Pfad abzuweichen.
Deshalb bevorzugen viele nach einiger Zeit auch lieber wieder rein
scriptgesteuerte Build-Tools wo man den Buildvorgang genauso textuell
programmieren kann wie man das eigentliche Programm programmiert was
sich eigentlich auch ganz gut trifft da man sich ja eh grad mit
Programmierung beschäftigen will und weniger mit Klickgrammierung und
Dialogtrübfischerei. Nur so am Rande.
(º°)·´¯`·.¸¸.·´¯`·.¸¸.·´¯`·.¸¸.·´¯`·.¸¸.·´¯`·.¸¸.· schrieb im Beitrag
#5397996:
> Will Mann selber einen
Man schreibt es mit einem n, nicht mit 2. Es schmerzt sonst beim Lesen
ganz erheblich. Und außerdem schreibt man es klein. Alles andere war
soweit ok auf den ersten Blick. Danke im Voraus für Dein Verständnis.
> Gibts da denn wirklich keine fertigen Projekt-templates oder> vorgefertigte Einstellungen für diesen Controller?
Ei sischa gibts die.
Aber ein paar Defines gehoeren bei ST dann trotzdem dazu.
Die landen dann zwar nicht in einem Makefile sondern
in den Projekteigenschaften.
z.B. STM32L1XX_MDP
Blind stochern und umherklicken muss ich da uebrigens nicht.
Und Linkerscripts gibts natuerlich auch.
Und Debuggerscripte obendrein auch.
Und, alle IAR Compiler sind da in etwa gleichgestrickt,
egal ob 8051, RL78, RX62, MSP430, STM8, V850, 8096 oder Z80.
Und es gibt noch mehr unterstuetzte Controller.
Vermissen tue ich eigentlich nur die CPU32 von Motorola.
Aber wer die Handbuecher nicht liest wird halt ewig nur im
Regen stehn.
> Alles andere war soweit ok auf den ersten Blick.
Ich habe vermutlich eine Größenordnung mehr Controller,
Compiler und Entwicklungsumgebungen gesehen und damit
gearbeitet als du dir ueberhaupt vorstellen kannst.
Insoweit bin ich an irgendwelchen Approvals
deinerseits nicht uebermaessig interessiert.
Wenn du keine Ahnung von IAR-Compilern hast, die
Dokumentation dazu weder beschaffen noch verinnerlichen
kannst, solltest zukuenftig vielleicht darauf
verzichten deinen Sempf dazuzugeben.
(º°)· schrieb:> Ich benutze regelmaessig eher eigenen Startupcode, damit> ich den Systeminit selber machen kann:
Magst du kurz beschreiben, welche Startupdatei standardmäßig verwendet
wird und wo die zu finden ist? In meinem IAR-Projektordner ist nämlich
keine.
Die startup_stm32f10x_md_vl.s enthält alle IRQ-Handler, die Datei findet
sich unter:
\arm\RTOS\SEGGER\ST\STM32F100\Start_STM32F100_Discovery\DeviceSupport
Die wird also anscheinend nicht verwendet.
Edit: Okay, ich hab dieses startup-File meinem Projekt hinzugefügt und
jetzt klappt alles - endlich!
(º°)·´¯`·.¸¸.·´¯`·.¸¸.·´¯`·.¸¸.·´¯`·.¸¸.·´¯`·.¸¸.· schrieb im Beitrag
#5398038:
>> Alles andere war soweit ok auf den ersten Blick.>> Ich habe vermutlich eine Größenordnung mehr Controller,
Deine Vermutung ist vermutlich falsch.
> verzichten deinen Sempf dazuzugeben.
Das schreibt man "Senf".
Leidenschaftliche Programmierer neigen dazu ein hervorragendes
Sprachgefühl zu haben und können überdurchschnittlich gut mit Syntax und
Grammatik umgehen, schließlich ist das ihr täglich Brot.
Im Nachhinein betrachtet ist es mir anscheinend gelungen ohne auch nur
einen Fetzen Dokumentation von IAR per Ferndiagnose das Problem korrekt
zu identifizieren und habe festgestellt daß er den falschen Startup-Code
verwendet und die wahrscheinliche Lösung in der unbekannten IDE
(richtige Datei zum Projekt hinzufügen) genannt bevor Du Dich überhaupt
zu Wort gemeldet hast.
Und als Du Dich dann gemeldet hast hast Du am Thema vorbei eine
dümmliche ominöse Andeutung über eine Seite in einem kostenpflichtigen
Dokument über Interrupts gemacht (ohne jedoch Details zu nennen) obwohl
es Dir als extremer Überfachmann der Du angeblich sein willst sofort
hätte klar sein sollen daß das Thema Interrupt zu dem Zeitpunkt schon
abgefrühstückt war und es nur noch um den falschen Startup code ging.
Bei mir könntest Du keinen beruflichen Blumentopf erben, ich brauche
Leute mit exzellenten analytischen Fähigkeiten. Und Rechtschreibung die
einem nicht die Schuhe auszieht.
> dümmliche ominöse Andeutung über eine Seite in einem kostenpflichtigen> Dokument
Die ist Bestandteil der Installation.
Die kostenlose Kickstartversion enthaelt die auch.
Oder die EVal.
Nur mit dem Lesen hapert es wohl.
Wenn deine beruflichen Projekte mit derselben Elle gemessen
als gelungen durchgehen, da spar ich mir mal weitere Worte.
(º°)·´¯`·.¸¸.·´¯`·.¸¸.·´¯`·.¸¸.·´¯`·.¸¸.·´¯`·.¸¸.· schrieb im Beitrag
#5398279:
>> dümmliche ominöse Andeutung über eine Seite in einem kostenpflichtigen>> Dokument>> Die ist Bestandteil der Installation.
Du hast wohl wirklich eine Leseschwäche! Ich besitze keine Installation
von IAR und brauche und will auch keine. Ich habe das Problem des
Threaderstellers blind gelöst. Und ich kann auch ohne die von Dir
angedeutete aber nicht genannte Seite gelesen zu haben sagen daß sie in
diesem Fall nicht im Geringsten relevant gewesen wäre.
> Und ich kann auch ohne die von Dir> angedeutete aber nicht genannte Seite gelesen zu haben sagen daß sie in> diesem Fall nicht im Geringsten relevant gewesen wäre.
Diese Leseschwaeche scheinst du ja mit dem TO zu teilen.
(º°)·´¯`·.¸¸.·´¯`·.¸¸.·´¯`·.¸¸.·´¯`·.¸¸.·´¯`·.¸¸.· schrieb im Beitrag
#5398293:
>> Und ich kann auch ohne die von Dir>> angedeutete aber nicht genannte Seite gelesen zu haben sagen daß sie in>> diesem Fall nicht im Geringsten relevant gewesen wäre.>> Diese Leseschwaeche scheinst du ja mit dem TO zu teilen.
Jetzt hab ich endlich deinen Nick verstanden:
Blindschleiche
Hast du eigentlich irgendwas von dem was Bernd geschrieben hat
verstanden?
(º°)·´¯`·.¸¸.·´¯`·.¸¸.·´¯`·.¸¸.·´¯`·.¸¸.·´¯`·.¸¸.· schrieb im Beitrag
#5398293:
>> Und ich kann auch ohne die von Dir>> angedeutete aber nicht genannte Seite gelesen zu haben sagen daß sie in>> diesem Fall nicht im Geringsten relevant gewesen wäre.>> Diese Leseschwaeche scheinst du ja mit dem TO zu teilen.
Jetzt werd mal nicht pampig! Du hast nichts zur Lösung beigetragen außer
auf explizite Nachfrage hin endlich zu wiederholen was ich bereits 2
Stunden vorher als korrekte Lösung vorschlug ("Datei mit richtigem
Startup zum Projekt hinzufügen, falschen entfernen") nachdem ich die
Ursache bereits gefunden hatte.
Du hast den Thread nicht gelesen (zumindest nicht sinnentnehmend) und
stattdessen am Thema vorbei fabuliert. Und jetzt unterstellst Du mir
eine Leseschwäche weil ich ein Dokument das ich nichtmal besitze nicht
gelesen habe? Seltsame Definition von "Leseschwäche" hast Du da.
PS: Hast Du nicht auch die leise Vermutung daß Leseschwäche und
Rechtschreibschwäche korrelieren? Ich hab keine belastbaren Zahlen aber
ich könnte es mir gut vorstellen.
Max M. schrieb:> Die startup_stm32f10x_md_vl.s enthält alle IRQ-Handler, die Datei findet> sich unter:> \arm\RTOS\SEGGER\ST\STM32F100\Start_STM32F100_Discovery\DeviceSupport>> Die wird also anscheinend nicht verwendet.
Kopiere diese Datei und die "system_stm32f10x.c" in Deinen
Projektordner. Dann klickst Du diese beiden Dateien unter Projekt->Add
Files zu Deinem Projekt hinzu. Nach dem Make (F7) findest Du in der
*.map-Datei die Referenz auf TIM2_IRQHandler.
Für ein lauffähiges Programm muss noch die passende *.icf-Datei unter
Options->Linker->Config eingetragen werden. "Override Default" anklicken
und unter arm/config/linker/ST/.. den betreffenden µC auswählen.
Selber habe ich nur die Kickstarter Version und auch kein F103-board.
Mit dem Simulator zu spielen, mag ich bei dem schönen Wetter heute nicht
;-)
(º°)·´¯`·.¸¸.·´¯`·.¸¸.·´¯`·.¸¸.·´¯`·.¸¸.·´¯`·.¸¸.· schrieb im Beitrag
#5398355:
> Ja, ausser einem gewissen religioesem Eifer deinerseits habe ich> nichts> gefunden was das Lesen gerechtfertigt haette.
Ich bin jetzt raus aus diesem Thread, Du kannst ja noch ein bisschen
weiter machen mit Deinem lächerlichen Auftritt hier wenn Du willst.