Exercise-004 State table approach for implementation of an FSM part-4
Let’s continue protimer_state_table_init coding.
We just completed protimer_state_table_init function. Now, let’s give the prototype of this function in the main.cpp, as shown in Figure 1.
Whenever the control first comes to the setup function, it calls the state_table_init with the address of the main application structure. The address is &protimer. Now, we did this. Our state table is ready in the state_table variable of mobj. Now, let’s fix the protimer_init function first. Let’s go there.
In the protimer_init function, first, we set up an event, active_state is made as IDLE, a pro_time variable is set to 0, then you have to call the ENTRY function of IDLE state. And you have to get that from the mobj state_table_pointer.
void protimer_init(protimer_t *mobj){
event_t ee;
e_handler_t ehandler;
ee.sig = ENTRY;
mobj->active_state = IDLE;
mobj->pro_time = 0;
ehandler = (e_handler_t) mobj->state_table[IDLE * MAX_SIGNALS + ENTRY];
}
Protimer_init function
How to get that?
Let’s create one variable e_handler_t ehandler; ehandler is a function pointer variable of e_handler_t type. This we defined in the main.h, so, hope you remember this.
ehandler, you have to get the address from the mobj-> state_table pointer. Remember, this is a pointer variable of type int *. This has to be treated as a pointer to the one-dimensional array.
How to fetch IDLE states entry address?
That is this value. First, you have to arrive at IDLE_Inc_time() place because of the row number in question. That is IDLE. IDLE multiplied by MAX_SIGNALS or MAX_COLUMNS. IDLE is 0, it’s value is 0; 0 multiplied by 7 is 0.You arrive here (IDLE_Inc_time(). And for this, you have to add its value. ENTRY you have to add. ENTRY is 5. You arrive at IDLE_Entry, as shown in Figure 2. Like this, you have to dereference this pointer.
Now, if you do this, what happens? The value stored in IDLE_Entry will be fetched and assigned to ehandler, which is nothing but a function pointer or address of a function. And its type is e_handler_t. We may have to typecast this.
And after that, jump to the ehandler function pointer. (*ehandler)(mobj,&ee). Now we fixed the init function.
Let’s go back to the main.cpp, and we will code for the event dispatcher. The event dispatcher code is shown below.
static void protimer_event_dispatcher(protimer_t *const mobj,event_t const *const e){ event_status_t status; protimer_state_t source, target; e_handler_t ehandler; source = mobj->active_state; ehandler = (e_handler_t) mobj->state_table[mobj->active_state * MAX_SIGNALS + e->sig]; if(ehandler) status = (*ehandler)(mobj,e); if(status == EVENT_TRANSITION){ target = mobj->active_state; event_t ee; //1. run the exit action for the source state ee.sig = EXIT; ehandler =(e_handler_t) mobj->state_table[source*MAX_SIGNALS + EXIT]; if(ehandler) (*ehandler)(mobj,&ee); //2. run the entry action for the target state ee.sig = ENTRY; ehandler =(e_handler_t) mobj->state_table[target * MAX_SIGNALS + ENTRY]; if(ehandler) (*ehandler)(mobj,&ee); } }
Event dispatcher code
How to build a different project in this workspace? I want to build the 004Protimer_SH project now.
You need to click here on that project, and then you will select your project. I select 004Protimer_SH. Then, it changes to 004Protimer_SH. When you build, it builds that project. Like that, you can switch between different projects.
We will check it on the hardware to see whether the output is the same as before. Try to reproduce this at your desk and reverify it. And with that note, I would like to end this article on implementing state machines using the state table method.
FastBit Embedded Brain Academy Courses
Click here: https://fastbitlab.com/course1