Forum: Compiler & IDEs Butterfly state-machine vorbildlich? Wer erläutert Funktionsweise?


von Bastler (Gast)


Lesenswert?

Hallo,

viele Anfragen hier nach einer "Steuerungssoftware" werden auf die 
state-machine der Butterfly Software verwiesen.

Der avr-gcc / avr-libc port von martin thomas ist hier:

http://www.siwawi.arubi.uni-kl.de/avr_projects/#bf_app

Siehe main.c und menu.h

Ich versuche mal eine Erläuterung:

Wenn ich das richtig verstanden habe, wird das Programm in Zustände 
unterteilt, die in dem Fall wohl eher makroskopisch aus den Menüpunkten 
bestehen.
Ereignisse (hier ein Tastendruck) veranlassen dann einen Wechsel in 
einen anderen Zustand.


menu.h:

Zur Steuerung sind zwei Arrays angelegt, in denen die Elemente als 
Struktur definiert sind, und die nötigen Daten zusammenfassen. Das liegt 
alles als const .... PROGMEM im Flash.

Das eine Array (menu_state) enthält
ein Byte für die Zustands-ID
einen Zeiger auf den Menü-Text
einen Funktionszeiger

Das andere Array (menu_nextstate) enthält für jede Zustands-ID und die 
möglichen Ereignisse die folgende Zustands-ID.

main.c
Da passiert folgendes, sofern nicht im Power-Save

- LCD-Ausgabe, wenn Text ansteht
- Tasten einlesen
- Zum Zustand gehörige Funktion ausführen, wenn Funktionszeiger 
vorhanden
- Wenn Taste gedrückt:
   Die Funktion statemachine sucht anhand der aktuellen Zustands-ID und 
des Ereignisses die nächste Zustands-ID aus dem Array nextstate

- Wenn Zustandswechsel ansteht, Menütextzeiger und Funktionszeiger 
aktualisieren.


Ok, damit lassen sich über ein Menü Funktionen aufrufen - aber wie geht 
es weiter? Blockieren diese Funktionen dann alles andere und kehren erst 
nach Beendigung zur state-machine zurück? Dann müssten alle anderen 
Funktionen, die "parallel" ablaufen, ja ausschließlich in ISRs stehen?

von AVRandLCD (Gast)


Lesenswert?

ja das würde mich auch interessieren!

von Martin T. (mthomas) (Moderator) Benutzerseite


Lesenswert?

Die Funktionen in der Beispielanwendung blockieren nicht (bis auf die 
Hardware-Test-Funktionen, die aber nicht über normale Eingabe gestartet 
werden können). Einfach mal in die Funktionen reinschauen, sind immer 
nach dem gleichen Prinzip aufgebaut:

- Parameter Input ist die Joystickeingabe ("stimulus" heißt das glaub 
ich)
- eine statische Variable enter, in den Beispielen meist mit 1 
initialisiert, dient dazu, den ersten Aufruf der Funktion zu erkennen.
- Prüfung auf enter<>0, wenn ja Initialisierungen durchführen enter auf 
0
- Dann Fallunterscheidung auf Input und entsprechende Aktionen ausführen
- Rückgabe ist der State-ID. Falls dieser nicht mit dem aktuellen 
Zustand übereinstimmt, enter auf 1 setzten, damit beim nächsten Aufruf 
der Funktion die notwendigen Initialisierungen wieder durchgeführt 
werden
- Die Hauptschleife in main() kümmert sich um die Auswertung des 
Rückgabewertes, also des Status-ID. Stimmt dieser nicht mit dem vor dem 
Aufruf der Funktion überein, wird anhand des neuen IDs in der 
Zustandsliste gesucht, die Anzeige aktualisiert und gegebenenfalls in 
die State-Funktion per Funktion-Pointer gesprungen (von "Bastler" ja 
schon beschrieben).

Wenn man sich an das Schema hält blockieren die Funktionen nicht. Soll 
auch so sein, damit z.B. die Aktivierung der Stromsparfunktion 
funktioniert (vgl. Code in main.c der Atmel Beispielanwendung (oder 
meinem GNU-Port davon).

Betr. der Frage im Topic von "Bastler" vom Juni 08: Ich weiss nicht, ob 
das vorbildlich ist, finde die Vorgehensweise aber recht brauchbar und 
nicht allzu unübersichtlich. Abgesehen von meinen etwas wirr aussehenden 
Anpassungen an "progmem" für avr-gcc/avr-libc, könnte man vielleich mit 
ein paar Macros netter aussehen lassen. Die erste Portierung des 
Beispielcodes von Atmel für IAR nach GNU war seinerzeit mein erster 
Kontakt mit avr-gcc/avr-libc und ein Sprung in ziemlich kaltes Wasser, 
aber auch sehr viel dabei gelernt.

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
Noch kein Account? Hier anmelden.