FSM Lecture 55- QHSM_INIT() and QHSM_DISPATCH() APIs

 

QHSM_INIT() and QHSM_DISPATCH() APIs

 

 

In this article, let’s explore the QHSM_INIT() and QHSM_DISPATCH() APIs.

Figure 1.QHSM_INIT API reference
Figure 1. QHSM_INIT API reference

Polymorphically executes the top-most initial transition in the state machine. You have initialized the state variable with the initial state handler in the previous step, and now you have to execute the top-most initial transition in the SM. You have to call the QHSM_INIT function with a ‘me’ pointer. You can see the example in Figure 1. That is the pointer to the Superclass. This must be called once after the SM “constructor.”

#include <Arduino.h>
#include "qpn.h"
#include "QHSM_Test.h"
Q_DEFINE_THIS_FILE;

void setup() {
  // put your setup code here, to run once:
  QHsmTst_ctor();
  QHSM_INIT(super_QHsmTst);
}

QHSM_INIT function

After the QHsmTst_ctor(), write QHSM_INIT. You already have a QHsmTst pointer to the superclass. Just use that super_QHsmTst

You have to define QHSM_INIT(super_QHsmTst)  macro. So, Q_DEFINE_THIS_FILE. Use this macro in the main.cpp, which defines the Q_this_module_variable. Which nothing but it’s an array that stores the file’s name (a module name); it stores the module name.

 

Now, we have to collect the events and dispatch it using QHSM_DISPATCH.

FSM Event Handling: QHSM_INIT() and QHSM_DISPATCH() APIs
Figure 2. QHSM_DISPATCH API reference

QHSM_DISPATCH dispatches the event to the dispatcher of the framework, and the framework then calls the appropriate state handler, and that’s how event execution happens. 

It processes one event at a time in Run-to-Completion fashion(RTC fashion). Just provide the ‘me’ pointer, which is the QHSM superclass’s pointer.

void loop() {
  // put your main code here, to run repeatedly:
  char ue;
  if(Serial.available() > 0){
    ue = Serial.read();
    if(ue == 'a' || ue == 'A'){
       Q_SIG(super_QHsmTst) = (QSignal)A_SIG;
    }
    else if (ue == 'b' || ue == 'B') Q_SIG(super_QHsmTst) = (QSignal)B_SIG;
    else if (ue == 'c' || ue == 'C') Q_SIG(super_QHsmTst) = (QSignal)C_SIG;
    else if (ue == 'd' || ue == 'D') Q_SIG(super_QHsmTst) = (QSignal)D_SIG;
    else if (ue == 'e' || ue == 'E') Q_SIG(super_QHsmTst) = (QSignal)E_SIG;
    else if (ue == 'f' || ue == 'F') Q_SIG(super_QHsmTst) = (QSignal)F_SIG;
    else if (ue == 'g' || ue == 'G') Q_SIG(super_QHsmTst) = (QSignal)G_SIG;
    else if (ue == 'h' || ue == 'H') Q_SIG(super_QHsmTst) = (QSignal)H_SIG;
    else if (ue == 'i' || ue == 'I') Q_SIG(super_QHsmTst) = (QSignal)I_SIG;
    else if (ue == 'x' || ue == 'X') Q_SIG(super_QHsmTst) = (QSignal)TERMINATE_SIG;
    else Q_SIG(super_QHsmTst) = IGNORE_SIG;
  }

Q_SIG function

Here, let’s take the events. Let me take the events from the serial port. The events are from ‘A’ to ‘I.’ 

Let’s take one variable, char ue. [ue→ user event].

Let me just write this code  Serial.available(). If the data is available at the Serial Port,  Serial.available>0.

ue = Serial.read(); → user event, let’s read the serial port 1 byte. 

And if(ue == ‘a’ || ue == ‘A’), then we have to dispatch the event. The event name is A_SIG

super_QHsmTst-> evt.sig = (QSignal)A_SIG; → Here take the super_QHsmTst pointer and dereference that, evt.sig = A_SIG, its type is QSignal just typecast that. Like that. Super_QHsmTst pointer itself holds the signal.

 

Instead of writing super_QHsmTst-> evt.sig = (QSignal)A_SIG, you can just do something like this Q_SIG(super_QHsmTst) = (QSignal)A_SIG;  You can just use the macro Q_SIG of the HSM pointer super_QHsmTst. That you can find in ‘qepn.h’.

else if (ue == ‘b’ || ue == ‘B’)Q_SIG(super_QHsmTst) = (QSignal)B_SIG;  Like that you have to write up to I. ‘A’ to ‘I’. Like this, you have to add different events, as per the user event to the superclass pointer.

And if the user entered character is other than these values, you can invent one an event called IGNORE_SIG. 

You can add that IGNORE_SIG, as shown in Figure 3.

FSM Event Handling: QHSM_INIT() and QHSM_DISPATCH() APIs
Figure 3. Adding IGNORE_SIG

 

After that, in the end, you use the function QHSM_DISPATCH. And you just use super_QHsmTst pointer. After that, print the new line character here to push the next message to the new line, as shown below. And add it to the setup function as well. 

   QHSM_DISPATCH(super_QHsmTst);
   Serial.print('\n');
}

QHSM_DISPATCH function

 

Get the Full course on Embedded System Design using UML State Machines Here

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.