1

I have few state machines which run "concurrently" in a super loop.

do
{
  state_one();
  state_two();
  state_three();

  /* The point I want to deal with the error */

} while(1);

Each of these state machines might consist of other state machines.

I'm trying to figure out a way that I'll be able to catch an unexpected situation and parse it directly to main.

Which means, the error will have to go through all the states and every state has to deal with this error. For example: The microcontroller I'm using is an ATSAM4S Cortex-M4 and dealing with error might be:

  • System reset
  • Do not reset the watchdog timer
  • Print a sad message
  • Blink a led on the board
  • Write something in an external memory
  • Disable a power supply
  • Trigger a variable
  • Run another state machine
  • Force a state machine to change its state
  • Ignore the error

My state machines are implemented with pointer to function method

typedef struct My_state_machine_t
{
   uint32_t (*run)(struct My_state_machine_t * const This_state_p);
   uint64_t entry_time_ms; 
}My_state_machine_t;

state_one() might contain:

My_state_machine_t my_state = {
    .run = first_state;
    };

uint32_t state_one(void)
{
   if (my_state.run != NULL)
   {
      my_state.run(&my_state);
   }
   return 0;
}

uint32_t first_state(My_state_machine_t * const This_state_p)
{
   /* run some functions */

   // Now we are jumping to next state
   This_state_p->run = &this_is_the_next_state;
   This_state_p->entry_time_ms = system_get_ms();
   return 0;
}

Furthermore, every state will give different kind of error. Different kind of error means different action. Also, some errors might be common between states and in this case the "error manager" will have to take the same or similar decisions, (for instance system reset).

  • Is having each state_blah() function return a succes/failure code not going to work? – whatsisname Mar 8 '18 at 1:18
1

A global variable bit-field may come in handy. Each state has a set of defined bits within the bit-field, each of which are to provide a status.

For example, state machine one could set (and clear) bits called SM1_BAD_FOO, SM1_BAD_BAR, SM1_BAD_BAZ. In state machine 1, if "BAD FOO" happens, it sets the bit, otherwise it clears the bit. Same for other "BAD" events and other states.

Then in your main loop, you check to see if the global bit-field is non-zero. If it is, something bad happened, and it needs to handle it.

You could also make it such that each state can only SET the bit (not clear) and only the main loop can clear, that way if there are outside influences on the "BAD" going away, the main loop may have more visibility that each state machine.

FYI, this type of solution is fairly common in embedded systems.

  • This sounds like a reasonable approach in an embedded system. – Robert Harvey Apr 11 '18 at 17:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.