Skip to content

Commit be257f9

Browse files
Update Readme file for better navigation
1 parent 544a860 commit be257f9

File tree

2 files changed

+655
-668
lines changed

2 files changed

+655
-668
lines changed
Lines changed: 259 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -1,120 +1,289 @@
1-
## Finite State Machine (Conditional Statement Implementation)
1+
# Finite State Machine (FSM) Implementation
22

3-
#### FSM Diagram
4-
![fsm](./stateMachine.png)
3+
## Overview
4+
A Finite State Machine (FSM) is a computational model used to design computer programs and digital logic circuits. It consists of a finite number of states, transitions between those states, and actions. FSMs are particularly important in embedded systems for managing system behavior, user interfaces, and protocol implementations.
55

6-
#### Usage
7-
```
6+
## Key Concepts
7+
8+
### States
9+
- **Idle State**: Initial state when no card is inserted
10+
- **Card Inserted State**: State after a card is inserted
11+
- **PIN Entered State**: State after PIN is entered
12+
- **Option Selected State**: State after user selects an option
13+
- **Amount Entered State**: State after amount is entered
14+
15+
### Events
16+
- **Card Insert Event**: Triggered when a card is inserted
17+
- **PIN Enter Event**: Triggered when PIN is entered
18+
- **Option Selection Event**: Triggered when user selects an option
19+
- **Amount Enter Event**: Triggered when amount is entered
20+
- **Amount Dispatch Event**: Triggered when amount is dispatched
21+
22+
### Transitions
23+
The FSM transitions between states based on events. Each transition is handled by a specific event handler function.
24+
25+
## Implementation
26+
27+
### FSM Diagram
28+
![FSM State Diagram](./stateMachine.png)
29+
30+
### Usage
31+
```bash
832
make
933
./stateMachine
1034
```
1135

12-
#### Code
36+
### Code Implementation
37+
38+
#### Header File (`state_machine.h`)
1339
```c
40+
#ifndef STATE_MACHINE_H
41+
#define STATE_MACHINE_H
42+
1443
#include <stdio.h>
1544
#include <stdlib.h>
16-
//Different state of ATM machine
17-
typedef enum
18-
{
19-
Idle_State,
20-
Card_Inserted_State,
21-
Pin_Eentered_State,
22-
Option_Selected_State,
23-
Amount_Entered_State,
45+
46+
// System states enumeration
47+
typedef enum {
48+
IDLE_STATE,
49+
CARD_INSERTED_STATE,
50+
PIN_ENTERED_STATE,
51+
OPTION_SELECTED_STATE,
52+
AMOUNT_ENTERED_STATE,
53+
MAX_STATES
2454
} eSystemState;
25-
//Different type events
26-
typedef enum
27-
{
28-
Card_Insert_Event,
29-
Pin_Enter_Event,
30-
Option_Selection_Event,
31-
Amount_Enter_Event,
32-
Amount_Dispatch_Event
55+
56+
// System events enumeration
57+
typedef enum {
58+
CARD_INSERT_EVENT,
59+
PIN_ENTER_EVENT,
60+
OPTION_SELECTION_EVENT,
61+
AMOUNT_ENTER_EVENT,
62+
AMOUNT_DISPATCH_EVENT,
63+
MAX_EVENTS
3364
} eSystemEvent;
34-
//Prototype of eventhandlers
35-
eSystemState AmountDispatchHandler(void)
36-
{
37-
return Idle_State;
65+
66+
// Function prototypes
67+
eSystemState amountDispatchHandler(void);
68+
eSystemState enterAmountHandler(void);
69+
eSystemState optionSelectionHandler(void);
70+
eSystemState enterPinHandler(void);
71+
eSystemState insertCardHandler(void);
72+
73+
// State machine functions
74+
void stateMachineInit(void);
75+
eSystemState processEvent(eSystemState currentState, eSystemEvent event);
76+
const char* getStateName(eSystemState state);
77+
const char* getEventName(eSystemEvent event);
78+
79+
#endif // STATE_MACHINE_H
80+
```
81+
82+
#### Implementation File (`state_machine.c`)
83+
```c
84+
#include "state_machine.h"
85+
86+
// Event handler functions
87+
eSystemState amountDispatchHandler(void) {
88+
printf("Amount dispatched. Returning to idle state.\n");
89+
return IDLE_STATE;
3890
}
39-
eSystemState EnterAmountHandler(void)
40-
{
41-
return Amount_Entered_State;
91+
92+
eSystemState enterAmountHandler(void) {
93+
printf("Amount entered successfully.\n");
94+
return AMOUNT_ENTERED_STATE;
4295
}
43-
eSystemState OptionSelectionHandler(void)
44-
{
45-
return Option_Selected_State;
96+
97+
eSystemState optionSelectionHandler(void) {
98+
printf("Option selected successfully.\n");
99+
return OPTION_SELECTED_STATE;
46100
}
47-
eSystemState EnterPinHandler(void)
48-
{
49-
return Pin_Eentered_State;
101+
102+
eSystemState enterPinHandler(void) {
103+
printf("PIN entered successfully.\n");
104+
return PIN_ENTERED_STATE;
50105
}
51-
eSystemState InsertCardHandler(void)
52-
{
53-
return Card_Inserted_State;
106+
107+
eSystemState insertCardHandler(void) {
108+
printf("Card inserted successfully.\n");
109+
return CARD_INSERTED_STATE;
54110
}
55-
int main(int argc, char *argv[])
56-
{
57-
eSystemState eNextState = Idle_State;
58-
eSystemEvent eNewEvent;
59-
char input;
60-
while(1)
61-
{
62-
printf("curState: %d\n", eNextState);
63-
//Read system Events
64-
printf("please enter event\n0 = Card_Insert_Event\n1 = Pin_Enter_Event\n2 = Option_Selection_Event\n3 = Amount_Enter_Event\n4 = Amount_Dispatch_Event\n");
65-
input = getchar( );
66-
eSystemEvent eNewEvent = atoi(&input);
67-
switch(eNextState)
68-
{
69-
case Idle_State:
70-
{
71-
if(Card_Insert_Event == eNewEvent)
72-
{
73-
eNextState = InsertCardHandler();
111+
112+
// State machine processing function
113+
eSystemState processEvent(eSystemState currentState, eSystemEvent event) {
114+
switch(currentState) {
115+
case IDLE_STATE:
116+
if(event == CARD_INSERT_EVENT) {
117+
return insertCardHandler();
74118
}
75-
}
76-
break;
77-
case Card_Inserted_State:
78-
{
79-
if(Pin_Enter_Event == eNewEvent)
80-
{
81-
eNextState = EnterPinHandler();
119+
break;
120+
121+
case CARD_INSERTED_STATE:
122+
if(event == PIN_ENTER_EVENT) {
123+
return enterPinHandler();
82124
}
83-
}
84-
break;
85-
case Pin_Eentered_State:
86-
{
87-
if(Option_Selection_Event == eNewEvent)
88-
{
89-
eNextState = OptionSelectionHandler();
125+
break;
126+
127+
case PIN_ENTERED_STATE:
128+
if(event == OPTION_SELECTION_EVENT) {
129+
return optionSelectionHandler();
90130
}
91-
}
92-
break;
93-
case Option_Selected_State:
94-
{
95-
if(Amount_Enter_Event == eNewEvent)
96-
{
97-
eNextState = EnterAmountHandler();
131+
break;
132+
133+
case OPTION_SELECTED_STATE:
134+
if(event == AMOUNT_ENTER_EVENT) {
135+
return enterAmountHandler();
98136
}
99-
}
100-
break;
101-
case Amount_Entered_State:
102-
{
103-
if(Amount_Dispatch_Event == eNewEvent)
104-
{
105-
eNextState = AmountDispatchHandler();
137+
break;
138+
139+
case AMOUNT_ENTERED_STATE:
140+
if(event == AMOUNT_DISPATCH_EVENT) {
141+
return amountDispatchHandler();
106142
}
107-
}
108-
break;
143+
break;
144+
109145
default:
110-
printf("invalid input\n");
146+
printf("Invalid state: %d\n", currentState);
147+
break;
148+
}
149+
150+
printf("Invalid event %s for state %s\n", getEventName(event), getStateName(currentState));
151+
return currentState;
152+
}
153+
154+
// Utility functions
155+
const char* getStateName(eSystemState state) {
156+
static const char* stateNames[] = {
157+
"IDLE_STATE",
158+
"CARD_INSERTED_STATE",
159+
"PIN_ENTERED_STATE",
160+
"OPTION_SELECTED_STATE",
161+
"AMOUNT_ENTERED_STATE"
162+
};
163+
return (state < MAX_STATES) ? stateNames[state] : "UNKNOWN_STATE";
164+
}
165+
166+
const char* getEventName(eSystemEvent event) {
167+
static const char* eventNames[] = {
168+
"CARD_INSERT_EVENT",
169+
"PIN_ENTER_EVENT",
170+
"OPTION_SELECTION_EVENT",
171+
"AMOUNT_ENTER_EVENT",
172+
"AMOUNT_DISPATCH_EVENT"
173+
};
174+
return (event < MAX_EVENTS) ? eventNames[event] : "UNKNOWN_EVENT";
175+
}
176+
```
177+
178+
#### Main Application (`main.c`)
179+
```c
180+
#include "state_machine.h"
181+
182+
int main(int argc, char *argv[]) {
183+
eSystemState currentState = IDLE_STATE;
184+
eSystemEvent newEvent;
185+
char input;
186+
187+
printf("=== ATM State Machine Demo ===\n");
188+
printf("Available events:\n");
189+
printf("0 = Card Insert Event\n");
190+
printf("1 = PIN Enter Event\n");
191+
printf("2 = Option Selection Event\n");
192+
printf("3 = Amount Enter Event\n");
193+
printf("4 = Amount Dispatch Event\n");
194+
printf("q = Quit\n\n");
195+
196+
while(1) {
197+
printf("Current State: %s\n", getStateName(currentState));
198+
printf("Enter event (0-4, q to quit): ");
199+
200+
input = getchar();
201+
getchar(); // Consume newline
202+
203+
if(input == 'q' || input == 'Q') {
204+
printf("Exiting...\n");
111205
break;
112206
}
207+
208+
newEvent = (eSystemEvent)atoi(&input);
209+
210+
if(newEvent >= 0 && newEvent < MAX_EVENTS) {
211+
eSystemState nextState = processEvent(currentState, newEvent);
212+
if(nextState != currentState) {
213+
printf("State transition: %s -> %s\n",
214+
getStateName(currentState), getStateName(nextState));
215+
currentState = nextState;
216+
}
217+
} else {
218+
printf("Invalid event. Please enter 0-4 or q to quit.\n");
219+
}
220+
221+
printf("\n");
113222
}
223+
114224
return 0;
115225
}
226+
```
227+
228+
#### Makefile
229+
```makefile
230+
CC = gcc
231+
CFLAGS = -Wall -Wextra -std=c99
232+
TARGET = stateMachine
233+
SOURCES = main.c state_machine.c
234+
HEADERS = state_machine.h
116235

236+
$(TARGET): $(SOURCES) $(HEADERS)
237+
$(CC) $(CFLAGS) -o $(TARGET) $(SOURCES)
117238

239+
clean:
240+
rm -f $(TARGET)
241+
242+
.PHONY: clean
118243
```
119-
#### Reference
120-
https://aticleworld.com/state-machine-using-c/
244+
245+
## Common Interview Questions
246+
247+
1. **What is a Finite State Machine?**
248+
- A computational model with a finite number of states and transitions
249+
- Used for modeling behavior in embedded systems
250+
- Consists of states, events, and transitions
251+
252+
2. **What are the advantages of using FSMs?**
253+
- Clear and predictable behavior
254+
- Easy to debug and maintain
255+
- Modular design
256+
- Suitable for real-time systems
257+
258+
3. **How would you implement an FSM in C?**
259+
- Use enums for states and events
260+
- Implement state transition table or switch statements
261+
- Create event handler functions
262+
- Use a main loop to process events
263+
264+
4. **What are the different types of FSMs?**
265+
- **Moore Machine**: Output depends only on current state
266+
- **Mealy Machine**: Output depends on current state and input
267+
268+
5. **How would you handle invalid state transitions?**
269+
- Add error handling in transition logic
270+
- Log invalid transitions
271+
- Return to a safe state or error state
272+
273+
## Advanced Topics
274+
275+
### State Machine Patterns
276+
1. **Hierarchical State Machines**: States can contain sub-states
277+
2. **Nested State Machines**: States can be state machines themselves
278+
3. **Parallel State Machines**: Multiple state machines running concurrently
279+
280+
### Implementation Considerations
281+
- **Memory efficiency**: Use lookup tables for large state machines
282+
- **Performance**: Optimize transition logic for real-time systems
283+
- **Maintainability**: Use clear naming conventions and documentation
284+
- **Testing**: Create comprehensive test cases for all transitions
285+
286+
## Resources
287+
- [State Machine Using C - AticleWorld](https://aticleworld.com/state-machine-using-c/)
288+
- [Finite State Machines in Embedded Systems](https://embeddedartistry.com/blog/2018/07/12/an-introduction-to-finite-state-machines/)
289+
- [State Machine Design Patterns](https://www.state-machine.com/doc/concepts.html)

0 commit comments

Comments
 (0)