Wie teile ich meiner lieben CubeIDE denn mit, dass der SPI Interrupt
eine bestimmte Funktion einer Klasseninstanz aufrufen soll?
Mein erfolgloser Versuch bisher:
main.cpp
Ich weiß nicht ob man eine in C definierte Funktion in einer C++ Klasse
implementieren kann. Bzw. stelle es mir nicht gerade schön und
ungeeignet vor. Ansonsten nimm doch Pointer.
Die Memberfunktion kann in der Klassendefinition als 'static' deklariert
werden. Dann sind in der Funktion aber keine Zugriffe auf
Membervariablen möglich weil der this pointer fehlt. Den kann die ISR
auch nicht mitgeben, dafür ist dann eine Hilfsfunktion nötig.
Johannes S. schrieb:> Die Memberfunktion kann in der Klassendefinition als 'static' deklariert> werden. Dann sind in der Funktion aber keine Zugriffe auf> Membervariablen möglich weil der this pointer fehlt. Den kann die ISR> auch nicht mitgeben, dafür ist dann eine Hilfsfunktion nötig.
Ok, dass funktioniert jetzt. Also es wird fehlerfrei kompiliert. Hier
der aktuelle Code:
main.cpp
1
// global visible pointer to actual static member function of class
// pointer to static member function is declared outside of this file
2
extern(*Callback_SPI_Interface_Ptr)(void);
3
//...
4
voidSPI1_IRQHandler(void)
5
{
6
/* USER CODE BEGIN SPI1_IRQn 0 */
7
Callback_SPI_Interface_Ptr();
8
/* USER CODE END SPI1_IRQn 0 */
9
HAL_SPI_IRQHandler(&hspi1);
10
/* USER CODE BEGIN SPI1_IRQn 1 */
11
/* USER CODE END SPI1_IRQn 1 */
12
}
Eine Frage noch. Kann man das so machen. Oder gibt es da elegantere
Möglichkeiten. Ich bin immer wieder am überlegen, ob nicht C doch
sinnvoller wäre... Sehr unschlüssig...
Anonymous U. schrieb:> Ich bin immer wieder am überlegen, ob nicht C doch> sinnvoller wäre... Sehr unschlüssig...
Ich würde mal sagen wenn es schon an einem ISR scheitert, ist C
vielleicht doch die bessere Lösung. Schlussendlich kannst du den Komfort
von C++ eh nicht richtig genießen und musst dir wieder um jede
Speicherallokation Gedanken machen. Das kannst du auch in C haben. Es
gibt sicher Projekte, wo der zusätzliche Aufwand Sinn ergibt, aber oft
ist es auch sinnvoll, einfach beim Bewährten zu bleiben.
Anonymous U. schrieb:> Eine Frage noch. Kann man das so machen. Oder gibt es da elegantere> Möglichkeiten.
Warum krampfhaft in der main() eine Klasseninstanz anlegen und
einen globalen Pointer darauf? Gibt es dafür triftige Gründe?
oooops schrieb:> Anonymous U. schrieb:>> Eine Frage noch. Kann man das so machen. Oder gibt es da elegantere>> Möglichkeiten.>> Warum krampfhaft in der main() eine Klasseninstanz anlegen und> einen globalen Pointer darauf? Gibt es dafür triftige Gründe?
Meine Klassen benötigen eine bereits initialisierte HAL. Ich könnte zwar
eine init()-Funktion in die Klasse integrieren, aber wenn dieser Code im
Konstruktor steht, finde ich es schöner.
Felix U. schrieb:> Es> gibt sicher Projekte, wo der zusätzliche Aufwand Sinn ergibt, aber oft> ist es auch sinnvoll, einfach beim Bewährten zu bleiben.
Ich war lange am überlegen, ob ich C oder C++ verwenden sollte. Ich bin
da eher erstmal zögerlich Neuem gegenüber. Aber dann dachte ich zurück
an meine Anfänge mit ASM und wie ich mich erst gegen C gesträubt habe
:-) So here we go..
ich benutze mittlerweile auch viel C++ und sehe darin keinen Nachteil.
Dazu Mbed-os, das ebenfalls sehr konsequent C++ nutzt und auch das API
bietet alles in Klassen an.
Die Interrupts kann man da auch bequem im Usercode abarbeiten:
Im RAM ist ein Bereich für die Kopie der Interrupt Vektoren reserviert.
Die ISR kann fest in die Tabelle wenn sie zur Kompilierzeit bekannt ist,
kann aber zur Laufzeit einfach mit
1
voidNVIC_SetVector(IRQn_TypeIRQn,uint32_tvector);
umgebogen werden.
Für den Fall das man eine Methode als ISR nutzen möchte gibt es einen
Helfer names CThunk. Das ist eine Trampolin Funktion die sich einen
Callback merkt und als ISR arbeitet. Kostet zusätzliche indirekte calls,
aber die nehme ich für den Luxus in Kauf. Dafür spare ich mir die lange
universelle Behandlung in der HAL ISR.
Der Vorteil ist, das ich meine Komponente schön kapseln kann und die bei
Bedarf den ISR Kram implizit behandelt. Es muss keine ISR im Core vorab
reserviert werden (Arduino) oder eine unübersichtliche 'ich kann alle
Ints' (HAL) implementiert werden.
Benutzt habe ich das z.B. in einer Timerklasse. Der gebe ich den
gewünschten Callback mit und intern wird die Interruptbehandlung
gemacht.
Auszugsweise sieht das so aus, Timerkram weggelassen:
Den CThunk könnte man auch aus dem OS rausoperieren, der setzt nichts OS
spezifisches vorraus. Aber da habe ich keine Ambitionen, das OS hat ja
noch mehr zu bieten das ich benutzen möchte.
Eine eigene Frage?
Dieser Thread ist über 6 Jahre alt.
Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.