Bird
Raised Fist0
Embedded Cprogramming~20 mins

Event-driven state machine in Embedded C - Practice Problems & Coding Challenges

Choose your learning style10 modes available
Challenge - 5 Problems
🎖️
Event-driven State Machine Master
Get all challenges correct to earn this badge!
Test your skills under time pressure!
❓ Predict Output
intermediate
2:00remaining
Output of a simple event-driven state machine

What is the output of this embedded C code simulating a simple event-driven state machine?

Embedded C
#include <stdio.h>

typedef enum {STATE_IDLE, STATE_RUN, STATE_STOP} State;
typedef enum {EVENT_START, EVENT_STOP, EVENT_RESET} Event;

State current_state = STATE_IDLE;

void handle_event(Event e) {
    switch(current_state) {
        case STATE_IDLE:
            if (e == EVENT_START) {
                current_state = STATE_RUN;
                printf("Started\n");
            }
            break;
        case STATE_RUN:
            if (e == EVENT_STOP) {
                current_state = STATE_STOP;
                printf("Stopped\n");
            } else if (e == EVENT_RESET) {
                current_state = STATE_IDLE;
                printf("Reset to Idle\n");
            }
            break;
        case STATE_STOP:
            if (e == EVENT_RESET) {
                current_state = STATE_IDLE;
                printf("Reset to Idle\n");
            }
            break;
    }
}

int main() {
    handle_event(EVENT_START);
    handle_event(EVENT_STOP);
    handle_event(EVENT_RESET);
    return 0;
}
A
Started
Reset to Idle
Stopped
B
Reset to Idle
Started
Stopped
C
Started
Stopped
Reset to Idle
D
Stopped
Started
Reset to Idle
Attempts:
2 left
💡 Hint

Trace the state changes step by step and note the printed messages.

🧠 Conceptual
intermediate
1:30remaining
Understanding event-driven state machine transitions

In an event-driven state machine, what best describes the role of the event handler function?

AIt directly modifies hardware registers without checking states.
BIt resets the state machine to the initial state on every event.
CIt only logs events without affecting the state machine.
DIt changes the current state based on the received event and current state.
Attempts:
2 left
💡 Hint

Think about how the state machine reacts to events.

🔧 Debug
advanced
2:00remaining
Identify the error in this event-driven state machine code

What error will this code produce when compiled or run?

Embedded C
#include <stdio.h>

typedef enum {IDLE, RUNNING} State;
typedef enum {START=1, STOP=2} Event;

State current_state = IDLE;

void handle_event(Event e) {
    switch(current_state) {
        case IDLE:
            if (e = START) {
                current_state = RUNNING;
                printf("Running\n");
            }
            break;
        case RUNNING:
            if (e == STOP) {
                current_state = IDLE;
                printf("Idle\n");
            }
            break;
    }
}

int main() {
    handle_event(START);
    handle_event(STOP);
    return 0;
}
ALogical error: the condition 'if (e = START)' assigns instead of compares, causing always true
BCompilation error due to missing semicolon
CRuntime error due to null pointer dereference
DNo error, outputs 'Running' then 'Idle'
Attempts:
2 left
💡 Hint

Look carefully at the if condition inside the IDLE case.

📝 Syntax
advanced
1:30remaining
Syntax error in event-driven state machine code

Which option contains the correct syntax to define an event-driven state machine handler function in embedded C?

A
void handle_event(Event e) {
    switch current_state {
        case IDLE:
            if (e == START) {
                current_state = RUNNING;
            }
            break;
    }
}
B
void handle_event(Event e) {
    switch(current_state) {
        case IDLE:
            if (e == START) {
                current_state = RUNNING;
            }
            break;
    }
}
C
void handle_event(Event e) {
    switch(current_state) 
        case IDLE:
            if (e == START) {
                current_state = RUNNING;
            }
            break;
    }
D
void handle_event(Event e) {
    switch(current_state) {
        case IDLE
            if (e == START) {
                current_state = RUNNING;
            }
            break;
    }
}
Attempts:
2 left
💡 Hint

