Hallo,
ich versuche den Code aus Beitrag "PWM Signal auswerten" in
mein C++ Projekt zu bekommen.
Irgendwie wollen die Interrupt Methoden nicht mit in die Klasse.
Ich nehme an, ISR wird über ein define überschrieben da ich so:
1
expected unqualified-id before 'extern'
bekomme.
Ohne KLASSE:: davor kann er natürlich die Attribute nicht finden. Diese
sind ja in der Klasse.
Hat da jemand eine Lösung?
Danke,
Stefan
> Irgendwie wollen die Interrupt Methoden nicht mit in die Klasse.
In jeder Klasseninstanz eine eigene Instanz des Interrupthandlers?
..keine gute Idee.. Wenns unbedingt C++ sein muss [1] dann lass die
Interrupthandlder 'draussen' und mach deine Instanzen stattdessen per
globaler Variable verfügbar, ein improvisierter 'this'-Zeiger sozusagen
:-)
HTH
[1] C++ hat viele schöne Konzepte, aber für so einen kleinen µC ein
bisschen Overkill..
Hallo,
ich meine bei Motorola sind das "normale" Methoden, die der Compiler
dann entsprechend umsetzt.
Dann muss ich wohl doch auf C zurück.
Ich habe auf C++ umgestellt, weil ich mit den Objekten eine bessere
Übersicht bekommen wollte.
Danke,
Stefan
g457 schrieb:> [1] C++ hat viele schöne Konzepte, aber für so einen kleinen µC ein> bisschen Overkill..
kommt drauf an, was man alles benutzt.
virtuelle Vererbung oder collections sind definitv overkill.
Aber ein bisschen templates und Klassen machen den Code oft
übersichtlicher.
vor allem die Möglichkeit datenstrukturen mit Funktionen versehen zu
können vermisse ich in C.
IgnitionHandler ig;
ig.initExplosion();
ist doch viel schöner als
IgnitionHandler ig;
IgnitionHandler_initExplosion(&ig);
und das enthält überhaupt keinen Overhead.
Oder konstruktoren.
Da entfallen die ganzen init-Aufrufe.
oder Operatorüberladung für Fixpointtypen zB.
Stefan Kuhne schrieb:> Irgendwie wollen die Interrupt Methoden nicht mit in die Klasse.> Ich nehme an, ISR wird über ein define überschrieben da ich so:> expected unqualified-id before 'extern'> bekomme.>> Ohne KLASSE:: davor kann er natürlich die Attribute nicht finden. Diese> sind ja in der Klasse.
Wie genau bist Du vorgegangen? Wichtig ist, daß die Interruptroutinen
als static deklariert werden, genauso, wie es auch mit aus C-Code
heraus aufgerufenen C++-Funktionen gemacht werden muss.
> ISR(TIM1_OVF_vect) //Overflow
Sieh Dir mal den Aufbau des Macros ISR an, und berücksichtige, daß die
Funktion als static deklariert sein muss, es also keinen this-Pointer
innerhalb der Funktion gibt.
Hab ich auch schon mal versucht mit dem Ergebnis, es künftig bleiben zu
lassen.
Du musst die ISR in der Klasse auf jeden fall static machen.
Außerdem muss dann sichergestellt sein, dass überhaupt eine Instanz
schon vorhanden ist, sonst nützt selbst static nix.
Das ganze sollte dann über _attribute_(signal) oder so ähnlich
funktionieren, damit erstens statt des ret ein reti am Ende der ISR
steht und zweitens der Interruptvector beschrieben wird.
Aber das Ganze ist halt weder C noch C++-konform, da diese Sprachen per
se keine Interrupts kennen. Daher sind diese Konstruktionen mehr oder
minder Krücken des Compilers, die sich jederzeit ändern können
(Interrupt -> Signal -> ISR).
Michael K. schrieb:> warum schreibt man für einen 8 bit µC ein Programm in C++...> Das versteh' ich net...
Das kann man wohl über alles sagen, was nicht Assembler ist. ;)
Ich hatte mich auch schon einmal damit beschäftigt und diese "Lösung"
hier gefunden:
http://waterproofman.wordpress.com/2007/02/07/avr-interrupts-in-c/
So ganz hat mich das nicht überzeugt. Es gibt IMO den grundsätzlichen
Widerspruch, dass man von einer Klasse zwar mehrere neue Instanzen
erzeugen kann, die damit angesteuerte Hardware aber nicht gleich mit
erzeugt wird.
Eventuell kann man die ISR ja ganz klassisch quasi in C programmieren
und die Objekte greifen auf dessen (globale) Daten dann zu. Wenn das nur
ein Objekt macht, dann hat man ja in der Praxis wieder eine Art
Kapselung.
Ich könnte mir z.B. ein UART-Objekt (UART mal als nahe liegendes
Beispiel) vorstellen, dessen Konstruktor ein Zeiger auf die Daten der
UART-ISR übergeben wird. Der wird in dem Objekt gespeichert (und könnte
ggf. auch geändert werden). So "bindet" man dann Objekte an die
Hardware. Will ich eine andere Funktion an der Schnittstelle, binde ich
ein anderes Objekt daran. Dasselbe Objekt kann ich an unterschiedliche
UARTs binden (natürlich nur wenn es mehrere gibt).
Ich könnte mir auch gut ein Objekt als eine Art "Torwächter" vorstellen,
der den Zugang zur SPI oder I²C-Schnittstelle kontrolliert. Oder eine
abstrakte ADC-Klasse, deren Nachfolger entweder interne oder externe
ADCs ansprechen...
Ich denke, es gibt schon Gründe, C++ auf Mikrocontrollern einzusetzen.
(ich persönliche bleibe aber bei C mit Assembler als Notnagel)
Es gab hier einen, meiner Meinung nach, sehr sinnvollen Patchvorschlag
von Ron Kreymborg. Der Patch hat die Nummer #6805 (Numeric interrupt
vectors).
Eine Erklärung und ein Beispiel ist hier zu finden:
http://jennaron.com.au/avr/classinterrupts.html
Leider scheint sich dieser Patch nicht durchgesetzt zu haben, denn
immerhin ist der Vorschlag schon etwas älter (2007). Schade eigentlich,
aber ich hoffe immer noch, dass der Patch irgendwann umgesetzt wird.