Hallo erst mal. Ist es möglich, den ISR-Code als Memberfunktion einer Klasse anzulegen? Ziel soll sein, eine Klasse zu haben, die sich exklusiv um bestimmte Hardware kümmert. Z.B. eine Zähler, gesteuert von externen Interrupts. Dabei möchte ich in der ISR auf Klassenvariablen zugreifen können. Der Art nach: class Cnt { public: Cnt(void): count(0) { ...initialisiere Interrupt... } char get(void) { return count; } private: char count; ISR_INT0_VECT; } Cnt::ISR_INT0_VECT { count++; } int main(void) { Cnt c; tu_etwas(); PORTB = c.get(); return 0; } , so, daß ISR_INT0_VECT in der Vektortabelle eingetragen wird. Probiert habe ich das ganze bisher mit avr-g++ (GCC) 4.1.2 20061027 (prerelease) wie folgt: 1. ISR_INT0_VECT entsprechend <avr/interrupt.h> mit extern "C" void INT0_vect... -> c++ meckert, will das nicht in der Klasse haben. 2. ISR_INT0_VECT ohne extern "C" -> name mangling und der Vektor wird nicht verbogen. 3. ISR_INT0_VECT mit __attribute__((naked)) und die ISR in assembler, mit asm (".global __vector_1\n__vector_1:\n"); beginnend funktioniert, ist aber kein c/c++. 4. ISR_INT0_VECT als friend von Klasse Cnt hat auch nicht gefruchtet. Geht das überhaupt; wenn ja, wie? mfg Marco
> Ist es möglich, den ISR-Code als Memberfunktion einer Klasse anzulegen?
Nein.
Das kann in C++ nicht gehen, da eine ISR nur über die
Funktionsadresse aufgerufen wird. Um eine Memberfunktion
aufzurufen benötigt man zusätzlich noch das Objekt für
welches die Funktion aufzurufen ist.
Einer der Schwachpunkte von C++ im Vergleich zu neueren
Sprachen wie zb C#
Stell es dir so vor:
Wenn du eine Memberfunktion aufrufst
1 | class A |
2 | {
|
3 | public:
|
4 | void foo( int arg ); |
5 | |
6 | private:
|
7 | int i; |
8 | }
|
9 | |
10 | void A::foo( int arg ) |
11 | {
|
12 | this.i = arg; |
13 | }
|
14 | |
15 | int main() |
16 | {
|
17 | A a; |
18 | |
19 | a.foo( 5 ); |
20 | }
|
dann behandelt der Compiler das so: aus der Memberfunktion wird eine ganz normale Funktion, die die Adresse des Objektes mitbekommt:
1 | void A_foo( A* obj, int arg ) |
2 | {
|
3 | obj->i = arg; |
4 | }
|
5 | |
6 | und der Aufruf wird zu: |
7 | |
8 | int main() |
9 | {
|
10 | struct A a; |
11 | |
12 | foo( &a, 5 ); |
13 | }
|
Der Funktion wird also ein Pointer auf das Objekt mitgegeben. Innerhalb der Funktion kannst du mit dem Schlüsselwort 'this' auf diesen versteckten Pointer zugreifen. Nur muss der Aufrufer aber auch das Objekt entsprechend angeben. Was kannst du tun. Du kannst den Umweg über eine ganz normale C++ Funktion nehmen und von der das Objekt einsetzen lassen:
1 | class Cnt { |
2 | public:
|
3 | Cnt(void): count(0) { ...initialisiere Interrupt... } |
4 | char get(void) { return count; } |
5 | |
6 | void OnInterrupt(); |
7 | |
8 | private:
|
9 | char count; |
10 | }
|
11 | |
12 | static Cnt* GetsInterrupt; |
13 | |
14 | ISR( ... ) |
15 | {
|
16 | if( GetsInterrupt ) |
17 | GetsInterrupt->OnInterrupt(); |
18 | }
|
19 | |
20 | int main() |
21 | {
|
22 | Cnt c; |
23 | |
24 | GetInterrupt = &c; // jetzt werden die Definierten Interrupts |
25 | // von der ISR an das Objekt c weitergereicht
|
26 | |
27 | ...
|
28 | }
|
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.