Remember the syntax for switch statements in C.

🚀 Application
expert
2:30remaining
Number of states after processing events in a complex state machine

Consider a state machine with states: INIT, READY, PROCESSING, ERROR, DONE. It starts in INIT. The events are: START, FAIL, COMPLETE, RESET. The transitions are:

  • INIT + START -> READY
  • READY + START -> PROCESSING
  • PROCESSING + COMPLETE -> DONE
  • PROCESSING + FAIL -> ERROR
  • ERROR + RESET -> INIT
  • DONE + RESET -> INIT

If the event sequence is START, START, FAIL, RESET, START, COMPLETE, how many times does the state machine enter the READY state?

A2
B3
C1
D0
Attempts:
2 left
💡 Hint

Trace the states step by step for each event.

Practice

(1/5)
1. What is the main purpose of an event-driven state machine in embedded C?
easy
A. To change behavior based on events and current state
B. To execute code sequentially without conditions
C. To store large amounts of data in memory
D. To perform mathematical calculations only

Solution

  1. Step 1: Understand the concept of event-driven state machine

    An event-driven state machine changes its behavior depending on the current state and the events it receives.
  2. Step 2: Compare options with the concept

    To change behavior based on events and current state correctly describes this behavior. Other options describe unrelated concepts.
  3. Final Answer:

    To change behavior based on events and current state -> Option A
  4. Quick Check:

    Event-driven state machine = change behavior by events [OK]
Hint: Remember: state machines react to events and states [OK]
Common Mistakes:
  • Thinking state machines just run code sequentially
  • Confusing state machines with data storage
  • Assuming state machines only do math
2. Which of the following is the correct way to define states in an event-driven state machine using embedded C?
easy
A. int STATE_IDLE = 0; int STATE_RUN = 1; int STATE_STOP = 2;
B. #define STATE_IDLE 0 #define STATE_RUN 1 #define STATE_STOP 2
C. typedef enum {STATE_IDLE, STATE_RUN, STATE_STOP} State;
D. char* states[] = {"IDLE", "RUN", "STOP"};

Solution

  1. Step 1: Identify proper enum syntax in embedded C

    Using typedef enum with named states is the standard and clear way to define states.
  2. Step 2: Check options for correctness and clarity

    The typedef enum syntax is the preferred choice for type safety and readability. Using separate ints, #defines, or string arrays lacks these benefits and is less idiomatic.
  3. Final Answer:

    typedef enum {STATE_IDLE, STATE_RUN, STATE_STOP} State; -> Option C
  4. Quick Check:

    Use enum typedef for states [OK]
Hint: Use typedef enum for clear state names [OK]
Common Mistakes:
  • Using #define instead of enum for states
  • Using strings instead of enums for states
  • Not using typedef with enum
3. Given the following code snippet, what will be the value of current_state after handle_event(EVENT_START) is called?
typedef enum {STATE_IDLE, STATE_RUN, STATE_STOP} State;
typedef enum {EVENT_START, EVENT_STOP} Event;

State current_state = STATE_IDLE;

void handle_event(Event e) {
    switch(current_state) {
        case STATE_IDLE:
            if (e == EVENT_START) current_state = STATE_RUN;
            break;
        case STATE_RUN:
            if (e == EVENT_STOP) current_state = STATE_STOP;
            break;
        case STATE_STOP:
            break;
    }
}

handle_event(EVENT_START);
medium
A. Compilation error
B. STATE_RUN
C. STATE_STOP
D. STATE_IDLE

Solution

  1. Step 1: Check initial state and event

    The initial state is STATE_IDLE. The event passed is EVENT_START.
  2. Step 2: Follow the switch-case logic

    In STATE_IDLE, if event is EVENT_START, current_state changes to STATE_RUN.
  3. Final Answer:

    STATE_RUN -> Option B
  4. Quick Check:

    EVENT_START in STATE_IDLE moves to STATE_RUN [OK]
