Butterfly state-machine vorbildlich? Wer erläutert Funktionsweise?

Gast #890452
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?
Moderator Persönliche Seite #1025952
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.

Antwort schreiben

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.