FSM Lecture 56: Exercise-006 Testing

 

Exercise-006 Testing

 

 

In the previous article, we completed the 006QHsmTest exercise. And now, let’s test this.

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

void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
Serial.println("QHSM Testing...");
QHsmTst_ctor();
QHSM_INIT(super_QHsmTst);
Serial.print('\n');
}

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;

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


Q_NORETURN Q_onAssert ( char_t const Q_ROM *const module,int_t const location ){

Serial.println("Assertion failure!!");
Serial.println((String)module);
Serial.println(location);
while(1);
}

006QHsmTest Exercise

Before testing in the setup function, please add Serial.begin(9600), which configures the baudrate of the UART. And also, I’ll send one message that is “QHSM Testing ”, as shown above. Now, let’s compile this. Let’s download.

Let me open the Arduino IDE serial terminal → Go to tools→ you have to select the board ‘Arduino Uno,’ → and then choose Serial Monitor.

You can see in the serial monitor the application ran and the initial transition; I mean, the actions related to the initial transition has been executed in that order, as shown in Figure 1. 

Figure 2. The initial transition action
Figure 1. The initial transition action

 

Now, let’s analyze that. Let’s go to the model. 

Figure 3. QHsmTst model
Figure 2. QHsmTst model

 

You can see Figure 2; The model starts from the initial transition, the arrow mark shows. ‘S’ is our outer shell. 

  • First, it executes the action related to the initial transition. The action is just printing “top-INIT.” That’s why, you see top-INIT in the serial monitor, that action is executed. 
  • After that, it enters the s2 state. As we discussed in the previous part of the course, the entry actions are executed from the outermost state to the innermost state while entering the nested states. The outermost state is s; the ENTRY action of this will be executed first. Just select that, and you can see the ENTRY and EXIT actions in the model. “s-ENTRY” is printed next.
  • And after that, the s2 state is entered because the initial transition points to s2 here. That’s why, after this, the state machine enters s2 state, s2’s ENTRY action will be executed. Look at the serial monitor(Figure 1) s2-ENTRY is executed. 

 

Figure 4. s2 init transition
Figure 3. s2 init transition
  • And when the state machine is in s2, s2-INIT transition shows the following state(Figure 3). This transition signifies which state has to enter when the state machine is in s2. That’s why the action related to this initial transition is executed next. s2_INIT. 
  • After that, the s2-Init transition enters s21. So, ENTRY action of s21 first; that’s why you can see  s21-ENTRY. 
  • After that, it directly enters s211 state, ENTRY action of s211. So, s211-ENTRY, like that. 

Now the state machine is settled at s211. s211 is now the current state of the state machine. 

 

Let’s test the event ‘D’. The state machine is in s211; let’s send the event D and see what happens. Figure 4 shows the Event D output in the serial monitor. This is a sequence of execution of different actions. Let’s analyze this.

Figure 5. The output of event D actions when the state machine is in s211
Figure 4. The output of event D actions when the state machine is in s211

 

Figure 6. Event D actions when the state machine is in s211
Figure 5. Event D actions when the state machine is in s211

 

In the state machine, s211 was the current active state, and it received the event D. When the event D is received, there is a transition. The transition is an external transition to s211, and it is a local transition for s21. 

  • First, the action associated with D is executed. So, this is a little different from the UML specification. The specification says, first, the EXIT action has to be executed. But, the implementation is a little different here with this framework; the action associated with the transition is executed first. So, s211-D is executed first. That’s why you see s211-D. 
  • And after that, it is an external transition, so EXIT action is executed next. s211-EXIT. 
  • After that, it enters s21. But, s21 is not entered, remember. Entering a state means when it has to be entered from the outside world. That’s why s21 is not entered here. The control went to s21 state. The ENTRY action will not be executed here because s21 was not entered from the external world. When it is in s21, it is a superclass of s211.

The state machine cannot settle at superclass. It has to finally go and settle at the state or settle at a simple state. s211 is a simple state, s21 is a superstate; So, it has to settle at sub-state. That’s why the s21-INIT transition will be executed next. Because, when it is in s21, it will be guided by the initial transition, which is guided by the initial pseudo-state. The action associated with s21_INIT is executed. That’s why you see s21_INIT. 

  • And after that, s211 is entered from the external world. That’s why the ENTRY action of s211 state will be executed at last. So you see, s211-ENTRY. Like that. Now, the state machine has settled at s211-ENTRY. 

 

The state machine is in s211.  When the state machine is in s211, what happens if event B is sent? Let’s analyze this.

When the state machine is in s211, let’s send event B, the actions are shown in Figure 6.