Hint: Trace event in current state switch-case [OK]
Common Mistakes:
  • Ignoring event condition inside the case
  • Assuming state changes without event match
  • Thinking code has syntax errors
4. Identify the bug in this event-driven state machine code snippet:
typedef enum {STATE_IDLE, STATE_RUN} State;
typedef enum {EVENT_START, EVENT_STOP} Event;

State current_state = STATE_IDLE;

void handle_event(Event e) {
    switch(current_state) {
        case STATE_IDLE:
            if (e = EVENT_START) current_state = STATE_RUN;
            break;
        case STATE_RUN:
            if (e == EVENT_STOP) current_state = STATE_IDLE;
            break;
    }
}
medium
A. State enum missing STATE_STOP
B. Missing default case in switch statement
C. current_state not initialized
D. Using assignment '=' instead of comparison '==' in if condition

Solution

  1. Step 1: Inspect the if condition in STATE_IDLE case

    The condition uses 'if (e = EVENT_START)', which assigns EVENT_START to e instead of comparing.
  2. Step 2: Understand the effect of assignment in condition

    Assignment returns the assigned value, which is non-zero, so condition is always true, causing incorrect state changes.
  3. Final Answer:

    Using assignment '=' instead of comparison '==' in if condition -> Option D
  4. Quick Check:

    Use '==' for comparison, not '=' [OK]
Hint: Check if conditions use '==' not '=' [OK]
Common Mistakes:
  • Confusing '=' and '==' in conditions
  • Ignoring missing default case (not critical here)
  • Assuming all states must be defined
5. You want to add a new state STATE_PAUSE and event EVENT_PAUSE to the existing state machine. Which code snippet correctly updates the handle_event function to handle pausing from STATE_RUN and resuming back to STATE_RUN from STATE_PAUSE?
hard
A. case STATE_RUN: if (e == EVENT_PAUSE) current_state = STATE_PAUSE; else if (e == EVENT_STOP) current_state = STATE_IDLE; break; case STATE_PAUSE: if (e == EVENT_PAUSE) current_state = STATE_RUN; break;
B. case STATE_RUN: if (e == EVENT_PAUSE) current_state = STATE_IDLE; break; case STATE_PAUSE: if (e == EVENT_PAUSE) current_state = STATE_STOP; break;
C. case STATE_RUN: if (e == EVENT_STOP) current_state = STATE_PAUSE; break; case STATE_PAUSE: if (e == EVENT_PAUSE) current_state = STATE_IDLE; break;
D. case STATE_RUN: if (e == EVENT_PAUSE) current_state = STATE_STOP; break; case STATE_PAUSE: if (e == EVENT_STOP) current_state = STATE_RUN; break;

Solution

  1. Step 1: Understand desired transitions

    From STATE_RUN, EVENT_PAUSE should move to STATE_PAUSE. From STATE_PAUSE, EVENT_PAUSE should resume to STATE_RUN.
  2. Step 2: Check each option for correct transitions

    case STATE_RUN: if (e == EVENT_PAUSE) current_state = STATE_PAUSE; else if (e == EVENT_STOP) current_state = STATE_IDLE; break; case STATE_PAUSE: if (e == EVENT_PAUSE) current_state = STATE_RUN; break; matches these transitions exactly. Other options assign wrong states or events.
  3. Final Answer:

    case STATE_RUN: if (e == EVENT_PAUSE) current_state = STATE_PAUSE; else if (e == EVENT_STOP) current_state = STATE_IDLE; break; case STATE_PAUSE: if (e == EVENT_PAUSE) current_state = STATE_RUN; break; -> Option A
  4. Quick Check:

    Pause toggles between RUN and PAUSE states [OK]
Hint: Match events to correct state transitions carefully [OK]
Common Mistakes:
  • Assigning wrong states on pause/resume events
  • Confusing EVENT_PAUSE with EVENT_STOP
  • Missing else if for multiple events
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard