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.
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_SetPriority
oder 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_ASSERT
sie 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
SCB->SHPR{1,2,3}
im Programmierhandbuch.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?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.
Tut
Andreja Ko
Sean Houlihane
Andreja Ko
folgte Monica zu Codidact