Figure 7. The output of event B actions when the state machine is in s211
Figure 6. The output of event B actions when the state machine is in s211

 

Figure 8.Event B actions when the state machine is in s211
Figure 7. Event B actions when the state machine is in s211
  • First of all, s211 doesn’t handle B. When it doesn’t handle B, the event will be propagated to its superstate. Its superstate is s21. Please note that the event is propagated; there is no transition. There is propagation. So, the event is propagated in s21. And s21 handles that event B. You can see Figure 8, which handles B. There is a local transition from s21 to s211. 

‘B’ is executed first, the action associated with a transition. That’s why you should see s21-B. s21-B is printed first.

  • After that, s211 state is entered. The ENTRY action of s211 has to be executed. But, the current state is still s211. The current state has not changed; it is s211. When it is in s211, how can it enter again? Unless it exists first and then re-enters. That’s why the EXIT action is executed first, and then the ENTRY action is executed next. It has to exit first; then it has to re-enter. Otherwise, that doesn’t make sense.

 

Now again, the current state is s211. The current state is s211, and what happens if I send the event ‘A’? The event A  actions are shown in Figure 8. Let’s analyze that.

Testing
Figure 8. The output of event A actions when the state machine is in s211

 

Testing
Figure 9. Event A actions when the state machine is in s211

 

A was sent, A is not handled by s211 state. So, the event is propagated to s21. Now, s21 handles that event. You can see that in Figure 10, there is a self-transition. That means the superstate s21 was left. When a superstate is left, all the EXIT actions must be executed right from the innermost state to the outer state. (Figure 9)

  • First, the action associated with this transition s21-A will be executed. 
  • Then EXIT action. The EXIT action has to be executed next s211-EXIT.
  • After that, innermost to outermost state, that’s why s21-EXIT is next. 
  • And then, it re-enters s21. If it is an ENTRY action, then outermost to innermost. 4th is s21-ENTRY. 
  • And when it comes to s21, the next state is guided by s21’s initial pseudo-state, and it has got its own action here. s21_ INIT is next. 
  • Then it goes to s211-ENTRY, like that. Finally, the state machine has settled at this sub-state s211.

 

Now, our current state is s211, and what happens if it receives the event H. Let’s send H. The event H actions are shown in Figure 10. Let’s analyze.

Testing
Figure 10. The output of event H actions when the state machine is in s211

 

Testing
Figure 11. Event H actions when the state machine is in s211
  • First of all, the s211 substate handles H; you can see that. First, the action associated with this transition → s211-H. 
  • After that, it is leaving s211 state. When is it leaving? All the EXIT actions have to be executed from innermost to outermost state. s211-EXIT is second.
  • s21-EXIT is third. 
  • After that, the 4th one is s2-EXIT. 
  • The transition is going to s. But, for  s, it is a local transition, and the state machine comes to this super state now ‘s’.  It is now guided by ‘s’ as an initial pseudo-state. So, the action associated with this will be executed; the 5th is s-INIT. 
  • And after that, it is directly guiding you to this state s11; now the ENTRY actions will come into the picture. s1-ENTRY next.
  • And next is s11-ENTRY. Now, our state machine has settled at s11 state. 

 

When the state machine has settled at s11 state, what happens if it receives H? You can see that in Figure 12, it came to  S11. Let’s analyze this. 

Testing
Figure 12. The output of event H actions when the state machine is in s11
  • When the state was s11, it received an H event. So, the first is s11-H. 
  • After that EXIT action. Two EXIT actions. S1-EXIT and s211-EXIT.
  • It comes to the superclass ‘s’ and is again guided by ‘s’ initial pseudo-state, s-INIT. 
  • And again, 2 ENTRY actions; s1-ENTRY, and s11-ENTRY. It is likewise settled at the S11 substate.

 

Now, our state machine is in s11. When the state machine is in s11, if you send I, it prints s1-I. Again send I, it prints s1-I. You can keep sending I here, it prints s1-I.  Let’s analyze the event ‘I’.

Testing
Figure 13. The output of event I actions when the state machine is in s11

 

Testing
Figure 14. Event I actions when the state machine is in s11

 

First of all, ‘I’ is not handled by the s11 state; that’s why it is propagated to its superstate. It comes to s1. As you can see, the superstate s1 handles ‘I.’ It’s an internal transition for s1. That’s why this internal transition will be executed. 

When the state is s11, when ‘I’ is sent, s1-I is printed. But, there is no transition. That’s why the state has not changed. The state is still s11 only. s11 is the current state. The state variable will hold the address of s11. The state has not changed. The event has propagated to the next level. And if there is any action defined, then it was executed. For s1, it was just an internal transition. That’s why s1-I is printed. 

