STM32-Interrupts und C++ passen nicht gut zusammen [duplizieren]

Ich habe TIM3 so eingerichtet, dass es einen Interrupt in meinem Projekt auslöst, und es würde einfach nicht funktionieren. Ich habe alles versucht, was ich konnte, und konnte immer noch nicht finden, was das Problem ist. Dann habe ich ein sauberes Projekt erstellt und nur den Code kopiert/eingefügt, der TIM3 und Interrupts einrichtet, und es hat auf magische Weise funktioniert. Ich habe buchstäblich einen halben Tag damit verschwendet, herauszufinden, was das Problem verursacht, und es stellt sich heraus ... Interrupts mögen C++ nicht.

Ich habe meinen Code in C++ geschrieben, weil ich Klassen in meinem Projekt benötigte, also habe ich natürlich alle meine prject .c-Dateien in .cpp umbenannt und auch mit der Direktive --cpp kompiliert. Alles funktionierte gut, bisher keine Probleme, bis ich mich entschied, Interrupts zu verwenden. Also habe ich alles in .c umbenannt und alles hat funktioniert, alles wieder in cpp umbenannt und es hat aufgehört zu funktionieren.

Ich verwende Keil uVision5 und meine Projekte werden mit STM32CubeMX generiert (nur RCC-Konfiguration).

Ist jemandem das passiert? Irgendwelche Problemumgehungen?

Möglicherweise haben Sie Probleme mit der C- vs. C++-Verknüpfung - Ihr Interrupt-Handler unterliegt wahrscheinlich einer C++-Namensverstümmelung, sodass er nicht den standardmäßigen schwachen Interrupt-Handler ersetzt, den CubeMX bereitstellt.
Ich habe gerade die Lösung gefunden, und es ist genau das, was Sie gesagt haben. Komisch, wie ich einen halben Tag damit verschwendet habe, nach einer Lösung zu suchen, nur um sie ein paar Minuten nach dem Posten der Frage zu finden.
Dies ist tatsächlich ein sehr bekanntes Problem bei Embedded. Es überrascht mich etwas, dass angemessen gewählte Suchbegriffe nicht sofort einen der Dutzende von Links zu Keil-Foren, TI-Foren, StackOverflow usw. ergaben, die ich zu bekommen scheine, wenn ich es versuche.

Antworten (1)

Ich habe einen halben Tag nach einer Lösung gesucht, nur um sie ein paar Minuten, nachdem ich diese Frage gepostet habe, zu finden. Die Antwort gibt dieser Beitrag:

Fehler im Keil ARM-Compiler mit Interrupt-Handlern und C++?

Die "schwache" Referenz bedeutet nur, dass die Routine durch eine gleichnamige Routine in Ihrem Code ersetzt wird. Wenn Sie C verwenden, ist dies einfach, die Namen sind immer identisch, aber der C++-Name verstümmelt die Funktionen (zum Überladen von Funktionen usw.), sodass der kompilierte Name wahrscheinlich nicht mit dem Standard-ISR-Namen übereinstimmt. Sie müssen die Funktion (oder zumindest eine Vorwärtsreferenz, ich bin mir der Einzelheiten nicht sicher, da ich hauptsächlich in C arbeite) in einen externen "C"-Wrapper umschließen, um den Compiler zu zwingen, den Namen nicht zu manipulieren.

extern "C" { void SysTick_Handler(void) { // mache was auch immer } }

Oder Sie können es einfach als deklarieren

extern "C" void SysTick_Handler(void);

Sie müssen es also nicht einwickeln.