Question

Je me demande si quelqu'un sait de quelques bons tutoriaux sur Internet pour le développement de machines d'état. Ou des ebooks?

Je commence à travailler sur des machines d'état et juste besoin de quelque chose en général pour me commencer.

Était-ce utile?

La solution

machines d'état sont très simples en C si vous utilisez des pointeurs de fonction.

Fondamentalement, vous avez besoin de 2 tableaux - un pour les pointeurs de fonction de l'état et une des règles de transition d'état. Chaque fonction d'état renvoie le code, vous lookup table de transition d'état par l'état et le code de retour pour trouver le prochain état, puis exécutez juste.

int entry_state(void);
int foo_state(void);
int bar_state(void);
int exit_state(void);

/* array and enum below must be in sync! */
int (* state[])(void) = { entry_state, foo_state, bar_state, exit_state};
enum state_codes { entry, foo, bar, end};

enum ret_codes { ok, fail, repeat};
struct transition {
    enum state_codes src_state;
    enum ret_codes   ret_code;
    enum state_codes dst_state;
};
/* transitions from end state aren't needed */
struct transition state_transitions[] = {
    {entry, ok,     foo},
    {entry, fail,   end},
    {foo,   ok,     bar},
    {foo,   fail,   end},
    {foo,   repeat, foo},
    {bar,   ok,     end},
    {bar,   fail,   end},
    {bar,   repeat, foo}};

#define EXIT_STATE end
#define ENTRY_STATE entry

int main(int argc, char *argv[]) {
    enum state_codes cur_state = ENTRY_STATE;
    enum ret_codes rc;
    int (* state_fun)(void);

    for (;;) {
        state_fun = state[cur_state];
        rc = state_fun();
        if (EXIT_STATE == cur_state)
            break;
        cur_state = lookup_transitions(cur_state, rc);
    }

    return EXIT_SUCCESS;
}

Je ne mets pas la fonction lookup_transitions() comme il est trivial.

C'est la façon dont je fais des machines d'état pendant des années.

Autres conseils

Je préfère utiliser des pointeurs de fonction sur les déclarations gigantesques switch, mais contrairement à la réponse de qrdl Je n'utilise normalement pas de codes explicites ou retour tables de transition.

En outre, dans la plupart des cas, vous aurez besoin d'un mécanisme pour passer le long des données supplémentaires. Voici une machine d'état par exemple:

#include <stdio.h>

struct state;
typedef void state_fn(struct state *);

struct state
{
    state_fn * next;
    int i; // data
};

state_fn foo, bar;

void foo(struct state * state)
{
    printf("%s %i\n", __func__, ++state->i);
    state->next = bar;
}

void bar(struct state * state)
{
    printf("%s %i\n", __func__, ++state->i);
    state->next = state->i < 10 ? foo : 0;
}

int main(void)
{
    struct state state = { foo, 0 };
    while(state.next) state.next(&state);
}

machines de l'Etat ne sont pas quelque chose qui doit en soi un tutoriel pour expliquer ou même utilisé. Ce que je suggère est que vous regardez les données et la façon dont il a besoin pour analyser.

Par exemple, je devais analyser le protocole de données pour un Près de l'ordinateur de vol du ballon spatial , qui devait être analysé sur dans un fichier séparé par des virgules il des données stockées sur la carte SD dans un format spécifique (binaire). En utilisant une machine d'état pour ce qui rend le plus de sens, car en fonction de ce que le prochain bit d'information est que nous devons changer ce que nous l'analyse syntaxique.

Le code est écrit en C ++, et est disponible en ParseFCU . Comme vous pouvez le voir, il détecte tout d'abord quelle version nous l'analyse syntaxique, et à partir de là il entre deux machines d'état différents.

Il pénètre dans la machine d'état dans un état connu bien-être, à ce moment-là, nous commençons l'analyse syntaxique et en fonction de ce que les personnages que nous rencontrons nous soit déplacer à l'état suivant ou revenir à un état précédent. Cela permet essentiellement le code à l'auto-adapter à la façon dont les données sont stockées et si oui ou non certaines données existe même du tout.

Dans mon exemple, la chaîne GPS n'est pas une exigence pour l'ordinateur de vol pour se connecter, de sorte que le traitement de la chaîne GPS peut être sautée si les octets se terminant pour cette écriture de journal unique se trouve.

machines d'état sont simples à écrire, et en général, je suivent la règle selon laquelle il devrait couler. Entrée en passant par le système doit circuler avec certaine aisance d'un état à l'autre.

Malheureusement, la plupart des articles sur des machines d'état sont écrites pour C ++ ou d'autres langues qui ont un soutien direct pour le polymorphisme comme il est agréable de modéliser les états dans une mise en œuvre des États fédérés de Micronésie comme les classes qui dérivent d'une classe abstraite de l'Etat.

Cependant, il est assez facile à mettre en œuvre des machines d'état en C en utilisant soit passer des déclarations à des événements d'expédition aux Etats (pour FSMs simples, ils le code à peu près jusqu'à) ou en utilisant des tables pour cartographier les événements à transitions d'état.

Il y a quelques simples, mais des articles décents sur un cadre de base pour les machines d'état en C ici:

temps réel Modélisation orientée objet a été fantastique (publié en 1994 et maintenant en vente pour aussi peu que 81 cents, plus 3,99 $ Expédition).

Ceci est tout ce que vous devez savoir.

int state = 0;
while (state < 3)
{
    switch (state)
    {
        case 0:
            // Do State 0 Stuff
            if (should_go_to_next_state)
            {
                state++;
            }
            break;
        case 1:
            // Do State 1 Stuff    
            if (should_go_back) 
            {
                state--;
            }    
            else if (should_go_to_next_state) 
            {
                state++;
            }
            break;
        case 2:
            // Do State 2 Stuff    
            if (should_go_back_two) 
            {
                state -= 2;
            }    
            else if (should_go_to_next_state) 
            {
                state++;
            }
            break;
        default:
            break;
    }
}

Il y a beaucoup de leçons à apprendre handcrafting machines d'état en C, mais permettez-moi de suggérer également compilateur machine d'état Ragel:

http://www.complang.org/ragel/

Il a tout à fait de manière simple de définir des machines d'état et vous pouvez générer des graphiques, générer du code dans des styles différents (déterminés par des tables, axée sur goto), d'analyser ce code si vous voulez, etc. Et il est puissant, peut être utilisé dans le code de production pour différents protocoles.

machines de l'État peut être très complexe pour un problème complexe. Ils sont également soumis à des bugs inattendus. Ils peuvent se transformer en cauchemar si quelqu'un se jette dans un bogue ou doit changer la logique à l'avenir. Ils sont également difficiles à suivre et debug sans le diagramme d'état. La programmation structurée est beaucoup mieux (par exemple, vous auriez probablement pas utiliser une machine d'état au niveau de la ligne principale). Vous pouvez utiliser la programmation structurée, même dans un contexte d'interruption (qui est l'endroit où les machines d'état sont généralement utilisés). Voir cet article "macros pour simuler multi Code tasking / blocage au niveau d'interruption " trouve à codeproject.com.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top