STM32F446- C Programmierung - unerwartetes springen in Infinite Loop

OP #6537968
Lesenswert?

Hallo,

ich arbeite mich gerade mit einem STM32F446 in die 
Microcontrollerprogrammierung in C ein. Aktuell schreibe ich einfache 
Interrupts, was auch funktioniert, bin hierbei aber auf ein, für mich, 
unerwartetes Verhalten gestoßen.
1
GPIO_PinConfig_t gpioa_config_5   = {GPIO_PIN_NO_5, GPIO_MODE_OUT, GPIO_LOW_SPEED, GPIO_PU,GPIO_OP_TYPE_PP,GPIO_AF5};
2
  GPIO_Handle_t gpioa_handle_5     = {(uint32_t*)(GPIOA_BASEADDR),gpioa_config_5};
3

4
  GPIO_PinConfig_t gpioc_config_13   = {GPIO_PIN_NO_13, GPIO_MODE_IT_FT, GPIO_LOW_SPEED, GPIO_PU,GPIO_OP_TYPE_PP,GPIO_AF5};
5
  GPIO_Handle_t gpioc_handle_13     = {(uint32_t*)(GPIOC_BASEADDR),gpioc_config_13};
6

7
  GPIO_PinConfig_t gpiob_config_2   = {GPIO_PIN_NO_2, GPIO_MODE_IT_FT, GPIO_LOW_SPEED, GPIO_PU, GPIO_OP_TYPE_PP,GPIO_AF5};
8
  GPIO_Handle_t gpiob_handle_2     = {(uint32_t*)(GPIOB_BASEADDR),gpiob_config_2};
9
    
10

11
  GPIO_Init(&gpioa_handle_5);
12
  GPIO_Init(&gpiob_handle_13);
13
  GPIO_Init(&gpioc_handle_2);

An Port A hängt eine LED, an C Pin 15 ein Taster und B Pin 2 soll über 
Kabel den Input auf GND ziehen. Durch C15 und B2 soll jeweils ein 
Interrupt ausgelöst werden und die LED zum blinken bringen, was auch 
funktioniert.

Allerdings springt das Programm in den Default Handler(Infinite Loop) 
nach Init von Port C  wenn:
1.
1
 GPIO_Init(&gpioa_handle_5);
2
      GPIO_Init(&gpioc_handle_13);
3
      GPIO_Init(&gpiob_handle_2);
Die Reihenfolge der Initalisierung von Port B und C vertauscht wird.


2.
Init von Port B gar nicht verwendet wird, aber der struct vorher 
trotzdem für Port B drin ist.

Wird die Iinitalisierung des structs auskommentiert, funktioniert das 
Programm alleine mit Port C wieder wie erwartet.


Kann mir jemand erklären, wieso zum einen die Reihenfolge  eine Rolle zu 
spielen scheint, in der die Funktion GPIO_Init jeweils für Port B und C 
ausgeführt werden und zum anderen, wieso das nicht initialisieren von 
gpiob_handle_2 wieder dazu führt, dass für den Port C das Programm nicht 
abstürzt?
Gast #6539275
Lesenswert?

Hi Jannik,

ohne eine wirklich brauchbare Antwort parat zu haben, kann ich dir 
sagen, dass ich vor einiger Zeit ähnliche Symptome in meinem STM-based 
SDR radio hatte. Irgendwann hing sich das Programm auf, was genauer 
betrachtet einfach nur das Anspringen des Default Interrupt Handlers 
(mit siener endless loop) war. Letztlich hatte ich es versäumt, den 
korrekten (meinen eigenen) Interrupt Handler in die Int Table 
einzutragen. Das hatte ich durch das Lesen der Listings für die 
entsprechenden Module rausgefunden, dort stand noch der Default Handler 
drinne.

Ansonsten denke ich (noch) nicht unbedingt, dass es wirklich und 
wahrhaftig nur von der Reihenfolge der GPIO_Init-Routinen abhängt (lasse 
mich aber gerne vom Gegenteil überzeugen), vielleicht ist es einfach nur 
ein Timing Issue, bedingt durch das zitierte Kabel an dem einen Eingang, 
das evtl. nicht auf einem definierten Pegel liegt, sondern in der Luft 
hängt.

