AVR Interrupt Routinen mit C++: Unterschied zwischen den Versionen
(Inhaltsverzeichnis und erstes Kapitel erstellt) |
(Theorie fertig) |
||
Zeile 4: | Zeile 4: | ||
== Probleme == | == Probleme == | ||
=== name | === name mangling === | ||
In C++ gibt es Namensräume, daher werden | In C++ gibt es Namensräume, daher werden nicht nur die Methodennamen für die Symbolnamen benutzt, sondern unter anderem auch die Klassennamen mit eingebracht. Die Schattenseite dieses Features ist allerdings, dass die Interrupt Makros der avr-libc nicht mehr genutzt werden können. ISR(...) ist eines davon; es wird vom Präprozessor über einige weitere Makros zur Funktion void __vector_n(void) (n = Interruptnummer) aufgelöst. | ||
=== Zugriff auf nicht statische Membervariablen === | === Zugriff auf nicht statische Membervariablen === | ||
Da Methoden als ersten impliziten Parameter den this Zeiger ihres Objekts bekommen,<ref name="Thinking in C++">Eckel, Bruce: Thinking in C++. Second Edition. Upper Saddle River: Prentice Hall Inc. 2000. S. 429.</ref> Interrupt Handler allerdings keine Parameter haben, müssen gezwungermaßen statische Methoden verwendet werden. Statische Methoden haben allerdings nur auf statische Variablen Zugriff. Dies ermöglicht allerdings nur eine suboptimale Objektorientierung. Beispielsweise soll eine Timer Klasse benutzt werden. Wollte man je ein Objekt für zwei verschiedene Timer erstellen, bräuchte man für jedes eine statische Variable. | |||
== Lösungen == | == Lösungen == | ||
=== das asm Schlüsselwort === | === das asm Schlüsselwort === | ||
Das Schlüsselwort '''asm''' ist nicht nur dazu da inline Assembler zu programmieren, sondern kann auch dazu verwendet werden Symbolnamen zu bestimmen.<ref>http://gcc.gnu.org/onlinedocs/gcc-4.7.2/gcc/Asm-Labels.html</ref> Somit ergibt sich die Möglichkeit das name mangling zu steuern. Nennt man eine statische Methode zum Beispiel __vector_1 gehört sie weiterhin zur Klasse, bekommt aber diesen Symbolnamen. Da die avr-libc eine Interruptvektortabelle anlegt in der ein Sprungbefehl zu __vector_1 für den ersten Interrupt steht wird die Methode auch im Interruptfall aufgerufen. | |||
=== befreundete Klassen === | === befreundete Klassen === | ||
Zu den pragmatischen Teilen der Sprache gehört das Schlüsselwort '''friend''', da es einer fremden Klasse Zugriff auf private Teile einer anderen Klasse gibt. Um mithilfe von '''friend''' einer Interrupt Routine Zugriff auf nicht statische Membervariablen zu geben kann eine geschachtelte befreundete Klasse angelegt werden, die eine statische Zeigervariable enthält.<ref>http://www.embedded.com/design/embedded/4023817/Interrupts-in-C-</ref> Wird mithilfe einer weiteren statischen Methode dieser Klasse der this Zeiger der äußeren Klasse gespeichert, kann durch die Interrupt Methode auf alle Member der äußeren Klasse zugegriffen werden. | |||
== Implementierungen == | == Implementierungen == | ||
Zeile 17: | Zeile 22: | ||
=== pragmatischer Ansatz === | === pragmatischer Ansatz === | ||
== Einzelnachweise == | |||
<references/> | |||
[[Kategorie:AVR| ]] | |||
[[Kategorie:C++| ]] | |||
[[Kategorie:Wettbewerb]] | [[Kategorie:Wettbewerb]] |
Version vom 7. März 2013, 17:49 Uhr
Einen Mikrocontroller mit C++ zu programmieren scheitert oft daran die Interrupt Routinen in die Klassenhierarchie zu integrieren. Ohne saubere Objektorientierung verliert C++ jedoch schnell an Wert. Zum Beispiel Frameworks um die Hardware zu abstrahieren sind mit den Interrupt Makros der avr-libc zwar machbar, jedoch mit reinem C++ weit flexibler.
Deshalb soll dieser Artikel einen Einblick in die Möglichkeiten des g++ Compilers geben, der einige Stellschrauben besitzt mit denen sich Interrupts trotz aller Probleme in Klassen, mit Zugriff auf nicht statische Membervariablen, integrieren lassen.
Probleme
name mangling
In C++ gibt es Namensräume, daher werden nicht nur die Methodennamen für die Symbolnamen benutzt, sondern unter anderem auch die Klassennamen mit eingebracht. Die Schattenseite dieses Features ist allerdings, dass die Interrupt Makros der avr-libc nicht mehr genutzt werden können. ISR(...) ist eines davon; es wird vom Präprozessor über einige weitere Makros zur Funktion void __vector_n(void) (n = Interruptnummer) aufgelöst.
Zugriff auf nicht statische Membervariablen
Da Methoden als ersten impliziten Parameter den this Zeiger ihres Objekts bekommen,[1] Interrupt Handler allerdings keine Parameter haben, müssen gezwungermaßen statische Methoden verwendet werden. Statische Methoden haben allerdings nur auf statische Variablen Zugriff. Dies ermöglicht allerdings nur eine suboptimale Objektorientierung. Beispielsweise soll eine Timer Klasse benutzt werden. Wollte man je ein Objekt für zwei verschiedene Timer erstellen, bräuchte man für jedes eine statische Variable.
Lösungen
das asm Schlüsselwort
Das Schlüsselwort asm ist nicht nur dazu da inline Assembler zu programmieren, sondern kann auch dazu verwendet werden Symbolnamen zu bestimmen.[2] Somit ergibt sich die Möglichkeit das name mangling zu steuern. Nennt man eine statische Methode zum Beispiel __vector_1 gehört sie weiterhin zur Klasse, bekommt aber diesen Symbolnamen. Da die avr-libc eine Interruptvektortabelle anlegt in der ein Sprungbefehl zu __vector_1 für den ersten Interrupt steht wird die Methode auch im Interruptfall aufgerufen.
befreundete Klassen
Zu den pragmatischen Teilen der Sprache gehört das Schlüsselwort friend, da es einer fremden Klasse Zugriff auf private Teile einer anderen Klasse gibt. Um mithilfe von friend einer Interrupt Routine Zugriff auf nicht statische Membervariablen zu geben kann eine geschachtelte befreundete Klasse angelegt werden, die eine statische Zeigervariable enthält.[3] Wird mithilfe einer weiteren statischen Methode dieser Klasse der this Zeiger der äußeren Klasse gespeichert, kann durch die Interrupt Methode auf alle Member der äußeren Klasse zugegriffen werden.
Implementierungen
ohne Elternklasse
mit Elternklasse
pragmatischer Ansatz
Einzelnachweise
- ↑ Eckel, Bruce: Thinking in C++. Second Edition. Upper Saddle River: Prentice Hall Inc. 2000. S. 429.
- ↑ http://gcc.gnu.org/onlinedocs/gcc-4.7.2/gcc/Asm-Labels.html
- ↑ http://www.embedded.com/design/embedded/4023817/Interrupts-in-C-