Günümüzde gömülü sistemlerde küçük veya kompleks birçok uygulama sonlu durum makinelerini kullanmaktadır. Gömülü sistemler için C programlamada sonlu durum makineleri (FSM) popüler model tasarımı (design pattern)’den biridir. Sonlu durum makineleri geliştirmeyi kolay ve problemsiz yapmayı sağlamaktadır. Kahve makinesi, Otomat satış makineleri, poz makinesi , kapı kilit sistemeleri gibi bir çok olay (event) temelli bir çok bulunmaktadır. Bazı pos cihazları, olayların bir olay işleyicisine kaydedildiği olay tablosu kullanır. Bazı POS aygıtları, olayların bir olay işleyicisine kaydedildiği (event handler) olay tablosunu kullanır. Bu olay işleyicisi(event handler), ilgili olay geldiğinde çalışır.
Sonlu durum makineleri , birden çok durum (state) sahip olabilir. Bir durumdan diğer duruma dahili ve harici girişler ile geçebilmektedir. Bu girişler donanımsal kesmeler, yazılımsal kesmeler veya timer sinyali olabilmektedir.
Bu yazıda sonlu durum makinelerinin uygulanmasını bir kaç yaklaşımla anlatacağım.
Örneğin, bir elektronik kontak anahtarı projesini göz önünde bulunduralım. Elektronik kontak anahtarında durumlar gelen olaylar(event) ile değişmektedir. Aşağıda bir elektronik kontak anahtarına ait durumlarından bahsettim.
Elektronik kontak anahtarının durumları
Boş Durum (Idle State)
Sistem elektrik durumu (15/54) (Electric State)
Kızdırma durumu (17) (Heater State)
Marş durumu(50) (Starter State)
Başlangıç durumunda, Elektronik kontak anahtarı boş durumdadır. Elektronik kontak anahtarının çalışması için kullanıcıya ait şifrenin girilmesi gerekmektedir. Kullanıcı şifreyi girip onayladığı zaman başlangıç durumu, sistem elektrik durumuna geçer 15/54’e ait röle aktif olmaktadır. Şifre girildikten sonra onay tuşuna 20sn boyunca basınca kızdırma durumuna geçerek kızdırma rölesi aktif edilir. 20 sn’yi geçince ise kızdırma durumu sonlanır ve marş durumuna geçer. Marş durumunda ise 15/54 yine aktif,kızdırma rölesi kapanır, marş rölesi aktif olur. Marş durumu tamamlanınca ise mars rölesi kapanır elektrik durumuna geçmektedir. Elektrik durumu ise keypadden girilen iptal tuşu ile kapanmaktadır. Bu olaylar örgüsü aşağıdaki görseldeki gibidir.
Olay temelli durum makinelerinde uygulanması için iki farklı popüler yaklaşım C programlamada mevcuttur. Bu yaklaşımların seçimi gereksinimlere ve durumlara bağladır.
- Koşullu önerme (Conditional Statement)
- Lookup table metodunun kullanılması
Bu yazıda koşullu önerme metodu uygulanacaktır.
Sonlu Durum Makineleri için Koşullu Önerme Metodunun Kullanılması
Sonlu durum makinelerin uygulanması için en kolay yoldur. Tetiklenen olayların ve durumların kontrolü için bu yöntemde if-else veya switch-case kullanılmaktadır. Aşağıda yukarıda elektronik kontak anahtarına ait sonlu durum makineleri için koşullu önerme metodunun kullanıldığı kod mevcuttur.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 |
#include <stdio.h> /*Project Name: ELECTRONİC IGNITION SWITCH */ //Elektronik Kontak Anahtarina ait Durumlar(States) int c; typedef enum { Idle_State, Electric_State, Heater_State, Starter_State, } eSystemState; //Farklı olaylar (Events) typedef enum { Keyword_Enter_Event, Okey_Enter_Event, Timer_Event, Timer_Not_Event, Okey_Cancel_Event, Cancel_Enter_Event, } eSystemEvent; //eventhandlers Prototipleri eSystemState KeywordEnterHandler(void) { scanf("%d",&c); printf("1.role calisti"); return Electric_State; } eSystemState OkeyEnterHandler(void) { return Heater_State; } eSystemState TimerNotHandler(void) { return Electric_State; } eSystemState TimerHandler(void) { return Starter_State; } eSystemState OkeyCancelHandler(void) { return Electric_State; } eSystemState CancelEnterHandler(void) { printf("iki kez led yandi\n"); printf("buzzer öttü\n"); printf("cihaz uykuya alindi\n"); return Idle_State; } int main(int argc, char *argv[]) { eSystemState eNextState =Idle_State; //Read system Events eSystemEvent eNewEvent = Keyword_Enter_Event; switch(eNextState) { case Idle_State: { if(Keyword_Enter_Event == eNewEvent) { eNextState = KeywordEnterHandler(); } } break; case Electric_State: { if(Okey_Enter_Event == eNewEvent) { eNextState =OkeyEnterHandler(); } else if(Cancel_Enter_Event==eNewEvent) { eNextState = CancelEnterHandler(); } } break; case Heater_State: { if( Timer_Event == eNewEvent) { eNextState = TimerHandler(); } else if(Timer_Not_Event==eNewEvent) { eNextState = TimerNotHandler(); } } case Starter_State: { if( Okey_Cancel_Event == eNewEvent) { eNextState = OkeyCancelHandler(); } } break; break; default: break; } return 0; } |