Hallo Forum, ich verwende GCC (WINAVR) für verschiedene ATmegas. Ich suche nach einer Lösung für folgendes Problem: ich hätte gerne eine zentrale Stelle im Quellcode, an dem die Interrupt-Routinen zu den entsprechenden Vectoren zugeordnet werden. Wenn ich die ISR(...)-Schreibweise verwende, verteilt sich die Interrupt-Belegung über alle Software-Module. Ich benötige die zentrale Verwaltung, da die Interrupts abhängig von einem Sub-System (per Compiler-Schalter) belegt werden. Das möchte ich nicht auf die Module verteilen. Nicht verwendete Interrupts sollen zusammen zu einer eigenen ISR laufen, in der dann eine Fehlerbehandlung abläuft. "__bad_interrupt" wird nicht gebraucht. Plan 1 ist fertige ISR(...) für jeden möglichen Interrupt bereit zuhalten und von dort als Unterfunktion in das jeweilige Software-Modul zu verzweigen. Dadurch brauche ich aber in der ISR einen CALL und zudem werden alle Register gesichert, selbst wenn in der ISR nichts gebraucht wird. Plan 2 ist per #define die jeweilge Funktion in "__vector_12" umzudefinieren. Das ist schon ganz brauchbar, aber nicht verwendete Interrupts können so nicht zusammengefasst werden. Ich bräuchte für jeden Interrupt einen eigenen Funktionssrumpf mit einem CALL zur Fehlerbehandlung. Das ergibt wieder die Plan 1-Probleme. Gibts hier schon eine bessere Lösung?
Nimm Möglichkleit und deklariere deine Interrupt-Handler als "static inline" - ist die sauberste Lösung... per Makros/defines gibt es irgendwann Probleme bei der Fehlersuche..
Du kannst alle Interrupts in eine ISR umleiten:
1 | ISR(PCINT0_vect) |
2 | {
|
3 | ...
|
4 | // Code to handle the event.
|
5 | }
|
6 | ISR(PCINT1_vect, ISR_ALIASOF(PCINT0_vect)); |
mfg.
Thomas Eckmann schrieb: > Du kannst alle Interrupts in eine ISR umleiten: Oder gleich bad_interrupt verwenden. Spart eine Menge Tipparbeit, man kann keine Vektoren vergessen, und es funktioniert mit jedem AtMega. Oliver
Oliver S. schrieb: > Oder gleich bad_interrupt verwenden. Spart eine Menge Tipparbeit, man > kann keine Vektoren vergessen, und es funktioniert mit jedem AtMega. Dann funktioniert das aber nicht: Rangi Jones schrieb: > Nicht verwendete Interrupts sollen zusammen zu einer eigenen > ISR laufen, in der dann eine Fehlerbehandlung abläuft. Brauchbar ist allerdings beides nicht, da man die Interruptquelle nicht feststellen kann. mfg.
Ich denke, ich hab jetzt eine Lösung. In allen Modulen ersetzt der Präprozessor den Modulnamen der Funktion durch den Vektornamen. Damit hängen alle ISR, egal in welchen Modul, direkt in der Tabelle.
1 | ...
|
2 | #define NO_INT8 INT7_vect /* External Interrupt Request 7 */ |
3 | #if( HW_ID == HW_ID_123 )
|
4 | #define IO_PCINT0_ISR PCINT0_vect/* Pin Change Interrupt Request 0 */ |
5 | #else
|
6 | #define NO_INT9 PCINT0_vect/* Pin Change Interrupt Request 0 */ |
7 | #endif
|
8 | ...
|
In der folgenden Liste werden die Funktionen als ISR deklariert:
1 | ...
|
2 | void __vector_8(void) __attribute__ ((signal,__INTR_ATTRS)); |
3 | void __vector_9(void) __attribute__ ((signal,__INTR_ATTRS)); |
4 | ...
|
Und dann gibt es noch eine Liste mit den unbenutzten Einträgen
1 | ...
|
2 | #ifdef NO_INT8
|
3 | ISR(_VECTOR(8), ISR_ALIASOF(_VECTOR(76))); |
4 | #endif
|
5 | #ifdef NO_INT9
|
6 | ISR(_VECTOR(9), ISR_ALIASOF(_VECTOR(76))); |
7 | #endif
|
8 | ...
|
Geändert wird nur in der ersten Liste mit den #define wenn keine eigene ISR verwendet wird, muss hier "NO_INTxx" stehen. Die anderen Listen werden einmal angelegt und bleiben unverändert in unterschiedlichen Subprojekten.
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.