W piątej lekcji w segmencie dotyczącym maszyny stanów autor przedstawia jej implementację w języku C, którą uznaje za optymalną zgodnie z wyjaśnionymi w dalszej części artykułu kryteriami. Wideo szkoleniowe nr 39 (poniżej) ilustruje, jak zbudować wielokrotnego użytku: „procesor zdarzeń”, aby włączyć tę miarodajną strategię implementacji maszyny stanów bezpośrednio w ramach aktywnego obiektu: „MicroC/AO”, który został zapoczątkowany we wcześniejszej lekcji.
Język specyfikacji maszyny stanów
Aby uzyskać optymalne rozwiązanie, często pomocne jest wyobrażenie sobie, jak powinno ono wyglądać. A następnie pracowanie wstecz, aby zaimplementować je w języku programowania, takim jak C. Załóżmy, że tworzysz język specyficzny dla domeny (DSL), nie tyle do implementacji maszyn stanów, co do ich najbardziej zwięzłego określenia. Taki DSL byłby zatem tekstową reprezentacją diagramów maszyny stanów.
Wideo ilustruje ten proces myślowy, gdzie przepisuje się diagram stanów maszyny TimeBomb, nie myśląc jeszcze o składni w C. Zaczyna się od stanów jako elementów najwyższego poziomu, a następnie uzupełnia się ich strukturę wewnętrzną, uwzględniając akcje wejścia/wyjścia, przejścia i strażników.
W ostatnim kroku dodaje się minimalną składnię do swojego DSL, aby zamienić go w prawidłowy program w języku C. W tym momencie specyfikacje stanów naturalnie stają się funkcjami w języku C (funkcjami obsługi stanu) z elementami wewnętrznymi, takimi jak akcje wejścia/wyjścia i przejścia, odwzorowanymi na przypadki wewnątrz instrukcji switch. Ten aspekt został zaczerpnięty z implementacji zagnieżdżonej instrukcji switch.
Procesor zdarzeń
Funkcje obsługi stanu, tworzące specyfikację maszyny stanów, wciąż potrzebują procesora zdarzeń do wykonania przejść między stanami i śledzenia bieżącego. Ten aspekt jest podobny do techniki tabeli stanów, gdzie funkcja dispatch() dokonywała indeksowania w tabeli i wywoływała obsługujące akcje w odpowiedniej kolejności. W porównaniu do implementacji opartej na tabeli, funkcję dispatch() dla funkcji obsługi stanu można uprościć, eliminując konieczność wymieniania stanów. Zamiast tego zmienna stanu staje się wskaźnikiem do funkcji wskazującym na funkcję obsługi stanu, która jest aktualnie aktywna.
Kolejną zaletą uproszczonego procesora zdarzeń jest to, że staje się on niezależny od maszyny stanów, którą wykonuje. Można go przenieść do warstwy infrastruktury, czyli do ramy aktywnego obiektu: „MicroC/AO”, co ilustruje wideo powyżej. W ten sposób następuje podział na dwie części: aplikacyjną specyfikację maszyny stanowej (funkcje obsługi stanu) oraz ogólny i wielokrotnego użytku procesor zdarzeń.
Obie te części komunikują się ciągle w obie strony. Ogólny procesor zdarzeń decyduje, które funkcje obsługi stanu wywołać i dostarcza im zdarzenia. Funkcje obsługi następnie raportują procesorowi, jak przetworzyły zdarzenia (za pomocą wartości zwracanej), informując go, co zrobić dalej. Na przykład, jeśli funkcja obsługi stanu zgłosi przejście, procesor zdarzeń: „wie”, że musi wykonać akcję wyjścia ze stanu źródłowego i akcję wejścia do stanu docelowego.
Porównanie z SMC (State Machine Compiler)
Kompilator maszyny stanowej (SMC) to kolejna popularna technika implementacji oparta na translacji. Ta metoda używa: „łatwego do zrozumienia języka maszyny stanowej” (DSL), który SMC może przetłumaczyć na kilka języków programowania, w tym C i C++.
Wideo powyżej pokazuje maszynę stanów TimeBomb określoną w języku SMC, który jest dość podobny do funkcji obsługi stanu. W rzeczywistości DSL SMC nie jest prostszy ani czytelniejszy niż bezpośrednia implementacja funkcji obsługi stanu w języku C. Cała warstwa pośrednictwa DSL SMC i krok tłumaczenia mają sens tylko dlatego, że ostateczna implementacja maszyny stanów opiera się na obiektowym wzorcu projektowym: „Stan”, który jest stosunkowo skomplikowany i podatny na błędy kodowania, zwłaszcza w języku nieobiektowym, takim jak C.
Podsumowanie
Artykuł ten kończy przegląd różnych strategii implementacji maszyny stanów w kodzie. Oczywiście istnieje wiele wariantów, ale wszystkie łączą podstawowe metody, które zaprezentowano.
Wyraźnym wyborem autora tych artykułów i rekomendacją jest technika procesora zdarzeń z dyskretnymi funkcjami do obsługi stanu. To: „optymalna” implementacja, ponieważ jest najbardziej czytelna i nietrudna w utrzymaniu, przy niskim zużyciu pamięci i dobrych osiągach czasowych procesora. Jest również rozszerzalna i łatwa do prześledzenia, a to, co oznacza, wyjaśnione zostanie w kolejnym artykule.
Źródło: https://www.embedded.com/programming-embedded-systems-optimal-state-machine-implementation-in-c/
Język specyfikacji maszyny stanów
Aby uzyskać optymalne rozwiązanie, często pomocne jest wyobrażenie sobie, jak powinno ono wyglądać. A następnie pracowanie wstecz, aby zaimplementować je w języku programowania, takim jak C. Załóżmy, że tworzysz język specyficzny dla domeny (DSL), nie tyle do implementacji maszyn stanów, co do ich najbardziej zwięzłego określenia. Taki DSL byłby zatem tekstową reprezentacją diagramów maszyny stanów.
Wideo ilustruje ten proces myślowy, gdzie przepisuje się diagram stanów maszyny TimeBomb, nie myśląc jeszcze o składni w C. Zaczyna się od stanów jako elementów najwyższego poziomu, a następnie uzupełnia się ich strukturę wewnętrzną, uwzględniając akcje wejścia/wyjścia, przejścia i strażników.
W ostatnim kroku dodaje się minimalną składnię do swojego DSL, aby zamienić go w prawidłowy program w języku C. W tym momencie specyfikacje stanów naturalnie stają się funkcjami w języku C (funkcjami obsługi stanu) z elementami wewnętrznymi, takimi jak akcje wejścia/wyjścia i przejścia, odwzorowanymi na przypadki wewnątrz instrukcji switch. Ten aspekt został zaczerpnięty z implementacji zagnieżdżonej instrukcji switch.
Procesor zdarzeń
Funkcje obsługi stanu, tworzące specyfikację maszyny stanów, wciąż potrzebują procesora zdarzeń do wykonania przejść między stanami i śledzenia bieżącego. Ten aspekt jest podobny do techniki tabeli stanów, gdzie funkcja dispatch() dokonywała indeksowania w tabeli i wywoływała obsługujące akcje w odpowiedniej kolejności. W porównaniu do implementacji opartej na tabeli, funkcję dispatch() dla funkcji obsługi stanu można uprościć, eliminując konieczność wymieniania stanów. Zamiast tego zmienna stanu staje się wskaźnikiem do funkcji wskazującym na funkcję obsługi stanu, która jest aktualnie aktywna.
Kolejną zaletą uproszczonego procesora zdarzeń jest to, że staje się on niezależny od maszyny stanów, którą wykonuje. Można go przenieść do warstwy infrastruktury, czyli do ramy aktywnego obiektu: „MicroC/AO”, co ilustruje wideo powyżej. W ten sposób następuje podział na dwie części: aplikacyjną specyfikację maszyny stanowej (funkcje obsługi stanu) oraz ogólny i wielokrotnego użytku procesor zdarzeń.
Obie te części komunikują się ciągle w obie strony. Ogólny procesor zdarzeń decyduje, które funkcje obsługi stanu wywołać i dostarcza im zdarzenia. Funkcje obsługi następnie raportują procesorowi, jak przetworzyły zdarzenia (za pomocą wartości zwracanej), informując go, co zrobić dalej. Na przykład, jeśli funkcja obsługi stanu zgłosi przejście, procesor zdarzeń: „wie”, że musi wykonać akcję wyjścia ze stanu źródłowego i akcję wejścia do stanu docelowego.
Porównanie z SMC (State Machine Compiler)
Kompilator maszyny stanowej (SMC) to kolejna popularna technika implementacji oparta na translacji. Ta metoda używa: „łatwego do zrozumienia języka maszyny stanowej” (DSL), który SMC może przetłumaczyć na kilka języków programowania, w tym C i C++.
Wideo powyżej pokazuje maszynę stanów TimeBomb określoną w języku SMC, który jest dość podobny do funkcji obsługi stanu. W rzeczywistości DSL SMC nie jest prostszy ani czytelniejszy niż bezpośrednia implementacja funkcji obsługi stanu w języku C. Cała warstwa pośrednictwa DSL SMC i krok tłumaczenia mają sens tylko dlatego, że ostateczna implementacja maszyny stanów opiera się na obiektowym wzorcu projektowym: „Stan”, który jest stosunkowo skomplikowany i podatny na błędy kodowania, zwłaszcza w języku nieobiektowym, takim jak C.
Podsumowanie
Artykuł ten kończy przegląd różnych strategii implementacji maszyny stanów w kodzie. Oczywiście istnieje wiele wariantów, ale wszystkie łączą podstawowe metody, które zaprezentowano.
Wyraźnym wyborem autora tych artykułów i rekomendacją jest technika procesora zdarzeń z dyskretnymi funkcjami do obsługi stanu. To: „optymalna” implementacja, ponieważ jest najbardziej czytelna i nietrudna w utrzymaniu, przy niskim zużyciu pamięci i dobrych osiągach czasowych procesora. Jest również rozszerzalna i łatwa do prześledzenia, a to, co oznacza, wyjaśnione zostanie w kolejnym artykule.
Źródło: https://www.embedded.com/programming-embedded-systems-optimal-state-machine-implementation-in-c/
Fajne? Ranking DIY
