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
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
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!
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.
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.
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?
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.
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).
@Hannes S. Vielen Dank! Das war's auch bei mir ;) Hat mir sehr geholfen!
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.
So, nochmal genauer zur Lösung des Problems: Beim Aufruf der Funktion SysTick_Config() wird mit
1 | 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!
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"
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
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.