|
1 | 1 | # FSM |
2 | 2 |
|
| 3 | +A lightweight C library for building and executing finite state machines with minimal overhead. Easily define states, transitions, composite events, and associate entry, update, and exit actions for each state. |
| 4 | + |
3 | 5 | ## Features |
4 | 6 |
|
5 | 7 | * Flat state machine model (no nested states by default) |
|
10 | 12 |
|
11 | 13 | ## Examples |
12 | 14 |
|
13 | | -* [Multi‑function button](examples/multi_function_button/) |
| 15 | +* Multi‑function button handler (single, double, long press) |
| 16 | +* Debounce filter with timeout confirmation |
| 17 | +* Generic GPIO‑driven state transitions |
| 18 | + |
| 19 | +## How to use |
| 20 | + |
| 21 | +A quick guide to set up a simple FSM with two states (`IDLE`, `RUNNING`), a timeout transition, and a completion flag. |
| 22 | + |
| 23 | +1. **Define FSM states** |
| 24 | + |
| 25 | + ```c |
| 26 | + typedef enum { |
| 27 | + STATE_IDLE = 0, |
| 28 | + STATE_RUNNING |
| 29 | + } state_t; |
| 30 | + ``` |
| 31 | +
|
| 32 | +2. **Declare FSM instance and event variables** |
| 33 | +
|
| 34 | + ```c |
| 35 | + fsm_t fsm; |
| 36 | + uint32_t get_time_ms(void) { return 0; /* dummy time source */ } |
| 37 | + int done_flag = 0; |
| 38 | + ``` |
| 39 | + |
| 40 | +3. **Initialize the FSM** |
| 41 | + |
| 42 | + ```c |
| 43 | + fsm_init(&fsm, STATE_IDLE, get_time_ms); |
| 44 | + ``` |
| 45 | +
|
| 46 | +4. **Add transitions with their events** |
| 47 | +
|
| 48 | + * **IDLE → RUNNING** on a 100 ms timeout |
| 49 | +
|
| 50 | + ```c |
| 51 | + fsm_trans_t *t; |
| 52 | + fsm_add_transition(&fsm, &t, STATE_IDLE, STATE_RUNNING); |
| 53 | + fsm_add_event_timeout(&fsm, t, 100); |
| 54 | + ``` |
| 55 | + * **RUNNING → IDLE** when `done_flag == 1` |
| 56 | +
|
| 57 | + ```c |
| 58 | + fsm_add_transition(&fsm, &t, STATE_RUNNING, STATE_IDLE); |
| 59 | + fsm_add_event_cmp(&fsm, t, &done_flag, 1, eval_eq); |
| 60 | + ``` |
| 61 | +
|
| 62 | +5. **Register state action callbacks** |
| 63 | +
|
| 64 | + ```c |
| 65 | + void on_enter_idle(void) { /* reset variables */ } |
| 66 | + void on_update_idle(void) { /* poll sensors or inputs */ } |
| 67 | + void on_enter_running(void) { /* start task */ } |
| 68 | + void on_exit_running(void) { /* cleanup */ } |
| 69 | +
|
| 70 | + fsm_register_state_actions(&fsm, STATE_IDLE, |
| 71 | + on_enter_idle, |
| 72 | + on_update_idle, |
| 73 | + NULL); |
| 74 | + fsm_register_state_actions(&fsm, STATE_RUNNING, |
| 75 | + on_enter_running, |
| 76 | + NULL, |
| 77 | + on_exit_running); |
| 78 | + ``` |
| 79 | + |
| 80 | +6. **Run the FSM in a loop** |
| 81 | + |
| 82 | + ```c |
| 83 | + while (1) { |
| 84 | + fsm_run(&fsm); |
| 85 | + delay_ms(10); /* dummy wait */ |
| 86 | + } |
| 87 | + ``` |
14 | 88 |
|
15 | 89 | ## Roadmap |
16 | 90 |
|
|
0 commit comments