Please note that there is no entry into the s11. Why? Because the state variable has not changed its value. The state variable is still holding the address of s11. Now, the state machine is in the s11 sub-state. 

 

Let’s go to s211 and see how ‘I’ behaves here. As per the state machine, I can send the event ‘G’ to go from s11 to s211. That’s why I will send G here. Event G actions are shown in Figure 15. We will analyze G later. How do ‘I’ respond here?

Testing
Figure 15. The output of event event ‘G’

 

First of all, the state is in s211, ‘I’ is not handled by s211, so it propagated to the next level→ s21. ‘I’ is also not handled in s21, so it is propagated to the next level→  s2. ‘I’ is an internal transition for s2. But the action is not defined. If the action is defined, you will put  ‘/.’  ‘/’ is not there, so action is not defined here. But, it has got a guard. 

It verifies the value of the foo variable. Initially, the foo variable is 0. So, not of 0 is 1. That means the Guard condition turns out to be true. If it is true, then the foo variable will have the value 1 and displays s2-I. That’s why s2-I will be printed, and there is no change in the state. The state variable still contains the address of s211. So, just s2-I is printed here.

 

Let’s see; I will send ‘I,’ s2-I is printed, as shown in Figure 16.

Testing
Figure 16. The output of event I actions when the state machine is in s211

 

Now, what happens if you send the ‘I’ again?

Again, s211 is not handled, so propagated to the next level. s21 is not handled, propagated to the next level, ‘I.’ The foo variable value is 1 because it was set to 1 previously. Not of 1 is 0; the Guard condition turns out to be false. If it is false, then BSP_display(s2-I) actions are not executed. So, it doesn’t print anything. 

That’s why s2 couldn’t handle ‘I’ in this case. Because the Guard evaluates to false, that’s why ‘I’ is propagated to the next level, ‘s.’ 

Again, the Guard condition is checked here when it comes ‘s’. The foo value is 1; Guard evaluates to true. If Guard evaluates to true, that means, ‘s’ handles it. So, ‘s-I’ is printed. That’s why you see ‘s-I’ when you send the ‘I’ a second time.

The first time you sent the ‘I,’ it printed s2-I. Because s2 handled it. When you send the ‘I’ next time, ‘I’ couldn’t handle it because the Guard has failed. That’s why it propagated to the next level, and ‘s’ handles it. That’s why you see s-I. 

And now, if you send ‘I’ again, the ‘s’  actually makes the foo variable 0 again. When it is 0 again, s2-I handles, like that. Alternatively, you see s2-I and s-I here. I hope that is clear. 

If you are not understanding, no problem. We will draw the Guard conditions and other things and understand how to define the Guard for a transition using this tool. It is a little different because this is a choice node. For the Guard, you have to use the choice node. But, we will learn that later. 

 

Now, let’s understand the event ‘C.’ We are in s211 now. In the s211, and the event C is sent, s211 doesn’t handle C, so it is propagated to the next level. s21 doesn’t handle it, so it is propagated to the next level. s2 handles it.  The action related to the transition is executed first. That’s why you see s2-C. And this is an external transition, so all the EXIT actions have to be executed right from the innermost state. All these are executed. There are three exits. s211-EXIT, s21-EXIT, s2-EXIT.

And then, s1 takes a transition here. So, s1-ENTRY. 

And the next state is guided by the initial pseudo-state. Its action is executed next, s1-INIT. 

And s11-ENTRY  is shown in Figure 17. 

 

We are now in s11. What happens if the state machine receives the event C here? So, it is not handled by the s11 state, so it propagates to the next state, s1. s1 handles it. s1-C is first,s11-EXIT is second, s1-EXIT is third. Two EXIT here. 

And after that, ENTRY action of s2, s2-ENTRY, then s2_INIT, s21-ENTRY, and s211-ENTRY. We are in s211 state.

Testing
Figure 17. Event C actions when the state machine is in s211

 

What happens if you send the event G? 

First of all, s21 doesn’t handle G, so it is propagated to the next level, s21. G is handled by s21. 

So, first s21-G; and followed by the  EXIT action, s211-EXIT; s21-EXIT; After that, this transition is going to leave this s2 also. That’s why, the EXIT action of s2, s2-EXIT. It comes to s1. 

The first ENTRY action, s1-ENTRY; When it is here, it is guided by this initial transition s1-INIT, and then S11-ENTRY. 

In the upcoming article, let’s discuss the history state.

 

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.