FSM Lecture 43: Exercise-004 State table approach for implementation of an FSM part-3

  • Post author:
  • Post category:Blog

 

Exercise-004 State table approach for implementation of an FSM part-3

 

 

Inside the main.cpp, in the setup function, let’s call a function protimer_state_table_init. 

static void protimer_state_table_init(protimer_t *const mobj)
{
   static e_handler_t protimer_state_table[MAX_STATES][MAX_SIGNALS] = {
     [IDLE] = {&IDLE_Inc_time,NULL,&IDLE_Time_tick,&IDLE_Start_pause,NULL,&IDLE_Entry,&IDLE_Exit},
     [TIME_SET] = {},
     [COUNTDOWN] = {},
     [PAUSE] = {},
     [STAT] = {}
   };

    mobj->state_table = (uintptr_t*) &protimer_state_table[0][0];
}

Protimer_state_table_init function implementation

 

The protimer_state_table_init function is implemented below in the event dispatcher. And it receives the pointer to the main object (protimer_t *const mobj). Static function and returns nothing.

Here we have to create a two-dimensional array; I will call this protimer_state_table[MAX_STATES][MAX_SIGNALS]. This is a two-dimensional array of type function pointers

 

Let’s go to the main.h, and in various states, add one entry MAX_STATES, and in internal activity signals, you can add one more entry MAX_SIGNALS. 

//function pointer type for event handlers
typedef event_status_t (*e_handler_t)(protimer_t *const mobj, event_t const *const e);

Function pointer type for event handlers

And we will create one typedef function pointer definition, as shown above.

typedef event_status_t (*e_handler_t)(protimer_t *const mobj, event_t const *const e); And we will use e_handler_t for the array we are going to create—the array of function pointers of  e_handler_t type. 

 

You have to initialize protimer_state_table[MAX_STATES][MAX_SIGNALS] this two-dimensional array with the pointers. You have to initialize this exactly like this protimer state table, as shown in Figure 1.

FSM- Protimer state table 2 dimensional array
Figure 1. Protimer state table

 

The first row is for the IDLE state, and the first event is INC_TIME, the second event is DEC_TIME, the third event is TIME_TICK, fourth is START_PAUSE, like that. Exactly like this table.

You can also do like this while doing two-dimensional array initialization, as shown in Figure 2. There are two rows, two columns. First, you write the row number. [0] signifies that you are initializing row number 0 and then using the braces to initialize that row. This is also valid initialization. 

 

FSM - Initialization of 2 dimensional array
Figure 2. Initialization of 2 dimensional array

 

[0]={1,2} signifies that you are initializing row 0. [1]={3,4} signifies that you are initializing row number 1. So, I’ll use a similar approach to provide more clarity.

Let’s go to the main.cpp, first, let me initialize for row 0, which is for IDLE state, [IDLE] = {}, that’s a first row initialization. Next as per the table it is for TIME_SET, [TIME_SET] = {}. Next for COUNTDOWN, next for PAUSE, next for STAT. These are five rows, and after that, each row should have seven entries. Some are Null because this indicates that the event is not handled by that state for that event.

First, you have to mention the event handler for Increment time while in the IDLE state.

[IDLE] = {&IDLE_Inc_time, NULL, &IDLE_Time_tick, &IDLE_Start_pause, NULL, &IDLE_Entry, &IDLE_Exit}   

IDLE_Inc_time, next is NULL, next for Time_time, address of IDLE_Time_tick. After that, IDLE_Start_pause, after that NULL, address of IDLE_Entry, and address of IDLE_Exit, look at Figure 3. MAX_SIGNALS value 7. That should be seven entries here. Similarly, you do it for TIME_SET, COUNTDOWN, PAUSE, and STAT. 

Once you complete this initialization, you store the protimer_state_table pointer in our main application object. Because we need it later in the dispatcher function. We have to access this state table to get the appropriate handle address. 

That’s why let’s go to the main application structure, and here will create a pointer to a state table. uintptr_t *state_table; state_table is a pointer variable to hold the address of that array.

Let’s go back to main.cpp. In the main object, get the pointer state_table and store it here address of protimer_state_table. mobj->state_table = &protimer_state_table[0][0];

The base address is nothing but the address of the first element, that is [0] [0]. You use the ‘& .’ The pointer is of e_handler_t type. That’s why you may have to typecast this uintptr_t*.

 

FastBit Embedded Brain Academy Courses

Click here: https://fastbitlab.com/course1

 

FastBitLab

The FastBit Embedded Brain Academy uses the power of internet to bring the online courses related to the field of embedded system programming, Real time operating system, Embedded Linux systems, etc at your finger tip with very low cost. Backed with strong experience of industry, we have produced lots of courses with the customer enrolment over 3000+ across 100+ countries.