mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Interrupt Priorität beim STM32


Autor: Michael (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Mikrocontroller- Gemeinde,

ich habe eine Frage zu den Prioritäten des STM32F103.
Irgendwie ist das nämlich net so ganz sauber dokumentiert, wie ich 
finde.
Hier mal so, wie ich das Ganze verstehe:

- Die Prioritäten sind in Haupt- und Unterpriorität unterteilbar
- es werden hierfür 4 Bits verwendet
- es gibt 5 Gruppen, die diese 4 Bits für die Unterteilung in Haupt und
  Unterpriorität nutzten (z.B. 1 Bit für Haupt, 3 Bit für Unterprio. 
usw.).
- ein Interrupt mit einer höheren Priorität darf eine niedrigere
  Unterbrechen --> die höhere wird dann zunächst abgearbeitet, bevor in
  die niedrige zurück gekehrt wird. Hier eine frage: Wie schaut's da mit
  der Verwaltung des Stack's aus? Normal muss ich mich ja nich darum
  kümmern, weil der CORTEX M3 das selbst erledigt (Hardware) - aber bei
  Unterbrechung einer ISR auch?
- kann ich dem Systick die oberste Priorität zuordnen, so dass diese 
alle
  anderen ISR's unterbrechen darf? Ich hab's nämlich noch
  nicht hnbekommen :) Verwendet habe ich hierfür: 
NVIC_SetPriority(SysTick_IRQn, 
NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 0, 0));

Vielleicht findet sich ja ein STM - Erfahrener, der da behilflich sein 
kann ;)

Danke & viele Grüße

Autor: Hannes S. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich selbst versuche nested Interrupts zu vermeiden, wann immer möglich, 
aber ich glaube, dieser Abschnitt aus dem Programmers Manual könnte Dir 
weiterhelfen:

---
To increase priority control in systems with interrupts, the NVIC 
supports priority grouping.

This divides each interrupt priority register entry into two fields:
● An upper field that defines the group priority
● A lower field that defines a subpriority within the group.

Only the group priority determines preemption of interrupt exceptions. 
When the processor is executing an interrupt exception handler, another 
interrupt with the same group priority as the interrupt being handled 
does not preempt the handler.
---

Folglich müsste der Systick in Deinem Fall denn eben der einzige sein, 
der eine höhere group priority besitzt.

Und um den Stack musst Du Dich nur insofern kümmern, dass da genügend 
vorhanden ist...

Gruß,
Hannes

Autor: Michael (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Eigentlich möchte ich auch keine Nested Interrupts verwenden.
Möchte aber eigentlich den Systick nutzen, um zu bestimmten Zeiten (jede 
ms) einen Wert über SPI auszugeben. Daher sollte dieser in der Lage 
sein, ggf. auch andere Interrupts zu unterbrechen... Na mal schauen, wie 
ich das hingekomme :)
Dank Dir' auf jeden Fall für die Antwort!

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Michael schrieb:

> - ein Interrupt mit einer höheren Priorität darf eine niedrigere
>   Unterbrechen --> die höhere wird dann zunächst abgearbeitet, bevor in
>   die niedrige zurück gekehrt wird. Hier eine frage: Wie schaut's da mit
>   der Verwaltung des Stack's aus?

Nicht deine Sorge, der Stack muss nur gross genug sein.

Grad beim CM3 spricht rein garnix gegen IRQ-Nesting, der ist ja 
regelrecht dafür gebaut.

> - kann ich dem Systick die oberste Priorität zuordnen, so dass diese
> alle anderen ISR's unterbrechen darf?

Ja. Die Prio der System Exceptions, wozu auch der Systick zählt, ist 
übrigens von Haus aus schon 0, also maximal.

Allerdings fehlt mit in deinem Posting irgendwie eine konkrete Frage, 
eine die sich beantworten liesse ohne dabei ganze Bücher zu schreiben. 
Du schreibst ja nicht einmal, was funktioniert oder nicht funktioniert 
hat und wo dein Problem liegt.

Das Thema Gruppierung von Interrupts würde ich erst einmal grosszügig 
ignorieren.

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Michael schrieb:

> Irgendwie ist das nämlich net so ganz sauber dokumentiert, wie ich
> finde.

Was hast du denn an Doku bisher aufgetrieben?

Bischen was steht im "Insiders Guide" drin, aber m.E. zu knapp. Deutlich 
mehr steht im "The Definitive Guide to the ARM Cortex-M3" von Joseph 
Yiu. Eine sinnvolle Lektüre wie ich meine.