Suche auf jeden Fall mal weiter in Richtung "korrekt aufgesetzte 
Interrupt Handler". Viel Erfolg!
Gast #6539460
Lesenswert?

Neee,die Routinen-Bezeichnung im Debugger (Hard fault Handler) ist hier 
etwas irreführend. Tatsächlich sind eben alle nicht benutzten 
Interrupt-Vektoren mit einem Sprung zu diesem Default Handler versehen, 
um ein kontrolliertes verhalten zu erreichen. Es ist aber m.E. sehr 
wahrscheinlich einfach nur ein nicht initialisierter, jedoch 
getriggerter Interrupt.
Gast #6540532
Lesenswert?

Nochmal neee: die Int-Vektoren werden per Jump genutzt und nicht per 
Call. Also steht nirgendwo eine Return-Adresse. Es bleibt einzig das 
auslösende Int Flag. Aber natürlich ist das gesetzt/aktiv, hilft aber 
nicht wirklich dabei, herauszufinden, warum nicht der eigene Int 
Handler, sondern der Default Int Handler genommen wird.

Man hört gar nichts mehr vom OP? Hat er das Problem evtl. schon in 
Eigenregie gelöst und lässt uns hier sinnlos weiter philosophieren? :-)

Wenn ja: lieber OP: dann teile doch Deinen Fehler - und die 
Lösungsfindung - hier mit, damit evtl. auch Andere davon profitieren 
können!
Gast #6540763
Lesenswert?

Thilo schrieb:
> Nochmal neee: die Int-Vektoren werden per Jump genutzt und nicht
> per Call. Also steht nirgendwo eine Return-Adresse.

Quatsch - wie sollte der Controller nach dem Interrupt denn dann da 
weitermachen, wo er vor dem Interrupt war? Natürlich gibt's irgendwo 
eine Return-Adresse.
Persönliche Seite #6540780
Lesenswert?

Nop schrieb:
> Thilo schrieb:
>> Nochmal neee: die Int-Vektoren werden per Jump genutzt und nicht
>> per Call. Also steht nirgendwo eine Return-Adresse.
>
> Quatsch - wie sollte der Controller nach dem Interrupt denn dann da
> weitermachen, wo er vor dem Interrupt war? Natürlich gibt's irgendwo
> eine Return-Adresse.

Und die liegt im 8x4er Packet auf dem Stack.

Ich vermute mal weil er (Thilo) im LR nix brauchbares finden konnte.
Das wäre dann eine ARMv4.

Ich empfehle mal die Bibel schlechthin
"The Definitive Guide to ARM Cortex-M3 and Cortex-M4 Processors"
von Joseph Yiu
OP #6546945
Lesenswert?

Vielen Dank vorab für die vielen Beiträge :)

@Thilo,
Zumindest kann durch das reine Wechseln der Reihenfolge dieses Verhalten 
getriggert oder auch behoben werden. Der Pin ist auf wird durch Pull Up 
auf High gezogen. Habe es auch mit anderen Pins, sollte also auch nicht 
an einen Defekt liegen.

@ Dennis. H

Also zumindest kein gewollter. Beim debuggen wird 
GPIO_Init(&gpioc_handle_2); noch ausgeführt, aber im nächsten Step 
landet man in der Infinite Loop.


Von Dennis H:
"Erstmal rausfinden was auslöste.

Die Adresse bei der Unterbrochen wurde steht im Stack (autom. stacking
R0-R3,R12,LR,PC,PSR).
Welcher Interrupt auslöste steht im IPSR. Im LR steht ein Spezialwert
fürs unstacking.
Beim Hardfault gibt es dies Adresse auch auf dem Stack und der Rest
steht im NVIC im HFSR."

Das werde ich mir mal ansehen, kann durch das debuggen, wie oben 
brereits erwähnt nicht erkennen, durch was der Interrupt ausgelöst wird.

"Sind die GPIO-Einheiten alle an ?
"GPIO_PeriClockControl"

Ja, da ist alles in Ordnung. B und C funktionieren ja unabhängig 
voneinander. Der Fall für B,C auch, wenn zuerst b initialisiert wird und 
dann c. Die Frage ist was z.B. das wechseln der Reihenfolge verändern 
könnte.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren