FSM Lecture 89| Exercise-008:Implementation part 8

 

Exercise-008:Implementation part 8


In the previous article, we implemented the alarm state machine as well as the button machine. It is not yet over, so we have to take care of our clock alarm state machine.

You see this error state in the clock alarm state machine (Figure 1). There are some missing links. So, we have to draw that.

Implementation part 8
Figure 1. Error state

 

And also, in the Alarm_Notify state, I have not implemented these links between these substates. We will do that now. 

Implementation part 8
Figure 2. Alarm_Notify state

 

When we are in an error state, we flash an error message for every 500 milliseconds. How do we implement that? We implemented that using variables. So, we used one timeout variable, and we incremented that timeout variable whenever the tick signal was received and then compared it with some timeout value like that. 

Now, you can get rid of all those things. You can use the timeout function provided by the framework. 

When we enter the setting_error state, let’s arm for a periodic timeout, as an entry action of this state. Let’s go to the entry action and arm a timeout. 

 

QActive_armX() function, as shown in Figure 3.

Implementation part 8
Figure 3. QActive_armX()

 

Let’s use QActive_armX(). Here Active object is AO_ClockAlarm. After that, the Tick rate is 0. The number of ticks is 500 ticks or 500 milliseconds. So, you can use MS_TO_TICKS here. In this case, 500 ticks are the same as 500 ms, because our frequency is 1000Hz. And after that, the periodicity you have to mention ‘interval’, that is also 500 milliseconds. setting_error states entry action code is shown in Figure 4.

Implementation part 8
Figure 4. setting _error states entry action

 

Whenever this setting_error state is exited, you have to disarm that. QActive_disarmX() function is shown in Figure 5.

Implementation part 8
Figure 5. QActive_disarmX() function

 

Put QActive_disarmX() as an exit action. You have to mention the Pointer to the AO and the tick rate 0. 

Implementation part 8
Figure 6. setting_error states exit action

 

Whenever there is a timeout, the state machine receives Q_TIME. That’s why we will transit like this. The signal name is Q_TIMEOUT. This is shown in Figure 7.

Q_TIMEOUT signal
Figure 7. Q_TIMEOUT signal

 

Whenever a tick happens here, then you have to inform the alarm class about the current time. The tick transition code is shown in Figure 8.

TICK transition code
Figure 8. TICK transition code

 

Now, go to the Alarm_notify state. Here, I have used one timeout variable. I’ll tell you why that is required. In the entry action of this alarm notify, you have to arm the timer. Let’s take the same code of setting_error state entry and exit actions. Let’s put in the entry action of this one.

Alarm_notify states entry action code
Figure 9. Alarm_notify states entry action code

 

In the exit action, the disarm function.

Alarm_notify states exit action code
Figure 10. Alarm_notify states exit action code

 

And let’s draw one transition, and I’ll use one choice node here. The signal name is Q_TIMEOUT.

alarm state machine
Figure 11. Alarm_Notify state

Whenever Q_TIMEOUT happens, what I do is I decrement a timeout variable  -me->timeout; And, in the guard condition of this choice segment, I’ll put one guard condition, that is me->timeout.

Whenever a timeout signal is received, the timeout variable is decremented by one, and then it will be compared. If it is non-zero, that will transition to this alarm_msg_off state. And, whenever the state machine is in this state, this trigger name is again Q_Timeout.

After some time, if no one presses this OK button, then after 20 seconds, this timeout variable will be 0. So, this guard fails. When this fails, this Q_Timeout signal will propagate to the superstate, and we will transition from the Alarm_notify state to the Settings state.

Figure 12. Q_TIMEOUT transition - alarm state machine
Figure 12. Q_TIMEOUT transition

 

The initial state is the Ticking state. It enters into a ticking state. Let me create that variable timeout in the clock alarm. I think that variable is not there. Let me create it. 

Right-click on Clock_Alarm, select Add attribute. Name it as timeout; type is uint8_t; visibility is private, as shown in Figure 13. 

alarm state machine
Figure 13. Adding a timeout attribute

 

Let’s generate the code. The code has generated successfully. And, let’s go back to the IDE. Let’s try to compile this. There are already some errors. So, let’s see. 

First of all, let’s start from the alarm.cpp. Go here Alarm_ctor, and it says some problems here. 

void Alarm_ctor(Alarm *const me) {
    QHsm_ctor(me,Q_STATE_CAST(&Alarm_initial));
}

Let’s copy this ${AOs::Alarm_ctor). Let’s go to the model and paste the link. It takes you to that code. 

The code is actually &me->super.

alarm state machine
Figure 14. Alarm_ctor

 

Now, let’s go to the next one. Identifier this module is undefined. Go to the model and go to alarm.cpp, here define this macro→ Q_DEFINE_THIS_FILE.(shown in Figure 15) 

 alarm state machine
Figure 15. alarm.cpp file

 

There are a couple of errors in the ClockAlarm_SM.cpp. These macros are not available here.

static QState Clock_Alarm_Alarm_Notify(Clock_Alarm * const me) {
      QState status_;
      switch (Q_SIG(me)) {
           /*.${AOs::Clock_Alarm::SM::Alarm_Notify} */
            case Q_ENTRY_SIG: {
                   me->timeout = 20;
                   QActive_armX(AO_ClockAlarm,0,MS_TO_TICKS(500),MS_TO_TICKS(500));
                   status_ = Q_HANDLED();
                   break;
            }

 

Go to the ClockAlarm_SM.cpp and include the main.h(shown in Figure 16).

 Include the main.h - alarm state machine
Figure 16. Include the main.h

 

After that, there is one more error. We used the Alarm_get_alarm_time method, but we didn’t give that method. We will do that.

Let’s go back to the model, Go to the Alarm, add one more operation called get_alarm_time. The return type is uint32_t, which is a public function. And the code is return me->alarm_time.

Implementation part 8- alarm state machine
Figure 17. Adding get_alatm_time operation

 

In the main.cpp give the definition of that, as shown in figure 18.

main.cpp file - alarm state machine
Figure 18. main.cpp file

 

When you start the QF_run here, QF_run runs, and it calls a hook function called startup. It is a startup call back to the application. We will implement this function in our main.cpp.

Let’s go to the main.cpp, let’s implement.  QF_onStartup. And from here, we will call that function sys_tick_init().

Implementation part 8 alarm state machine
Figure 19. QF_onStartup function

 

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.