ST reicht im Cortex-M3 Programming Manual effektiv nur die Core-Doku von 
ARM durch, die haben den CM3 ja nicht selbst erfunden. Und diese Doku 
ist nicht wirklich als Anleitung geschrieben.

Autor: Hannes S. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ohne grouping wird's nicht gehen - nur ein Interrupt mit höherer group 
priority (in der Lib "preemption priority" genannt) kann einen anderen 
Interrupt unterbrechen.
Habe gerade mal meinen Code modifiziert und bin jetzt auch mit dem 
Systick etwas ratlos - mit RTC hingegen funktioniert es. Hier meine NVIC 
Config:

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);

NVIC_SetPriority(SysTick_IRQn, 
NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 0, 0));

NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);

NVIC_InitStructure.NVIC_IRQChannel = RTC_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);

In den TIM2 Irq Handler habe ich ein while(1); eingebaut. Der RTC 
interrupt unterbricht dieses und wird ausgeführt, der Systick hingegen 
nicht... strange... irgendwelche Ideen?

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hannes S. schrieb:

> Ohne grouping wird's nicht gehen - nur ein Interrupt mit höherer group
> priority (in der Lib "preemption priority" genannt) kann einen anderen
> Interrupt unterbrechen.

Was andersrum gemeint. Wenn nichts konkret dagegen spricht, dann kann 
man alle 4 Bits als preeption priority konfigurieren - ist wohl auch 
default.

Zu dem CMSIS Kram kann ich nicht viel sagen, der ist mir zu umständlich.

Ist der Systick Interrupt überhaupt eingeschaltet? Die bisherigen 
Schnipsel enthalten dazu nichts.

Autor: Hannes S. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hab's gerade rausgefunden, woran es lag: Der Aufruf von SysTick_Config() 
ist der übeltäter, denn hier wird offensichtlich nochmal in der Lib an 
der Priotrity gedreht. Wenn man DANACH NVIC_SetPriority() aufruft, dann 
tut es wie es soll. Also in meinem Fall:

  SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);
  SysTick_Config(0x9000);
  NVIC_SetPriority(SysTick_IRQn,
       NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 0, 0));

Jau, und die Frage was der Default-Mode ist: Meiner Meinung nach ist 
nach dem Reset kein Grouping aktiviert also NVIC_PriorityGroup_0. 
Allerdings hatte ich das in meinem Code auch immer explizit drinstehen. 
Aber Dein Vorschlag alle Bits zur preemption zu nutzen sollte natürlich 
auch gangbar sein (NVIC_PriorityGroup_4).

Autor: Michael (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Hannes S.

Vielen Dank! Das war's auch bei mir ;)
Hat mir sehr geholfen!

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hannes S. schrieb:

> Jau, und die Frage was der Default-Mode ist: Meiner Meinung nach ist
> nach dem Reset kein Grouping aktiviert also NVIC_PriorityGroup_0.

Das Feld im Register SCB_AIRCR ist ab Reset 0, ein Wert der für 7 
Preemption-Bits und ein Subprio-Bit steht und bei 4 Prio-Bits daher 
überhaupt nicht definiert ist ;-).

Faktisch heisst das wahrscheinlich, dass ab Reset alle 4 Bits als 
Preemption-Bits verstanden werden, man aber saubererweise was anderes 
(z.B. 3) reinschreiben sollte. Man aber jedenfalls aber nicht das 
reinschreiben sollte, was vorher drinstand.

Autor: Michael (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So, nochmal genauer zur Lösung des Problems:

Beim Aufruf der Funktion SysTick_Config() wird mit
NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1); 

Die Priorität für den Systick auf 15 gesetzt. Also die niedrigste!

Wenn die Systick Priorität verändert werden soll, muss dies also nach 
dem SysTick_Config() Aufruf erfolgen!

Autor: Lutz (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Michael schrieb:
> Beim Aufruf der Funktion SysTick_Config() wird ...Die Priorität für den
> Systick auf 15 gesetzt. Also die niedrigste!

Na ob das wohl so von den Erschaffern gewollt ist ...
Der eine oder andere von Euch kennt vielleicht diesen Thread? 
Beitrag "CMSIS und die Interrupt-Prioritäten"

Autor: Marcus Harnisch (mharnisch) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Lutz schrieb:
> Na ob das wohl so von den Erschaffern gewollt ist ...

Anscheinend. Ich habe dieses Verhalten vor etwa zwei Jahren bei Keil 
bemängelt und bekam die Antwort, dass man in den meisten RTOS 
Situationen den SysTick mit niedrigster Priorität belegen möchte. CMSIS 
bediene hier den wahrscheinlichsten Fall.

Wenn es denn wenigstens dokumentiert wäre...

Gruß
Marcus

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.