Was ist der Unterschied zwischen dem Festlegen von SysTick Interrupt in NVIC und der Verwendung als Ausnahme?

Ich verwende eine STM32F303-MCU und habe festgestellt, dass der SysTick so eingerichtet werden kann, dass er eine Ausnahme verursacht, die in verschiedenen Benutzerhandbüchern ziemlich häufig erwähnt wird. Auf diese Weise hat es eine höhere Priorität als normale Interrupts.

Andererseits scheint es möglich zu sein, Systick auch in NVIC als Interrupt einzurichten. Es hat seine eigene Interrupt-Anforderungsnummer und es scheint, dass es in den Wartestatus versetzt werden kann. Da die NVIC-Interrupts programmierbare Prioritätsstufen haben, könnten wir es auch so einrichten.

Ich bin mir nicht sicher, was der Unterschied zwischen diesen beiden Ansätzen mit dem SysTick ist.

Nur ein Schuss ins Blaue: Ist Ihr Programm zufällig in C++? Denken Sie in diesem Fall daran, dass Sie Ihren SysTick_Handler oder seine Deklaration in 'extern "C"' einschließen müssen.
@Tut Nein, in diesem Fall ist es reines C, aber danke für den Tipp!
Können Sie Ihren zweiten Absatz erweitern, vielleicht mit Beispielen. Ich frage mich, ob hier eine subtile Verwirrung vorliegt. Das NVIC verarbeitet alle Ausnahmen, einschließlich IRQs.
@ Sean Houlihane Du hast es auf den Punkt gebracht! Ich steige gerade nach mehreren Jahren Matlab wieder in die ARM-Programmierung ein. Ich habe ein Projekt von einem leitenden Entwickler in meiner Firma erhalten, der systematisch versucht, SysTick so zu verwenden, als wäre es ein normaler Interrupt, was zu meinem zweiten Absatz, subtiler Verwirrung und zahlreichen Bus- und harten Fehlern führt.
@AndrejaKo siehe meine aktualisierte Antwort, um schnell alle Stellen zu finden, an denen SysTick als Interrupt behandelt wird.

Antworten (2)

Vorab ein paar Definitionen:

Im Cortex-M-Programmierhandbuch ist eine Ausnahme alles, was den normalen Programmfluss unterbricht und einen Handler aus der Vektortabelle aufruft, und Interrupts sind eine Teilmenge von Ausnahmen, die von den Peripheriegeräten außerhalb des ARM-Kerns kommen. Da SysTick im Cortex-M-Kern implementiert ist, wird es als Ausnahme, aber nicht als Interrupt betrachtet.

Ausnahmen haben eine Ausnahmenummer , beginnend bei 0. Interrupts haben eine IRQ-Nummer , beginnend bei 0. Da alle Interrupts Ausnahmen sind, erhalten sie alle eine Ausnahmenummer, die um 16 höher ist als die IRQ-Nummer. Die Ausnahmen, die keine Interrupts sind (einschließlich SysTick), haben Ausnahmenummern im Bereich von 0–15, kleiner als die Ausnahmenummern der Interrupts. Etwas verwirrenderweise haben Ausnahmen, die keine Interrupts sind, auch IRQ-Nummern, die per Erweiterung in den Bereich von -16 bis -1 fallen. SysTick hat die Ausnahmenummer 15 und die IRQ-Nummer -1.

Ich verwende eine STM32F303-MCU und habe festgestellt, dass der SysTick so eingerichtet werden kann, dass er eine Ausnahme verursacht, die in verschiedenen Benutzerhandbüchern ziemlich häufig erwähnt wird. Auf diese Weise hat es eine höhere Priorität als normale Interrupts.

Alle Ausnahmen außer Reset, NMI und Hardfault haben konfigurierbare Prioritäten. Es ist nur für Interrupts und andere Ausnahmen anders konfiguriert. Sehen Sie sich die CMSIS-Implementierung als klares Beispiel an:

__STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
{
  if ((int32_t)(IRQn) < 0)
  {
    SCB->SHP[(((uint32_t)(int32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL);
  }
  else
  {
    NVIC->IP[((uint32_t)(int32_t)IRQn)]               = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL);
  }
}

Sie können direkt aufrufen NVIC_SetPriorityoder manipulieren SCB->SHP, um SysTick eine niedrigere Priorität als jedem anderen Interrupt zu geben.

SysTick hat zwar eine Default -Prioritätsstufe, die höher ist als jeder Interrupt, aber das liegt nur daran, dass beim Reset alle Prioritäten auf 0 gesetzt werden und bei Gleichstand die niedrigere IRQ-Nummer gewinnt, in diesem Fall SysTick mit -1.

Andererseits scheint es möglich zu sein, Systick auch in NVIC als Interrupt einzurichten. Es hat seine eigene Interrupt-Anforderungsnummer und es scheint, dass es in den Wartestatus versetzt werden kann. Da die NVIC-Interrupts programmierbare Prioritätsstufen haben, könnten wir es auch so einrichten.

Nur Interrupts sind über die NVIC-Register konfigurierbar, und SysTick ist kein Interrupt. NVIC-Register haben keinen Platz für negative IRQ-Nummern, in Bitmasken oder anderswo.

SysTick kann tatsächlich in einen ausstehenden Zustand versetzt werden, aber das geschieht über SCB->ICSR, nicht in NVIC.

Beachten Sie, dass NVIC_SetPriority()und NVIC_GetPriority()die einzigen NVIC_-Funktionen in CMSIS sind, die mit negativen IRQ-Nummern richtig umgehen. Andere Funktionen mögen NVIC_SetPendingIRQ()oder NVIC_EnableIRQ()akzeptieren einfach negative IRQ-Nummern, führen ein Bit-Shuffling durch, was zu einem RIESIGEN Offset von den NVIC-Registern führt, und kritzeln eine weit entfernte Speicheradresse, was möglicherweise einen Hardfault oder ein anderes seltsames Verhalten verursacht. HAL_NVIC_-Funktionen führen einige Begrenzungsprüfungen durch, wenn Sie USE_FULL_ASSERTsie in Ihren Headern aktivieren, aber ansonsten lassen sie nur ungültige Parameter an die CMSIS-NVIC-Funktionen durch.

BEARBEITEN

Es gibt einen netten Trick, um alle Stellen zu finden, an denen eine Funktion mit einem negativen Parameter aufgerufen wird. Fügen Sie dies in einen gemeinsamen Header ein:

#define NVIC_EnableIRQ(x) ((void)sizeof(char[x]))

Es ist ein Kompilierzeitfehler, wenn dieses Konstrukt mit einer negativen Zahl aufgerufen wird. Wiederholen Sie dies für jede NVIC-Funktion außer NVIC_SetPriority() und NVIC_GetPriority().

Der grundlegende Unterschied zwischen Systick- und Peripherie-Interrupts besteht darin, dass der Systick von ARM auf IRQ 6 (0x003C) festgelegt wird, wenn er im Kern verfügbar ist.
Es ist auch Teil des ARM Cortex, von der gleichen Uhr getaktet und damit synchron.

Die anderen Ausnahmen (Interrupts) sind Sache des Herstellers, um zu entscheiden, welche Basispriorität (Offset) und Quelle sie haben.

Aus dem ST-Programmierhandbuch (PM0056):

Eine SysTick-Ausnahme ist eine Ausnahme, die der Systemzeitgeber generiert, wenn er Null erreicht. Software kann auch eine SysTick-Ausnahme generieren. In einer OS-Umgebung kann der Prozessor diese Ausnahme als System-Tick verwenden.

Ein Interrupt oder IRQ ist eine Ausnahme, die von einem Peripheriegerät signalisiert oder durch eine Softwareanforderung generiert wird. Alle Interrupts sind asynchron zur Befehlsausführung. Im System

Ausnahmeprioritäten sind bei der Cortex-M-Serie konfigurierbar, mit Ausnahme von Reset, NMI und Hardfault. Siehe die Beschreibung von SCB->SHPR{1,2,3}im Programmierhandbuch.
@berendi Das ist richtig. Aber sie nennen jeden Interrupt eine Ausnahme, da es sich um eine Ausnahme vom normalen Programmablauf handelt.
@ Jeroen3 The fundamental difference between the systick and peripheral interrupts is that the SysTick is guaranteed to be at priority 6 (0x003C) when it is available in the core. It is also part of the ARM Cortex, clocked by the same clock and thus synchronous.alles hier ist nicht die Wahrheit. Er hat keine garantierte Priorität und kann von einer anderen Taktquelle als dem Kerntakt getaktet werden (wenn Referenztakt von der Implementierung bereitgestellt wird). Was ist das Quelldokument dieser Enthüllungen?
@ PeterJ_01 Garantiert ist vielleicht nicht das richtige Wort. Kennen Sie Teile mit einem asynchron getakteten Systemtick ?
Wie der interne Taktbaum aufgebaut ist, liegt zu 100% beim Chiphersteller. Es spielt keine Rolle, ob es irgendwelche handelsüblichen Chips gibt. Nur dieser Teil Ihrer Antwort ist zu 100% falsch. Guaranteed might indeed not be the correct word- Es ist nicht das falsche Wort, es ist Ihre falsche Annahme, dass SysTick eine konstante Priorität hat. Aber es ist dasselbe wie jeder andere Interrupt mit Ausnahme von HW-Ausnahmen, die feste Prioritäten haben. IMO Ihre Antwort ist irreführend und falsch und sollte gelöscht werden.
Wenn die von ARM bereitgestellte Logik das Taktsignal an den Systick-Zähler wie an andere Teile des Kerns weiterleitet (was ich ziemlich sicher bin), wie könnte ein Chiphersteller Systick nicht synchron machen?
@supercat Genau, das kannst du nicht.
@PeterJ_01 Es wird immer noch IRQ 6 sein. Aber Sie können die Prioritätsgruppen im NVIC ändern. Aber es wird immer 6 sein, in jedem Cortex, den du bekommst.
IRQ Nummer 6 nicht die Priorität 6, was einen großen Unterschied macht. Jedenfalls ist die Nummer zweitrangig.
@PeterJ_01 Wenn keine Prioritäten festgelegt wurden, ist die Zahl die Priorität. Daher "Grundpriorität".