Hallo, folgendes Problem. In meiner ISR(USART1_RX_vect) sammele ich ankommende Zeichen und schreibe diese in einen Puffer. Bei einem bestimmten Zeichen oder einer Zeichenkombination (z.B. <CR> <LF>) kopiere ich den Puffer in einen global definierten String und setze ein Flag für einen Parser, damit der angekommene Datensatz außerhalb der ISR entsprechend ausgewertet werden kann. Soweit ist alles ja noch Standard und nicht weiter kompliziert. Die Schnittstelle wird hardwareseitig allerdings umgeschaltet und dient zwei verschiedenen Zwecken (Datenaustausch mit Benutzer über USB und Konfiguration eines Funkmoduls auf der Platine). Beide Dinge kommen nicht gleichzeitig vor, so dass die Schnittstelle problemlos für beides genutzt werden kann. Jetzt brauche ich natürlich verschiedene Parser für beide Zwecke, und auch das "Ende des Datensatzes"-Zeichen ist bei beiden Einsätzen verschieden. Das könnte ich über zusätzliche Flags regeln, die jeweils den einen oder anderen Parser aufrufen und die Entscheidung auf das eine oder andere Ende-Zeichen umstellen. Schöner wäre es allerdings, wenn ich zwei verschiedene zur Laufzeit umschaltbare ISRs bauen könnte. Weiß jemand, ob und ggf. wie das geht?
Gerhard schrieb: > Schöner wäre es allerdings, Das ist etwas 2-schneidig. Natürlich ist das schöner, aber es kostet auch Resourcen. Und das unangenehme ist: ohne einen Funktionsaufurf geht es nicht und wenn du das tust zwingst du den Compiler dazu, bei Eintritt in die ISR erst mal alle Register zu sichern, was wiederrum teuer sein kann im Vergleich zum Rest > wenn ich zwei verschiedene zur Laufzeit > umschaltbare ISRs bauen könnte. Weiß jemand, ob und ggf. wie das geht? zb mittels einem Funktionspointer. In der ISR rufst du die eigentliche Funktion über einen Funktionspointer auf und extern weist du dem Funktionspointer die Funktion zu (also bei dir eine von 2 möglichen) die benutzt werden soll um das Zeichen zu verarbeiten. http://www.mikrocontroller.net/articles/FAQ#Funktionszeiger
Wo die Vektoren liegen kann man mit IVSEL im Register GICR bzw. MCUCR beeinflussen. Wo es hingeht bstimmen dann die BOOTSZ Fuses. MfG Skua
>Schöner wäre es allerdings, wenn ich zwei verschiedene zur Laufzeit >umschaltbare ISRs bauen könnte. Weiß jemand, ob und ggf. wie das geht? Nee, das finde ich gar nicht schön! Zudem veschwendest Du Memory, weil Du dann auch unterschidliche Puffer für die ISRs und die Parser. mach das lieber über das Flag! Gib doch dem Flag einfach unterschidliche Werte mit, jenachdem für welchen Parser die Message sein soll.
@ Gerhard (Gast) >verschieden. Das könnte ich über zusätzliche Flags regeln, die jeweils >den einen oder anderen Parser aufrufen und die Entscheidung auf das eine >oder andere Ende-Zeichen umstellen. Was bitte schön ist an einer einfachen if() Abfrage so kompliziert? Da kann man die beiden verschiedenen ISRs reinpacken. Einfach und schnell. >Schöner wäre es allerdings, wenn ich zwei verschiedene zur Laufzeit >umschaltbare ISRs bauen könnte. Was ist daran schöner? Akademischer Firlefanz. > Weiß jemand, ob und ggf. wie das geht? Dann wäre es sinnvoll zu sagen, um welchen Prozessor es geht. Jaja, ich rate mal, es ist ein AVR. NEIN, geht nicht, weil die ISR VEktoren fest im Flash liegen, und ein Überschreiben per SPM sinnfrei ist. MFG Falk
Karl heinz Buchegger schrieb: > Gerhard schrieb: > >> Schöner wäre es allerdings, > > Das ist etwas 2-schneidig. > Natürlich ist das schöner, aber es kostet auch Resourcen. Und das > unangenehme ist: ohne einen Funktionsaufurf geht es nicht und wenn du > das tust zwingst du den Compiler dazu, bei Eintritt in die ISR erst mal > alle Register zu sichern, was wiederrum teuer sein kann im Vergleich zum > Rest Man könnte die Funktionen mit __attribute__((always_inline)) deklarieren. Dann kann man den Code immer noch sauber auf zwei Funktionen aufteilen, hat aber den Overhead nicht. Ich bezweifle aber mal den Sinn der Aktion. Ein Parser hat in einer ISR eigentlich nichts verloren. Die sollte so kurz wie möglich sein, und die eigentliche Arbeit gehört ins Hauptprogramm, wo man das auch sauber über zwei getrennte Funktionen regeln kann, ohne da noch einen besonderen Overhead zu bekommen. Karl heinz Buchegger schrieb: >> wenn ich zwei verschiedene zur Laufzeit >> umschaltbare ISRs bauen könnte. Weiß jemand, ob und ggf. wie das geht? > > zb mittels einem Funktionspointer. Das hat aber auch keinen wirklichen Vorteil gegenüber einem Flag, über das mit einer einfachen Verzweigung zwischen den beiden Funktionen gewählt wird.
Gerhard schrieb: > Jetzt brauche ich natürlich verschiedene Parser für beide Zwecke, und > auch das "Ende des Datensatzes"-Zeichen ist bei beiden Einsätzen > verschieden. Nun, der Parser hat ja mit dem Interrupt nichts zu tun, den rufst Du ja im Main auf. Und das wird ja aus seinem Kontext heraus wissen, welchen es aufrufen muß. Es hat ja auch die Hardware umgeschaltet. Der Interrupt macht nur die FIFO, ist also immer gleich. Er kann ja beide Endezeichen testen und das Main fragt dann das zutreffende Flag ab. Peter
Gut, ihr habt mich überzeugt, ich mache das über Flags. Wegen der "Schönheit": Ein über Flags umschaltbarer Parser zerschießt mir halt meine schöne Modularisierung des Programms und verschlechtert die spätere Verständlichkeit und Lesbarkeit.
Gerhard schrieb: > Gut, ihr habt mich überzeugt, ich mache das über Flags. > > Wegen der "Schönheit": Ein über Flags umschaltbarer Parser zerschießt > mir halt meine schöne Modularisierung des Programms und verschlechtert > die spätere Verständlichkeit und Lesbarkeit. Mir ist nicht ganz klar, was du da immer mit deinem Parser hast. Der eigentliche Parser ist doch ausserhalb der ISR. In der ISR geht es doch nur darum Zeichen zu sammeln und beim Erreichen des End-of-Input Zeichens der Hauptschleife eine Benachrichtigung zu geben. Dann mach es doch so, dass du der ISR das gewünschte End-Of-Input Zeichen extern zur Verfügung stellst. Beim Kontextwechsel wird dieses ausgetauscht und die ISR macht weiterhin was sie tut: Zeichen sammeln, bis das vorgegebene End-Of-Input Zeichen eintrudelt.
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.