<?xml version="1.0" encoding="UTF-8"?>
<!-- generator="FeedCreator 1.8" -->
<?xml-stylesheet href="https://sinelabore.com/lib/exe/css.php?s=feed" type="text/css"?>
<rss version="2.0">
    <channel xmlns:g="http://base.google.com/ns/1.0">
        <title>SinelaboreRT - wiki:toolbox</title>
        <description>Productivity for embedded software development</description>
        <link>https://sinelabore.com/</link>
        <lastBuildDate>Wed, 08 Apr 2026 00:02:32 +0000</lastBuildDate>
        <generator>FeedCreator 1.8</generator>
        <image>
            <url>https://sinelabore.com/lib/exe/fetch.php/favicon.ico</url>
            <title>SinelaboreRT</title>
            <link>https://sinelabore.com/</link>
        </image>
        <item>
            <title>What is Bela?</title>
            <link>https://sinelabore.com/doku.php/wiki/toolbox/bela</link>
            <description>
&lt;h1 class=&quot;sectionedit1&quot; id=&quot;what_is_bela&quot;&gt;What is Bela?&lt;/h1&gt;
&lt;div class=&quot;level1&quot;&gt;

&lt;p&gt;
&lt;a href=&quot;https://learn.bela.io/using-bela/about-bela/what-is-bela/&quot; class=&quot;urlextern&quot; title=&quot;https://learn.bela.io/using-bela/about-bela/what-is-bela/&quot; rel=&quot;ugc nofollow&quot;&gt;Bela&lt;/a&gt; is an open-source embedded computing platform for creating responsive, real-time interactive systems with audio and sensors. It features ultra-low latency, high-resolution seneor sampling, a convenient and powerful browser-based IDE, and a fully open-source toolchain that includes support for both low-level languages like C/C++.
&lt;/p&gt;

&lt;p&gt;
&lt;a href=&quot;https://sinelabore.com/lib/exe/detail.php/wiki/toolbox/bela_mini.png?id=wiki%3Atoolbox%3Abela&quot; class=&quot;media&quot; title=&quot;wiki:toolbox:bela_mini.png&quot;&gt;&lt;img src=&quot;https://sinelabore.com/lib/exe/fetch.php/wiki/toolbox/bela_mini.png?w=300&amp;amp;tok=6f2378&quot; class=&quot;media&quot; loading=&quot;lazy&quot; alt=&quot;&quot; width=&quot;300&quot; /&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;
There is ready made hardware based on the Beagle single-board computers. The Bela software extends the functionality of the Beagle systems by integrating audio processing and sensor connectivity in a single, high-performamce package.
&lt;/p&gt;

&lt;p&gt;
Bela comes with excellent online &lt;a href=&quot;https://learn.bela.io/tutorials/&quot; class=&quot;urlextern&quot; title=&quot;https://learn.bela.io/tutorials/&quot; rel=&quot;ugc nofollow&quot;&gt;tutorials&lt;/a&gt; explaining how to use and program the system. Tutorial 13 introduces the concept of the finite state machine modelling a metronome and debouncing buttons.
&lt;/p&gt;

&lt;p&gt;
It it really worth watching the tutorial video and doing the exercises.
&lt;/p&gt;
&lt;iframe src=&quot;//www.youtube-nocookie.com/embed/x1mlHEUwl_8?&quot; width=&quot;425&quot; height=&quot;239&quot; style=&quot;width:425px;height:239px;&quot; class=&quot;vshare vshare__none&quot; allowfullscreen=&quot;&quot; frameborder=&quot;0&quot; scrolling=&quot;no&quot; data-domain=&quot;www.youtube-nocookie.com&quot; loading=&quot;lazy&quot;&gt;&lt;h3&gt;&lt;/h3&gt;&lt;/iframe&gt;
&lt;p&gt;
Have fun with BELA!
&lt;/p&gt;

&lt;/div&gt;
</description>
            <author>anonymous@undisclosed.example.com (Anonymous)</author>
            <pubDate>Mon, 17 Apr 2023 16:43:22 +0000</pubDate>
        </item>
        <item>
            <title>Event-based vs polling</title>
            <link>https://sinelabore.com/doku.php/wiki/toolbox/event-based_versus_polling</link>
            <description>
&lt;h1 class=&quot;sectionedit1&quot; id=&quot;event-based_vs_polling&quot;&gt;Event-based vs polling&lt;/h1&gt;
&lt;div class=&quot;level1&quot;&gt;

&lt;p&gt;
When designing an embedded system an important design decision is how the system should work: event-based or polling based.
&lt;/p&gt;

&lt;p&gt;
The type of the connected hardware can provide a first hint. Communication interfaces and many other hardware interfaces are nowadays mostly realized event based (e.g. a CAN network interface). If binary input/output channels are the dominating interface polling can be the better choice. In case of doubts better choose the event-based design.
In both system types state-machines are the right tool to model state based behavior. In event-based systems also the state-machines should be modeled state-based. I.e. the machine waits for new events, possibly changes state, perform actions as a reaction to an event and then waits for the next event. If there is no event the state machine needs not to run. In polling-based systems the state machine is executed cyclically independent if it is necessary or not. The cycle time must be chosen in a way that no relevant signal change is missed.
In the following section a simple example is presented first in an event-based and then as polling-based design. The task of the machine is similar to an AND function. If one input appears the other must appear within a certain time, otherwise a fault state is entered.
&lt;/p&gt;

&lt;/div&gt;

&lt;h4 id=&quot;event-based_model&quot;&gt;Event-based model&lt;/h4&gt;
&lt;div class=&quot;level4&quot;&gt;

&lt;p&gt;
&lt;img src=&quot;https://sinelabore.com/lib/exe/fetch.php/wiki/articles/event_vs_polling_event_sm.png&quot; class=&quot;mediacenter&quot; loading=&quot;lazy&quot; alt=&quot;&quot; /&gt;
&lt;/p&gt;

&lt;p&gt;
In this model transitions are triggered by events that are sent form outside to the machine. E.g. from an interrupt service routine detecting a change of the digital inputs. The do not loose events often a queue is used. Whenever the state machine runs it looks for new events in the queue, processes them and does not consume any CPU time if there are no events. If a &lt;abbr title=&quot;Real-Time Operating System&quot;&gt;RTOS&lt;/abbr&gt; is used the state-machine often runs in its own thread and blocks the thread execution until a new event arrives.
&lt;/p&gt;

&lt;p&gt;
Generated source code looks like this (reduced to fit in here):
&lt;/p&gt;
&lt;pre class=&quot;code c&quot;&gt;&lt;span class=&quot;coMULTI&quot;&gt;/*Events which can be sent to the state-machine  */&lt;/span&gt;
&lt;span class=&quot;kw4&quot;&gt;typedef&lt;/span&gt; &lt;span class=&quot;kw2&quot;&gt;enum&lt;/span&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
evAB&lt;span class=&quot;sy0&quot;&gt;=&lt;/span&gt;0U&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt;
evB&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt;
evA&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt;
evNoInput&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt;
evEnable&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt;
evTimeout&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt;
evDisable&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt;
_NO_MSG
&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt; A_EVENT_T&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&amp;nbsp;
&lt;span class=&quot;kw4&quot;&gt;void&lt;/span&gt;  event_example&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;A_EVENT_T msg&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
  &lt;span class=&quot;kw1&quot;&gt;switch&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;stateVar&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
    &lt;span class=&quot;kw1&quot;&gt;case&lt;/span&gt; Idle&lt;span class=&quot;sy0&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;kw1&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;msg&lt;span class=&quot;sy0&quot;&gt;==&lt;/span&gt;evEnable&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
        setReady&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;nu0&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
        stateVar &lt;span class=&quot;sy0&quot;&gt;=&lt;/span&gt; Init&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;&lt;span class=&quot;kw1&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
        &lt;span class=&quot;coMULTI&quot;&gt;/* Intentionally left blank */&lt;/span&gt;
     &lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt; 
   &lt;span class=&quot;kw2&quot;&gt;break&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&amp;nbsp;
   &lt;span class=&quot;kw1&quot;&gt;case&lt;/span&gt; Init&lt;span class=&quot;sy0&quot;&gt;:&lt;/span&gt;
     &lt;span class=&quot;kw1&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;msg&lt;span class=&quot;sy0&quot;&gt;==&lt;/span&gt;evA&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
       startTimer&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
       stateVar &lt;span class=&quot;sy0&quot;&gt;=&lt;/span&gt; WaitB&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
     &lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;&lt;span class=&quot;kw1&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;msg&lt;span class=&quot;sy0&quot;&gt;==&lt;/span&gt;evAB&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
       setOut&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;nu0&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
       timerStop&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
       stateVar &lt;span class=&quot;sy0&quot;&gt;=&lt;/span&gt; AandB&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
     &lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;
    ...
   &lt;span class=&quot;kw2&quot;&gt;break&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&amp;nbsp;
   &lt;span class=&quot;kw1&quot;&gt;case&lt;/span&gt; WaitA&lt;span class=&quot;sy0&quot;&gt;:&lt;/span&gt;
     &lt;span class=&quot;kw1&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;msg&lt;span class=&quot;sy0&quot;&gt;==&lt;/span&gt;evNoInput&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
       setReady&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;nu0&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
       stateVar &lt;span class=&quot;sy0&quot;&gt;=&lt;/span&gt; Init&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
     &lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;&lt;span class=&quot;kw1&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;msg&lt;span class=&quot;sy0&quot;&gt;==&lt;/span&gt;evTimeout&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
       stateVar &lt;span class=&quot;sy0&quot;&gt;=&lt;/span&gt; Error&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
     &lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;
   ...
&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Event-based vs polling&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;event-based_vs_polling&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:0,&amp;quot;secid&amp;quot;:1,&amp;quot;range&amp;quot;:&amp;quot;1-2703&amp;quot;} --&gt;
&lt;h3 class=&quot;sectionedit2&quot; id=&quot;polling-based_model&quot;&gt;Polling-based model&lt;/h3&gt;
&lt;div class=&quot;level3&quot;&gt;

&lt;p&gt;
In this model transitions are triggered by boolean conditions. The state machine has to run cyclically. This type of state machine is often found in systems based on a big main loop. The cycle time of the main loop must be fast enough to ensure that no condition changes are lost e.g. input inA going from low to hight and low again.
&lt;/p&gt;

&lt;p&gt;
Generated source code looks like this (reduced to fit in here):
&lt;/p&gt;
&lt;pre class=&quot;code c&quot;&gt;&lt;span class=&quot;kw4&quot;&gt;void&lt;/span&gt;  polling_example&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;kw4&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
&amp;nbsp;
  &lt;span class=&quot;coMULTI&quot;&gt;/* action code */&lt;/span&gt;
  inA &lt;span class=&quot;sy0&quot;&gt;=&lt;/span&gt; getA&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
  inB &lt;span class=&quot;sy0&quot;&gt;=&lt;/span&gt; getB&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
  enable &lt;span class=&quot;sy0&quot;&gt;=&lt;/span&gt; getEnable&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&amp;nbsp;
  &lt;span class=&quot;kw1&quot;&gt;switch&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;stateVar&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
    &lt;span class=&quot;kw1&quot;&gt;case&lt;/span&gt; Idle&lt;span class=&quot;sy0&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;kw1&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;enable&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
        setReady&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;nu0&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
        stateVar &lt;span class=&quot;sy0&quot;&gt;=&lt;/span&gt; Init&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;&lt;span class=&quot;kw1&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
         &lt;span class=&quot;coMULTI&quot;&gt;/* Intentionally left blank */&lt;/span&gt;
      &lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt; 
    &lt;span class=&quot;kw2&quot;&gt;break&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&amp;nbsp;
  &lt;span class=&quot;kw1&quot;&gt;case&lt;/span&gt; Init&lt;span class=&quot;sy0&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;kw1&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;inA &lt;span class=&quot;sy0&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;!&lt;/span&gt;inB&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
      timerStart&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
      stateVar &lt;span class=&quot;sy0&quot;&gt;=&lt;/span&gt; WaitB&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;   
     &lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;&lt;span class=&quot;kw1&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;kw1&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;inA &lt;span class=&quot;sy0&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; inB&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
       setOut&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;nu0&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
       timerStop&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
       stateVar &lt;span class=&quot;sy0&quot;&gt;=&lt;/span&gt; AandB&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
     &lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;
   ...
  &lt;span class=&quot;kw2&quot;&gt;break&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&amp;nbsp;
  &lt;span class=&quot;kw1&quot;&gt;case&lt;/span&gt; WaitA&lt;span class=&quot;sy0&quot;&gt;:&lt;/span&gt;
   &lt;span class=&quot;coMULTI&quot;&gt;/* action code  */&lt;/span&gt;
   timout &lt;span class=&quot;sy0&quot;&gt;=&lt;/span&gt; isTimeout&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt; 
&amp;nbsp;
   &lt;span class=&quot;kw1&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;!&lt;/span&gt;inB&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
     setReady&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;nu0&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
     stateVar &lt;span class=&quot;sy0&quot;&gt;=&lt;/span&gt; Init&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
   &lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;&lt;span class=&quot;kw1&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;timeout&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
     stateVar &lt;span class=&quot;sy0&quot;&gt;=&lt;/span&gt; Error&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
   &lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;
...
&amp;nbsp;
&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;
The Sinelabore&lt;em&gt;RT&lt;/em&gt; code generator can generate both machine types for you. As you can see the overall structure looks very similar but the two run-time models - event-based vs. polling are very different. 
&lt;/p&gt;

&lt;p&gt;
&lt;em&gt;Be aware of the different run-time models during architecture design and make a conscious decision! &lt;strong&gt;In case of doubts better choose the event-based model.&lt;/strong&gt;&lt;/em&gt;
&lt;/p&gt;

&lt;p&gt;
If you have any feedback or suggestions for improvement please send me an email.
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Polling-based model&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;polling-based_model&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:1,&amp;quot;secid&amp;quot;:2,&amp;quot;range&amp;quot;:&amp;quot;2704-&amp;quot;} --&gt;</description>
            <author>anonymous@undisclosed.example.com (Anonymous)</author>
            <pubDate>Sun, 21 Oct 2012 10:31:48 +0000</pubDate>
        </item>
        <item>
            <title>Features for High-Availability and Safety Systems</title>
            <link>https://sinelabore.com/doku.php/wiki/toolbox/features_for_high-availability_and_safety_systems</link>
            <description>
&lt;h1 class=&quot;sectionedit1&quot; id=&quot;features_for_high-availability_and_safety_systems&quot;&gt;Features for High-Availability and Safety Systems&lt;/h1&gt;
&lt;div class=&quot;level1&quot;&gt;

&lt;p&gt;
For high availability applications it is desirable to detect serious errors happening outside the state machine code but effecting the correct execution of the state machine. Such errors might come from a runaway pointer overwriting key variables, power brownout corrupting a bit or a bad ram cell losing a bit to name a few. To detect and handle such situations is an overall system design task. But the code generator can help you to detect inconsistencies of the state machine offering the following two mechanisms:
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Features for High-Availability and Safety Systems&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;features_for_high-availability_and_safety_systems&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:0,&amp;quot;secid&amp;quot;:1,&amp;quot;range&amp;quot;:&amp;quot;1-585&amp;quot;} --&gt;
&lt;h2 class=&quot;sectionedit2&quot; id=&quot;undefined_state_error_handler&quot;&gt;Undefined State Error Handler&lt;/h2&gt;
&lt;div class=&quot;level2&quot;&gt;

&lt;p&gt;
You can provide error handler code that is executed in the default path of the switch/case statements. This helps to detect undefined values of the state variables. See configuration key &lt;code&gt;UnknownStateHandler&lt;/code&gt;.
Example:
&lt;/p&gt;
&lt;pre class=&quot;code c&quot;&gt;&lt;span class=&quot;kw1&quot;&gt;switch&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;instanceVar−&lt;span class=&quot;sy0&quot;&gt;&amp;gt;&lt;/span&gt;stateVar&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt; 
  &lt;span class=&quot;kw1&quot;&gt;case&lt;/span&gt; S1&lt;span class=&quot;sy0&quot;&gt;:&lt;/span&gt;
    ...
  &lt;span class=&quot;kw1&quot;&gt;case&lt;/span&gt; S2&lt;span class=&quot;sy0&quot;&gt;:&lt;/span&gt;
    ...
  &lt;span class=&quot;kw1&quot;&gt;default&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;:&lt;/span&gt;
    error_handler&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;co1&quot;&gt;// your error handler&lt;/span&gt;
    &lt;span class=&quot;kw2&quot;&gt;break&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt; 
&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Undefined State Error Handler&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;undefined_state_error_handler&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:0,&amp;quot;secid&amp;quot;:2,&amp;quot;range&amp;quot;:&amp;quot;586-1011&amp;quot;} --&gt;
&lt;h2 class=&quot;sectionedit3&quot; id=&quot;validate_state_transitions&quot;&gt;Validate State Transitions&lt;/h2&gt;
&lt;div class=&quot;level2&quot;&gt;

&lt;p&gt;
The code generator optionally generates a validate function that checks if a transition from a present state to a new target state is allowed (i.e. modeled in the state diagram). To enable the generation of the validate function set parameter &lt;code&gt;ValidationCall=yes&lt;/code&gt; in the configuration file. This validate function has to be called from a user provided handler that is automatically called from the generated state machine code. This indirection allows you to define the reaction in the case a transition is not allowed. The validation code is automatically generated for you. In a single CPU setup the validation function runs on the same controller that executes the state machine code. But it is also possible to execute the validate function on a second CPU in a redundant CPU setup.
&lt;/p&gt;

&lt;p&gt;
Example state machine:
&lt;/p&gt;
&lt;pre class=&quot;code c&quot;&gt;&lt;span class=&quot;kw1&quot;&gt;case&lt;/span&gt; S22&lt;span class=&quot;sy0&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;kw1&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;msg&lt;span class=&quot;sy0&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;TESTCASE EVENT T&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;ev32&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
     &lt;span class=&quot;sy0&quot;&gt;/&lt;/span&gt;∗ Transition from S22 to S21 ∗&lt;span class=&quot;sy0&quot;&gt;/&lt;/span&gt; 
     testcaseValidationHandler&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;S22&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; S21&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; instanceVar−&lt;span class=&quot;sy0&quot;&gt;&amp;gt;&lt;/span&gt;inst id&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt; 
     evConsumed&lt;span class=&quot;sy0&quot;&gt;=&lt;/span&gt;1U&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
     &lt;span class=&quot;sy0&quot;&gt;/&lt;/span&gt;∗ OnExit code of state S22 ∗&lt;span class=&quot;sy0&quot;&gt;/&lt;/span&gt;
     ...&lt;/pre&gt;

&lt;p&gt;
Example for an user defined handler:
&lt;/p&gt;
&lt;pre class=&quot;code c&quot;&gt;&lt;span class=&quot;co1&quot;&gt;// your own handler begins here&lt;/span&gt;
&lt;span class=&quot;kw4&quot;&gt;void&lt;/span&gt; testcaseValidationHandler&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;kw4&quot;&gt;uint16_t&lt;/span&gt; from&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kw4&quot;&gt;uint16&lt;/span&gt; t to&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kw4&quot;&gt;uint8_t&lt;/span&gt; machineId&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
  &lt;span class=&quot;kw4&quot;&gt;uint8_t&lt;/span&gt; testcaseValidate&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;from&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; to&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;co1&quot;&gt;// checks if this transitions is allowed&lt;/span&gt;
  &lt;span class=&quot;kw1&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;retCode&lt;span class=&quot;sy0&quot;&gt;!=&lt;/span&gt;0U&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
    &lt;span class=&quot;co1&quot;&gt;// transition not allowed&lt;/span&gt;
    reboot&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;co1&quot;&gt;// or whatever is best in your system&lt;/span&gt;
  &lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;&lt;span class=&quot;kw1&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
    &lt;a href=&quot;http://www.opengroup.org/onlinepubs/009695399/functions/printf.html&quot;&gt;&lt;span class=&quot;kw3&quot;&gt;printf&lt;/span&gt;&lt;/a&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;&amp;quot;Transition␣allowed&lt;span class=&quot;es1&quot;&gt;\n&lt;/span&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;kw1&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;
Generated validation code for some example machine:
&lt;/p&gt;
&lt;pre class=&quot;code c&quot;&gt;&lt;span class=&quot;co2&quot;&gt;#define SIZE_TRANSITION_TABLE (31U)&lt;/span&gt;
&lt;span class=&quot;co2&quot;&gt;#define TRANSITION(from,to)  (uint16_t)((from * 127) + to)&lt;/span&gt;
&amp;nbsp;
&lt;span class=&quot;coMULTI&quot;&gt;/* Hash table of valid transitions */&lt;/span&gt;
&lt;span class=&quot;kw4&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kw4&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;kw4&quot;&gt;uint16_t&lt;/span&gt; valid_transitions&lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
  16249U &lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;coMULTI&quot;&gt;/* S1-&amp;gt;S3 */&lt;/span&gt;
  10880U &lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;coMULTI&quot;&gt;/* S111-&amp;gt;S111 */&lt;/span&gt;
  9728U &lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;coMULTI&quot;&gt;/* S11-&amp;gt;S11 */&lt;/span&gt;
  10489U &lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;coMULTI&quot;&gt;/* S132-&amp;gt;S131 */&lt;/span&gt;
  15360U &lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;coMULTI&quot;&gt;/* S3-&amp;gt;S3 */&lt;/span&gt;
  9754U &lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;coMULTI&quot;&gt;/* S11-&amp;gt;S12 */&lt;/span&gt;
  13030U &lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;coMULTI&quot;&gt;/* S12-&amp;gt;S11 */&lt;/span&gt;
  13056U &lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;coMULTI&quot;&gt;/* S12-&amp;gt;S12 */&lt;/span&gt;
  6680U &lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;coMULTI&quot;&gt;/* S13-&amp;gt;S11 */&lt;/span&gt;
  9704U &lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;coMULTI&quot;&gt;/* S11-&amp;gt;S13 */&lt;/span&gt;
  16181U &lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;coMULTI&quot;&gt;/* S1-&amp;gt;S13 */&lt;/span&gt;
  10892U &lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;coMULTI&quot;&gt;/* S111-&amp;gt;S112 */&lt;/span&gt;
  15292U &lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;coMULTI&quot;&gt;/* S3-&amp;gt;S13 */&lt;/span&gt;
  12404U &lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;coMULTI&quot;&gt;/* S112-&amp;gt;S111 */&lt;/span&gt;
  6724U &lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;coMULTI&quot;&gt;/* S13-&amp;gt;S3 */&lt;/span&gt;
  5745U &lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;coMULTI&quot;&gt;/* S22-&amp;gt;S21 */&lt;/span&gt;
  6731U &lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;coMULTI&quot;&gt;/* S13-&amp;gt;S1 */&lt;/span&gt;
  3855U &lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;coMULTI&quot;&gt;/* S21-&amp;gt;S22 */&lt;/span&gt;
  1009U &lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;coMULTI&quot;&gt;/* S4-&amp;gt;S3 */&lt;/span&gt;
  15247U &lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;coMULTI&quot;&gt;/* S3-&amp;gt;S4 */&lt;/span&gt;
  914U &lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;coMULTI&quot;&gt;/* S4-&amp;gt;FINAL0 */&lt;/span&gt;
  1016U &lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;coMULTI&quot;&gt;/* S4-&amp;gt;S1 */&lt;/span&gt;
  896U &lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;coMULTI&quot;&gt;/* S4-&amp;gt;S4 */&lt;/span&gt;
  5461U &lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;coMULTI&quot;&gt;/* S2-&amp;gt;S1 */&lt;/span&gt;
  16159U &lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;coMULTI&quot;&gt;/* S1-&amp;gt;S21 */&lt;/span&gt;
  9694U &lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;coMULTI&quot;&gt;/* S11-&amp;gt;S2 */&lt;/span&gt;
  9682U &lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;coMULTI&quot;&gt;/* S11-&amp;gt;S21 */&lt;/span&gt;
  9779U &lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;coMULTI&quot;&gt;/* S11-&amp;gt;S1 */&lt;/span&gt;
  16205U &lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;coMULTI&quot;&gt;/* S1-&amp;gt;S11 */&lt;/span&gt;
  16256U &lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;coMULTI&quot;&gt;/* S1-&amp;gt;S1 */&lt;/span&gt;
  16171U &lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;coMULTI&quot;&gt;/* S1-&amp;gt;S2 */&lt;/span&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&amp;nbsp;
&lt;span class=&quot;kw4&quot;&gt;uint8_t&lt;/span&gt; testcaseValidate&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;kw4&quot;&gt;uint16_t&lt;/span&gt; from&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kw4&quot;&gt;uint16_t&lt;/span&gt; to&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
&amp;nbsp;
  &lt;span class=&quot;kw4&quot;&gt;uint16_t&lt;/span&gt; hash &lt;span class=&quot;sy0&quot;&gt;=&lt;/span&gt; TRANSITION&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;from&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt;to&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;kw4&quot;&gt;uint16_t&lt;/span&gt; x&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&amp;nbsp;
  &lt;span class=&quot;kw1&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;x &lt;span class=&quot;sy0&quot;&gt;=&lt;/span&gt; 0U&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt; x &lt;span class=&quot;sy0&quot;&gt;&amp;lt;&lt;/span&gt; SIZE_TRANSITION_TABLE&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt; x &lt;span class=&quot;sy0&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;
  &lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
    &lt;span class=&quot;kw1&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;valid_transitions&lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;x&lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;==&lt;/span&gt; hash&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;
    &lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
      &lt;span class=&quot;kw1&quot;&gt;return&lt;/span&gt; 0U&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;
  &lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;
  &lt;span class=&quot;coMULTI&quot;&gt;/* return an error */&lt;/span&gt;
  &lt;span class=&quot;kw1&quot;&gt;return&lt;/span&gt; 1U&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;
The validate code uses some predefined types. Define them in a header that fits your system needs and include it by setting the parameter &lt;code&gt;AdditionalValidateIncludes&lt;/code&gt; in the configuration file.
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Validate State Transitions&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;validate_state_transitions&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:1,&amp;quot;secid&amp;quot;:3,&amp;quot;range&amp;quot;:&amp;quot;1012-4015&amp;quot;} --&gt;
&lt;h2 class=&quot;sectionedit4&quot; id=&quot;generate_stateevent_definitions_with_hamming_distance&quot;&gt;Generate State/Event Definitions with Hamming Distance&lt;/h2&gt;
&lt;div class=&quot;level2&quot;&gt;

&lt;p&gt;
It is possible to generate the states and events in an ascending order but using a user defined hamming distance between them. So in case one or more bits swap accidentally the state machine will end up in the default path which can then call an error handler. See parameters &lt;code&gt;UseHammingCodesForEvents&lt;/code&gt;, &lt;code&gt;UseHammingCodesForStates&lt;/code&gt; and &lt;code&gt;HammingDistance&lt;/code&gt;.
&lt;/p&gt;

&lt;p&gt;
Example:
&lt;/p&gt;

&lt;p&gt;
&lt;code&gt;UseHammingCodesForEvents=yes
UseHammingCodesForStates=yes
HammingDistance=3&lt;/code&gt;
&lt;/p&gt;
&lt;pre class=&quot;code c&quot;&gt;&lt;span class=&quot;coMULTI&quot;&gt;/*Events which can be sent to the state-machine  */&lt;/span&gt;
&lt;span class=&quot;kw4&quot;&gt;typedef&lt;/span&gt; &lt;span class=&quot;kw2&quot;&gt;enum&lt;/span&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
  evInnerS3&lt;span class=&quot;sy0&quot;&gt;=&lt;/span&gt;0U&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt;
  ev3434&lt;span class=&quot;sy0&quot;&gt;=&lt;/span&gt;7U&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt;
  ev111&lt;span class=&quot;sy0&quot;&gt;=&lt;/span&gt;25U&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt;
  evInnerS111&lt;span class=&quot;sy0&quot;&gt;=&lt;/span&gt;30U&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt;
  evBH&lt;span class=&quot;sy0&quot;&gt;=&lt;/span&gt;42U&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt;
  evBG&lt;span class=&quot;sy0&quot;&gt;=&lt;/span&gt;45U&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt;
  evBF&lt;span class=&quot;sy0&quot;&gt;=&lt;/span&gt;51U&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt;
  ...
  &lt;span class=&quot;me1&quot;&gt;TESTCASE_NO_MSG&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;=&lt;/span&gt; 461U
&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt; TESTCASE_EVENT_T&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;  &lt;/pre&gt;

&lt;p&gt;
In case of any questions and suggested send us a mail.
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Generate State\/Event Definitions with Hamming Distance&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;generate_stateevent_definitions_with_hamming_distance&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:4,&amp;quot;secid&amp;quot;:4,&amp;quot;range&amp;quot;:&amp;quot;4016-&amp;quot;} --&gt;</description>
            <author>anonymous@undisclosed.example.com (Anonymous)</author>
            <pubDate>Tue, 10 Nov 2020 21:12:45 +0000</pubDate>
        </item>
        <item>
            <title>Model-based testing of state machines</title>
            <link>https://sinelabore.com/doku.php/wiki/toolbox/model-based_testing_of_state_machines_i</link>
            <description>
&lt;h1 class=&quot;sectionedit1&quot; id=&quot;model-based_testing_of_state_machines&quot;&gt;Model-based testing of state machines&lt;/h1&gt;
&lt;div class=&quot;level1&quot;&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Model-based testing of state machines&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;model-based_testing_of_state_machines&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:0,&amp;quot;secid&amp;quot;:1,&amp;quot;range&amp;quot;:&amp;quot;1-53&amp;quot;} --&gt;
&lt;h3 class=&quot;sectionedit2&quot; id=&quot;this_article_explains_how_sinelaborert_helps_you_to_test_your_state_based_software&quot;&gt;This article explains how sinelaboreRT helps you to test your state based software.&lt;/h3&gt;
&lt;div class=&quot;level3&quot;&gt;

&lt;p&gt;
In 2000 Martin Gomez wrote on embedded.com: “&lt;em&gt;The beauty of coding even simple algorithms as state machines is that the test plan almost writes itself. All you have to do is to go through every state transition. I usually do it with a highlighter in hand, crossing off the arrows on the state transition diagram as they successfully pass their tests. This is a good reason to avoid “hidden states”-they&amp;#039;re more likely to escape testing than explicit states. Until you can use the “real” hardware to induce state changes, either do it with a source-level debugger, or build an “input poker” utility that lets you write the values of the inputs into your application.&lt;/em&gt;” In many teams this is still common practice.
&lt;/p&gt;

&lt;p&gt;
On a more general view state machine testing covers the following steps: (1) building a (test) model, (2) generating test cases (3) generating expected outputs, (4) running the tests, (5) comparing actual outputs with expected outputs, and (6) deciding on further actions (e.g. whether to modify the model, generate more tests, or stop testing).
&lt;/p&gt;

&lt;p&gt;
Model based testing usually means that the test cases and other required data (e.g. test stimuli or expected test results) are derived automatically from the state machine model. And often also the automated test execution and validation is associated with model based testing. Probably only few organizations have implemented a fully automated test system covering all these steps. Especially for smaller teams the required investment for tools etc. is out of budget.
&lt;/p&gt;

&lt;p&gt;
This article explains the features of sinelaboreRT that are relevant for (model based) testing. We use I) the Equivalent PCLopen function block and II) the microwave oven from the manual throughout this article. Both examples are available for download and allows you to follow all steps in. As we use the same model to generate code and testcases from step one is already done.
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;This article explains how sinelaboreRT helps you to test your state based software.&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;this_article_explains_how_sinelaborert_helps_you_to_test_your_state_based_software&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:0,&amp;quot;secid&amp;quot;:2,&amp;quot;range&amp;quot;:&amp;quot;54-2068&amp;quot;} --&gt;
&lt;h3 class=&quot;sectionedit3&quot; id=&quot;generating_test_cases&quot;&gt;Generating test cases&lt;/h3&gt;
&lt;div class=&quot;level3&quot;&gt;

&lt;p&gt;
Defining testcases is the 2nd important step that usually consumes a lot of time if it must be done manually. The code generator can save you a lot of time by auto-matically suggesting test routes through a given state
machine.
&lt;/p&gt;

&lt;p&gt;
The used algorithm ensures that all transitions are taken at least  once  (100% transition coverage that also means 100% state coverage). So it is not anymore necessary to go through the 
diagram with a highlighter in hand. The following figure 1 shows the coverage
information  from the equivalent machine.  The command line option &amp;#039;-c&amp;#039; switches on the coverage data generation. The following command generates code and test routes from a Magic Draw model.
&lt;/p&gt;
&lt;pre class=&quot;code bash&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;java&lt;/span&gt; &lt;span class=&quot;re5&quot;&gt;-jar&lt;/span&gt; codegen.jar &lt;span class=&quot;re5&quot;&gt;-v&lt;/span&gt; &lt;span class=&quot;re5&quot;&gt;-c&lt;/span&gt; &lt;span class=&quot;re5&quot;&gt;-p&lt;/span&gt; md &lt;span class=&quot;re5&quot;&gt;-o&lt;/span&gt; equivalent &lt;span class=&quot;re5&quot;&gt;-t&lt;/span&gt; &lt;span class=&quot;st0&quot;&gt;&amp;quot;Model:Equivalent&amp;quot;&lt;/span&gt; equivalent.xml&lt;/pre&gt;

&lt;p&gt;
The output looks the following:
&lt;/p&gt;

&lt;p&gt;
&lt;img src=&quot;https://sinelabore.com/lib/exe/fetch.php/wiki/articles/model_based_testing_testcases.png&quot; class=&quot;mediacenter&quot; loading=&quot;lazy&quot; title=&quot;Automatic generation of test cases for 100 percent transition coverage&quot; alt=&quot;Automatic generation of test cases for 100 percent transition coverage&quot; /&gt;
&lt;/p&gt;

&lt;p&gt;
Figure 1: Coverage output generated from the code generator for the ￼&lt;a href=&quot;https://sinelabore.com/doku.php/wiki/examples/plcopen_function_block&quot; class=&quot;wikilink1&quot; title=&quot;wiki:examples:plcopen_function_block&quot; data-wiki-id=&quot;wiki:examples:plcopen_function_block&quot;&gt;Safety Function Block&lt;/a&gt; state machine. The colored lines were added to better indicate the different routes.
&lt;/p&gt;

&lt;p&gt;
You can see that the first test route starts from the initial state in line 0 and ends at line 9 where no untaken transitions are left to go (take a look in the state diagram below and follow the red arrows). The output moves to the right at every new transition on the route. Sometimes not all outgoing transitions of a state can be tested. In this case a branch in the test route is necessary. Take «WaitChannelB» as an example. As you can see not all transitions starting from WaitChannelB could be tested in one route. Two further branches are necessary. They are shown in line 21 and 23 (follow the yellow line) in figure 1. Branches are indicated by the same indentation level. Other branches in our example are marked with the red, green and blue lines. 
&lt;/p&gt;

&lt;p&gt;
SinelaboreRT can also generate an Excel sheet with all the test routes. More about this feature follows below. 
&lt;/p&gt;

&lt;p&gt;
&lt;a href=&quot;https://sinelabore.com/lib/exe/detail.php/wiki/articles/model_based_testing_annotated_sm.png?id=wiki%3Atoolbox%3Amodel-based_testing_of_state_machines_i&quot; class=&quot;media&quot; title=&quot;wiki:articles:model_based_testing_annotated_sm.png&quot;&gt;&lt;img src=&quot;https://sinelabore.com/lib/exe/fetch.php/wiki/articles/model_based_testing_annotated_sm.png&quot; class=&quot;mediaright&quot; align=&quot;right&quot; loading=&quot;lazy&quot; title=&quot;State machine with test path &quot; alt=&quot;State machine with test path &quot; /&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;
Figure 2: State machine with test path from step 0 to 8 as suggested from the coverage algorithm shown in figure 1.
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Generating test cases&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;generating_test_cases&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:0,&amp;quot;secid&amp;quot;:3,&amp;quot;range&amp;quot;:&amp;quot;2069-4369&amp;quot;} --&gt;
&lt;h3 class=&quot;sectionedit4&quot; id=&quot;expected_outputs&quot;&gt;Expected outputs&lt;/h3&gt;
&lt;div class=&quot;level3&quot;&gt;

&lt;p&gt;
To assess the test results the expected behavior must be defined. SinelaboreRT can not determine output values from the transitions or guards. It is your responsibility to define the output variables of the state machine (either hardware or software). But if you embed the expected output values in the state machine the code generator can extract it for you automatically. 
&lt;/p&gt;

&lt;p&gt;
To be able to extract the outputs you have to define it as so called state constraints. The &lt;abbr title=&quot;Unified Modeling Language&quot;&gt;UML&lt;/abbr&gt; does not directly support this so you have to define a comment and attach it to a state. In the comment use the ‘Constraints:’ key-word to start the constraints section. The format of the specification is up to you. An example for the ‘SafetyOutputState’ is shown in the following figure 3. In this case it is stated that the error output must be zero whereas the normal output must be one.
&lt;/p&gt;

&lt;p&gt;
&lt;img src=&quot;https://sinelabore.com/lib/exe/fetch.php/wiki/articles/model_based_testing_constraint.png&quot; class=&quot;mediacenter&quot; loading=&quot;lazy&quot; title=&quot;Use a comment to specify a constraint per state&quot; alt=&quot;Use a comment to specify a constraint per state&quot; /&gt;
&lt;/p&gt;

&lt;p&gt;
Figure 3: Use a comment to specify a constraint per state.
&lt;/p&gt;

&lt;p&gt;
Beside the console output from above - which provides a quick overview about the test effort - an Excel file can be created. It contains one route per sheet. Each line in a sheet is a single test step on the test route starting from the init state. There are as many sheets as routes are necessary to achieve the 100% transition coverage. A sheet lists the present state and the trigger to reach the next state. In addition the constraints of the source and the target states are listed. The constraint information is taken from the state diagram if specified (see figure 3 above). The following figure 4 shows the sheet for the state diagram from figure 2.
&lt;/p&gt;

&lt;p&gt;
&lt;img src=&quot;https://sinelabore.com/lib/exe/fetch.php/wiki/articles/model_based_testing_excel.png&quot; class=&quot;mediacenter&quot; loading=&quot;lazy&quot; title=&quot; Image that shows the test case in an Excel file&quot; alt=&quot; Image that shows the test case in an Excel file&quot; /&gt;
Figure 4: Excel sheets with the test routes for the equivalent state machine.  Each line contains a test step. If constraint data is provided in the state diagram  (test oracle) it is added too. A tester can use this data as input for the test plan.
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Expected outputs&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;expected_outputs&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:1,&amp;quot;secid&amp;quot;:4,&amp;quot;range&amp;quot;:&amp;quot;4370-6463&amp;quot;} --&gt;
&lt;h3 class=&quot;sectionedit5&quot; id=&quot;running_tests&quot;&gt;Running tests&lt;/h3&gt;
&lt;div class=&quot;level3&quot;&gt;

&lt;p&gt;
Test-beds are usually very hardware dependent in the embedded world. Therefore sinelaboreRT can’t generate a test-bed and the test case code for you. Using a unit test toolkit as described in [2] can be of great help here. To check that the machine is in the correct state you can instruct SinelaboreRT to generate trace code. Within the trace function you can send the trace data to a monitoring PC or store it e.g. for later analysis. This feature of SinelaboreRT is discussed in more detail in the second part of this article.
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Running tests&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;running_tests&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:1,&amp;quot;secid&amp;quot;:5,&amp;quot;range&amp;quot;:&amp;quot;6464-7023&amp;quot;} --&gt;
&lt;h3 class=&quot;sectionedit6&quot; id=&quot;comparing_actual_outputs_and_deciding_on_further_actions&quot;&gt;Comparing actual outputs and deciding on further actions&lt;/h3&gt;
&lt;div class=&quot;level3&quot;&gt;

&lt;p&gt;
Comparison of the actual outputs with expected outputs, and the decision on further actions (e.g. whether to modify the model, generate more tests, or stop testing) is a manual step. SinelaboreRT does not directly support this work.
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Comparing actual outputs and deciding on further actions&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;comparing_actual_outputs_and_deciding_on_further_actions&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:1,&amp;quot;secid&amp;quot;:6,&amp;quot;range&amp;quot;:&amp;quot;7024-7326&amp;quot;} --&gt;
&lt;h3 class=&quot;sectionedit7&quot; id=&quot;summary&quot;&gt;Summary&lt;/h3&gt;
&lt;div class=&quot;level3&quot;&gt;

&lt;p&gt;
This part 1 of a 2 parts (&lt;a href=&quot;https://sinelabore.com/doku.php/wiki/toolbox/model-based_testing_of_state_machines_ii&quot; class=&quot;wikilink1&quot; title=&quot;wiki:toolbox:model-based_testing_of_state_machines_ii&quot; data-wiki-id=&quot;wiki:toolbox:model-based_testing_of_state_machines_ii&quot;&gt;-&amp;gt; 2nd part&lt;/a&gt;) article has discussed how to test your state machine model and how the SinelaboreRT code-generator does support you in creating test routes to reach 100% transition coverage. Part II of this article shows how SinelaboreRT helps trace the test execution and to visualize the actual status of your state machine and the actually reach coverage. If you want to read more about MBT look &lt;a href=&quot;http://goldpractice.thedacs.com/practices/mbt/&quot; class=&quot;urlextern&quot; title=&quot;http://goldpractice.thedacs.com/practices/mbt/&quot; rel=&quot;ugc nofollow&quot;&gt;here&lt;/a&gt;.
&lt;/p&gt;

&lt;p&gt;
Your feedback is very welcome!
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Summary&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;summary&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:1,&amp;quot;secid&amp;quot;:7,&amp;quot;range&amp;quot;:&amp;quot;7327-7916&amp;quot;} --&gt;
&lt;h1 class=&quot;sectionedit8&quot; id=&quot;further_readings&quot;&gt;Further readings&lt;/h1&gt;
&lt;div class=&quot;level1&quot;&gt;
&lt;div class=&quot;table sectionedit9&quot;&gt;&lt;table class=&quot;inline&quot;&gt;
	&lt;tr class=&quot;row0&quot;&gt;
		&lt;td class=&quot;col0&quot;&gt; &lt;img src=&quot;https://sinelabore.com/lib/exe/fetch.php/wiki/articles/book_mbt.png&quot; class=&quot;medialeft&quot; align=&quot;left&quot; loading=&quot;lazy&quot; title=&quot;Image of book Practical Model-Based Testing: A Tools Approach&quot; alt=&quot;Image of book Practical Model-Based Testing: A Tools Approach&quot; /&gt; &lt;/td&gt;&lt;td class=&quot;col1&quot;&gt; &lt;a href=&quot;http://www.cs.waikato.ac.nz/research/mbt/&quot; class=&quot;urlextern&quot; title=&quot;http://www.cs.waikato.ac.nz/research/mbt/&quot; rel=&quot;ugc nofollow&quot;&gt;Practical Model-Based Testing: A Tools Approach&lt;/a&gt; from Mark Utting and Bruno Legeard. Chapter 5 discusses “Testing from finite state machines”.  &lt;/td&gt;
	&lt;/tr&gt;
&lt;/table&gt;&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;table&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;table&amp;quot;,&amp;quot;secid&amp;quot;:9,&amp;quot;range&amp;quot;:&amp;quot;7949-8251&amp;quot;} --&gt;&lt;div class=&quot;table sectionedit10&quot;&gt;&lt;table class=&quot;inline&quot;&gt;
	&lt;tr class=&quot;row0&quot;&gt;
		&lt;td class=&quot;col0&quot;&gt; &lt;img src=&quot;https://sinelabore.com/lib/exe/fetch.php/wiki/articles/book_test_driven_development.png&quot; class=&quot;medialeft&quot; align=&quot;left&quot; loading=&quot;lazy&quot; title=&quot;Image of book Test-Driven Development for Embedded C&quot; alt=&quot;Image of book Test-Driven Development for Embedded C&quot; /&gt; &lt;/td&gt;&lt;td class=&quot;col1&quot;&gt;“Test-Driven Development for Embedded C” from  &lt;a href=&quot;http://www.renaissancesoftware.net/blog/&quot; class=&quot;urlextern&quot; title=&quot;http://www.renaissancesoftware.net/blog/&quot; rel=&quot;ugc nofollow&quot;&gt;James W. Grenning&lt;/a&gt;. It teaches you how to use the unit testing frameworks  &lt;a href=&quot;http://sourceforge.net/apps/trac/unity/wiki&quot; class=&quot;urlextern&quot; title=&quot;http://sourceforge.net/apps/trac/unity/wiki&quot; rel=&quot;ugc nofollow&quot;&gt;Unity&lt;/a&gt; and CppUTest to test embedded software. This book does not explicitly discuss state machine testing. Read a review  &lt;a href=&quot;http://www.eetimes.com/discussion/other/4211145/New-embedded-systems-books?pageNumber=0&quot; class=&quot;urlextern&quot; title=&quot;http://www.eetimes.com/discussion/other/4211145/New-embedded-systems-books?pageNumber=0&quot; rel=&quot;ugc nofollow&quot;&gt;here&lt;/a&gt;. &lt;/td&gt;
	&lt;/tr&gt;
&lt;/table&gt;&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;table&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;table1&amp;quot;,&amp;quot;secid&amp;quot;:10,&amp;quot;range&amp;quot;:&amp;quot;8254-8809&amp;quot;} --&gt;
&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Further readings&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;further_readings&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:1,&amp;quot;secid&amp;quot;:8,&amp;quot;range&amp;quot;:&amp;quot;7917-&amp;quot;} --&gt;</description>
            <author>anonymous@undisclosed.example.com (Anonymous)</author>
            <pubDate>Mon, 01 Nov 2021 13:51:20 +0000</pubDate>
        </item>
        <item>
            <title>Model-based testing of state machines - part II</title>
            <link>https://sinelabore.com/doku.php/wiki/toolbox/model-based_testing_of_state_machines_ii</link>
            <description>
&lt;h1 class=&quot;sectionedit1&quot; id=&quot;model-based_testing_of_state_machines_-_part_ii&quot;&gt;Model-based testing of state machines - part II&lt;/h1&gt;
&lt;div class=&quot;level1&quot;&gt;

&lt;p&gt;
This article explains how sinelaboreRT helps you to test your state based software.
&lt;/p&gt;

&lt;p&gt;
In the first part of this article we have seen how SinelaboreRT helps you to generate test cases to reach 100% transition coverage. But sinelaboreRT can do more. You can connect your running target with an automatically generated visualization, show the present state of the state machine, show possible triggers etc. - all visually. And finally it shows the actually reached transition coverage.
&lt;/p&gt;

&lt;p&gt;
This article uses the microwave oven from the manual as example. Code is available in the examples folder of the code generator.
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Model-based testing of state machines - part II&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;model-based_testing_of_state_machines_-_part_ii&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:0,&amp;quot;secid&amp;quot;:1,&amp;quot;range&amp;quot;:&amp;quot;1-678&amp;quot;} --&gt;
&lt;h3 class=&quot;sectionedit2&quot; id=&quot;enabling_tracing&quot;&gt;Enabling tracing&lt;/h3&gt;
&lt;div class=&quot;level3&quot;&gt;

&lt;p&gt;
The first step is to close the link between the state machine running on the target with the sinelaboreRT visualization running on the PC. In this article we assume that the state machine was created with the built-in editor. If you have used another &lt;abbr title=&quot;Unified Modeling Language&quot;&gt;UML&lt;/abbr&gt; tool used just convert your model file into the sinelaboreRT internal format by using -l ssc as output format on the command line. The following example shows how to convert a cadifra model into the internal scc representation: 
&lt;/p&gt;
&lt;pre class=&quot;code bash&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;java&lt;/span&gt; &lt;span class=&quot;re5&quot;&gt;-jar&lt;/span&gt; codegen.jar &lt;span class=&quot;re5&quot;&gt;-p&lt;/span&gt; CADIFRA &lt;span class=&quot;re5&quot;&gt;-l&lt;/span&gt; ssc &lt;span class=&quot;re5&quot;&gt;-o&lt;/span&gt; oven.xml oven.cdd&lt;/pre&gt;

&lt;p&gt;
To generate trace code use the   &lt;code&gt;-Trace&lt;/code&gt; command line switch. An example is shown as follows: 
&lt;/p&gt;
&lt;pre class=&quot;code bash&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;java&lt;/span&gt; &lt;span class=&quot;re5&quot;&gt;-jar&lt;/span&gt; codegen.jar &lt;span class=&quot;re5&quot;&gt;-c&lt;/span&gt; &lt;span class=&quot;re5&quot;&gt;-Trace&lt;/span&gt; &lt;span class=&quot;re5&quot;&gt;-p&lt;/span&gt; ssc &lt;span class=&quot;re5&quot;&gt;-l&lt;/span&gt; cx &lt;span class=&quot;re5&quot;&gt;-o&lt;/span&gt; oven oven.xml &lt;/pre&gt;

&lt;p&gt;
The trace function itself has to be provided by yourself because it is typically very system dependent. Within the trace function trace data can be sent to the monitoring PC. As the trace function is in your hand you can use whatever hardware interface is feasible to send the trace events. In most cases it might be a kind of serial uart interface. If you have a target with TCP/IP capabilities the use of UDP is recommended. The following code shows the trace function we use in this example.
&lt;/p&gt;
&lt;pre class=&quot;code c&quot;&gt;&lt;span class=&quot;kw4&quot;&gt;void&lt;/span&gt; ovenTraceEvent&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;kw4&quot;&gt;int&lt;/span&gt; evt&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
    &lt;span class=&quot;kw1&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;sendto&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;s&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt;ovenTraceEvents&lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;evt&lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt;
            &lt;a href=&quot;http://www.opengroup.org/onlinepubs/009695399/functions/strlen.html&quot;&gt;&lt;span class=&quot;kw3&quot;&gt;strlen&lt;/span&gt;&lt;/a&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;ovenTraceEvents&lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;evt&lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nu0&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;kw4&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;kw4&quot;&gt;struct&lt;/span&gt; sockaddr &lt;span class=&quot;sy0&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;&amp;amp;&lt;/span&gt;si_other&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt;slen&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;==-&lt;/span&gt;&lt;span class=&quot;nu0&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
        &lt;a href=&quot;http://www.opengroup.org/onlinepubs/009695399/functions/perror.html&quot;&gt;&lt;span class=&quot;kw3&quot;&gt;perror&lt;/span&gt;&lt;/a&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;&amp;quot;sendto&lt;span class=&quot;es1&quot;&gt;\n&lt;/span&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
        &lt;a href=&quot;http://www.opengroup.org/onlinepubs/009695399/functions/exit.html&quot;&gt;&lt;span class=&quot;kw3&quot;&gt;exit&lt;/span&gt;&lt;/a&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;nu0&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Enabling tracing&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;enabling_tracing&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:0,&amp;quot;secid&amp;quot;:2,&amp;quot;range&amp;quot;:&amp;quot;679-2184&amp;quot;} --&gt;
&lt;h3 class=&quot;sectionedit3&quot; id=&quot;display_the_state_diagram&quot;&gt;Display the state diagram&lt;/h3&gt;
&lt;div class=&quot;level3&quot;&gt;

&lt;p&gt;
To actually display the state diagram call the code generator with the &lt;code&gt;-S&lt;/code&gt; command line switch. The window as shown in figure 1 pops up. The status of the state machine in its initial state is displayed. 
&lt;/p&gt;
&lt;pre class=&quot;code bash&quot;&gt;&lt;span class=&quot;kw2&quot;&gt;java&lt;/span&gt; &lt;span class=&quot;re5&quot;&gt;-jar&lt;/span&gt; codegen.jar &lt;span class=&quot;re5&quot;&gt;-S&lt;/span&gt; &lt;span class=&quot;re5&quot;&gt;-p&lt;/span&gt; ssc &lt;span class=&quot;re5&quot;&gt;-o&lt;/span&gt; oven oven.xml&lt;/pre&gt;

&lt;p&gt;
&lt;img src=&quot;https://sinelabore.com/lib/exe/fetch.php/wiki/articles/mbt_partii_simulation.jpg&quot; class=&quot;mediacenter&quot; loading=&quot;lazy&quot; alt=&quot;&quot; /&gt;
Figure 1: The example here is the microwave oven state machine used in the 
manual. It is available in the examples folders of the SinelaboreRT download.
&lt;/p&gt;

&lt;p&gt;
he main window shows the automatically generated state diagram. Events that can be handled at that moment are shown in blue. They are also listed in left tree view. The output field on the bottom of the window shows the so far executed action code. 
&lt;/p&gt;

&lt;p&gt;
You can now send events to the machine by clicking on an event in the tree view. The display is updated accordingly and shows the new status.
&lt;/p&gt;

&lt;p&gt;
But as we want to trace the real machine we need the connection between the target and the visualization. Therefore the code generator is able to receive events via UPD. This is what was shown in the code snipped above. Most embedded systems will not offer an Ethernet connection directly. In this case send the trace data e.g. via a serial interface to the PC and forward them from there via UDP to the visualization. This can be done in a view lines of code. This has been realized in the &lt;a href=&quot;https://sinelabore.com/doku.php/wiki/examples/mobile_robot_i&quot; class=&quot;wikilink1&quot; title=&quot;wiki:examples:mobile_robot_i&quot; data-wiki-id=&quot;wiki:examples:mobile_robot_i&quot;&gt;Asuro Mobile Robot&lt;/a&gt; example.
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Display the state diagram&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;display_the_state_diagram&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:3,&amp;quot;secid&amp;quot;:3,&amp;quot;range&amp;quot;:&amp;quot;2185-3658&amp;quot;} --&gt;
&lt;h3 class=&quot;sectionedit4&quot; id=&quot;testing_at_work&quot;&gt;Testing at work&lt;/h3&gt;
&lt;div class=&quot;level3&quot;&gt;

&lt;p&gt;
Now we have prepared the visualization. So let’s start the microwave oven example. To make it simple for you to follow this example the microwave oven code was compiled as a simple console program. This program allows you to set the cooking time, cooking power and to open and close the door via keyboard commands. When a cooking time was set and the door is closed the cooking starts. The console application prints out some debug messages e.g. how much cooking time is left. When the time is zero the microwave generator is switched off and the door must be opened before the next cooking cycle can start. The following figure shows just this situation. Cooking has ended. The actual state is “Completed”. As you can see only a transition coverage of 57% was reached during this test run.
&lt;/p&gt;

&lt;p&gt;
&lt;img src=&quot;https://sinelabore.com/lib/exe/fetch.php/wiki/articles/mbt_partii_simulation57percent.jpg&quot; class=&quot;mediacenter&quot; loading=&quot;lazy&quot; alt=&quot;&quot; /&gt;
Figure 2: While testing available transitions are displayed in blue 
and the active states in red. The presently achieved transition 
coverage is shown as progress bar below the event list.
&lt;/p&gt;

&lt;p&gt;
The transitions not yet taken can be displayed as tooltip of the progress bar. As you can see we have not yet changed the cooking power nor have we opened the door while cooking.
&lt;/p&gt;

&lt;p&gt;
With this information at hand it is easy to add the missing transitions to the test script to reach the 100% transition coverage. Be aware that 100% transition coverage also means 100% state coverage!
&lt;/p&gt;

&lt;p&gt;
So far we have interactively tested the device i.e. the console application in our case. To avoid this manual interaction (which is really annoying for large machines) it is highly recommended to create a test environment that can be fed with the test routes generated from the code generator (see first part of this article series). This pays back quickly if extensions or bug fixes are necessary and regression tests must be performed.
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Testing at work&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;testing_at_work&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:4,&amp;quot;secid&amp;quot;:4,&amp;quot;range&amp;quot;:&amp;quot;3659-5561&amp;quot;} --&gt;
&lt;h3 class=&quot;sectionedit5&quot; id=&quot;testing_not_modeled_behavior&quot;&gt;Testing not modeled behavior&lt;/h3&gt;
&lt;div class=&quot;level3&quot;&gt;

&lt;p&gt;
Even with 100% transition coverage you have only tested what was modeled. Often transitions that do not lead to a state change are omitted during the initial design. But from a testing point of view it is highly recommended to model such transitions too. Then the test route automatically include steps that check if the machine reacts correctly to transitions that do not change state! 
&lt;/p&gt;

&lt;p&gt;
Of course also perform boundary tests of used variables. For the microwave oven machine check for example what happens if the cooking time is zero and you still decrement it, or if it has reached its maximum and you still increment it etc. See the two recommended books listed in the &lt;a href=&quot;https://sinelabore.com/doku.php/wiki/toolbox/model-based_testing_of_state_machines_i&quot; class=&quot;wikilink1&quot; title=&quot;wiki:toolbox:model-based_testing_of_state_machines_i&quot; data-wiki-id=&quot;wiki:toolbox:model-based_testing_of_state_machines_i&quot;&gt;first part&lt;/a&gt; of the article for many more practical hints.
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Testing not modeled behavior&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;testing_not_modeled_behavior&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:4,&amp;quot;secid&amp;quot;:5,&amp;quot;range&amp;quot;:&amp;quot;5562-6390&amp;quot;} --&gt;
&lt;h3 class=&quot;sectionedit6&quot; id=&quot;summary&quot;&gt;Summary&lt;/h3&gt;
&lt;div class=&quot;level3&quot;&gt;

&lt;p&gt;
We close this article with citing again Martin Gomez who wrote “ … require a fair amount of patience and coffee, because even a mid-size state machine can have 100 different transitions. However, the number of transitions is an excellent measure of the system&amp;#039;s complexity. The complexity is driven by the user&amp;#039;s requirements: the state machine makes it blindingly obvious how much you have to test. With a less-organized approach, the amount of testing required might be equally large-you just won&amp;#039;t know it.”
&lt;/p&gt;

&lt;p&gt;
This article has shown how sinelaboreRT helps you in testing your state based software. Therefore the different steps of testing were presented and how the sinelaboreRT code-generator supports you during the different test steps was discussed in detail.
&lt;/p&gt;

&lt;p&gt;
We hope you enjoyed these two articles. Your feedback is very welcome!
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Summary&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;summary&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:4,&amp;quot;secid&amp;quot;:6,&amp;quot;range&amp;quot;:&amp;quot;6391-&amp;quot;} --&gt;</description>
            <author>anonymous@undisclosed.example.com (Anonymous)</author>
            <pubDate>Sun, 21 Oct 2012 18:39:23 +0000</pubDate>
        </item>
        <item>
            <title>Regions or no regions</title>
            <link>https://sinelabore.com/doku.php/wiki/toolbox/regions_or_no_regions</link>
            <description>
&lt;h1 class=&quot;sectionedit1&quot; id=&quot;regions_or_no_regions&quot;&gt;Regions or no regions&lt;/h1&gt;
&lt;div class=&quot;level1&quot;&gt;

&lt;p&gt;
For some systems you want to model certain parts which run independently from each other but react on the same set of events. These independent parts can be modelled using regions in &lt;abbr title=&quot;Unified Modeling Language&quot;&gt;UML&lt;/abbr&gt; state diagrams. Another term often used are orthogonal states or AND states (model is in state A and state B at the same time).
&lt;a href=&quot;https://sinelabore.com/lib/exe/detail.php/wiki/examples/state-machine_hierachical.gif?id=wiki%3Atoolbox%3Aregions_or_no_regions&quot; class=&quot;media&quot; title=&quot;wiki:examples:state-machine_hierachical.gif&quot;&gt;&lt;img src=&quot;https://sinelabore.com/lib/exe/fetch.php/wiki/examples/state-machine_hierachical.gif&quot; class=&quot;media&quot; loading=&quot;lazy&quot; title=&quot;Microwave oven model with hierarchical states&quot; alt=&quot;Microwave oven model with hierarchical states&quot; /&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;
Let&amp;#039;s take a microwave oven as an example. The model above is designed around the states that can be perceived from the outside (i.e. the user). Either the oven is on or off or paused. All other elements in the oven (lamp, timer …) are handled in these states and the transitions between them.
&lt;/p&gt;

&lt;p&gt;
Benefits:
&lt;/p&gt;
&lt;ul&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; compact diagram&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; Eventually easier to understand for an outsider (e.g. customer) not knowing or interested in the internal organisation of the device.&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
Drawbacks:
&lt;/p&gt;
&lt;ul&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; the individual parts of the system are not represented and separated clearly&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Regions or no regions&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;regions_or_no_regions&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:0,&amp;quot;secid&amp;quot;:1,&amp;quot;range&amp;quot;:&amp;quot;1-1008&amp;quot;} --&gt;
&lt;h1 class=&quot;sectionedit2&quot; id=&quot;model_with_regions&quot;&gt;Model with regions&lt;/h1&gt;
&lt;div class=&quot;level1&quot;&gt;

&lt;p&gt;
Introducing regions separates the parallel running parts of a system in an own region of the model.
A region has a name and should focus on one part of the system. A state can contain two or more regions which are executed in parallel. Each region receives the same events that are sent to the containing state. Entering a state with regions enters all regions at the same time. Leaving a state with regions leaves all regions at the same time.
&lt;/p&gt;

&lt;p&gt;
&lt;a href=&quot;https://sinelabore.com/lib/exe/detail.php/wiki/examples/state-machine-with-regions.gif?id=wiki%3Atoolbox%3Aregions_or_no_regions&quot; class=&quot;media&quot; title=&quot;wiki:examples:state-machine-with-regions.gif&quot;&gt;&lt;img src=&quot;https://sinelabore.com/lib/exe/fetch.php/wiki/examples/state-machine-with-regions.gif&quot; class=&quot;media&quot; loading=&quot;lazy&quot; title=&quot;Microwave oven model using regions&quot; alt=&quot;Microwave oven model using regions&quot; /&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;
Benefits:
&lt;/p&gt;
&lt;ul&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; Clear separation of parallel running parts of the system&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; Reuse is simpler because different parts of the system are not mixed with each other.&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
Drawbacks:
&lt;/p&gt;
&lt;ul&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; Slightly bigger model and more states to model&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Model with regions&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;model_with_regions&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:0,&amp;quot;secid&amp;quot;:2,&amp;quot;range&amp;quot;:&amp;quot;1009-1798&amp;quot;} --&gt;
&lt;h1 class=&quot;sectionedit3&quot; id=&quot;conclusions&quot;&gt;Conclusions&lt;/h1&gt;
&lt;div class=&quot;level1&quot;&gt;

&lt;p&gt;
Both models creates the same output. So it is not about right or wrong but more what is more appropriate for the current case. If reuse is a design goal regions can have a benefit. If a most compact design is a design goal regions have a slight drawback.
&lt;/p&gt;

&lt;p&gt;
Send us a mail in case you want receive the model and test bench to get an own impression.
&lt;/p&gt;

&lt;p&gt;
~~DISCUSSION|Leave your comments~~
&lt;/p&gt;
&lt;div class=&quot;tags&quot;&gt;&lt;span&gt;
	&lt;a href=&quot;https://sinelabore.com/doku.php/tag/learning?do=showtag&amp;amp;tag=%5BLearning%5D&quot; class=&quot;wikilink1&quot; title=&quot;tag:learning&quot; rel=&quot;tag&quot;&gt;[Learning]&lt;/a&gt;
&lt;/span&gt;&lt;/div&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Conclusions&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;conclusions&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:0,&amp;quot;secid&amp;quot;:3,&amp;quot;range&amp;quot;:&amp;quot;1799-&amp;quot;} --&gt;</description>
            <author>anonymous@undisclosed.example.com (Anonymous)</author>
            <pubDate>Sun, 18 Apr 2021 15:55:55 +0000</pubDate>
        </item>
        <item>
            <title>Time Events in State Machines</title>
            <link>https://sinelabore.com/doku.php/wiki/toolbox/time_events_in_state_machines</link>
            <description>


&lt;h1 class=&quot;sectionedit1&quot; id=&quot;time_events_in_state_machines&quot;&gt;Time Events in State Machines&lt;/h1&gt;
&lt;div class=&quot;level1&quot;&gt;

&lt;p&gt;
In almost every embedded application, time-controlled activities are required. Examples of this are activities that are to run in a fixed cycle, or activities that are to be triggered in the event of a timeout, or also to implement certain signal patterns.
&lt;/p&gt;

&lt;p&gt;
In &lt;abbr title=&quot;Unified Modeling Language&quot;&gt;UML&lt;/abbr&gt; state machines, a time event specifies an instance in time that triggers  a transition to be taken when the specified time has elapsed. E.g. move from a state &lt;code&gt;S1&lt;/code&gt; to a state &lt;code&gt;S2&lt;/code&gt; after 1 second.  
&lt;/p&gt;

&lt;p&gt;
Time events might be relative and be used in the context of a trigger and the starting point is the time at which the trigger becomes active.
A relative time trigger is specified with the keyword &lt;code&gt;after&lt;/code&gt; followed by an expression that evaluates to a time value, such as “after (5 seconds).” 
&lt;/p&gt;

&lt;p&gt;
Alternatively an absolute time trigger is specified with the keyword &lt;code&gt;at&lt;/code&gt; followed by an expression that evaluates to a time value, such as “Oct. 1, 2023, 12:00:00.”
&lt;/p&gt;

&lt;p&gt;
&lt;a href=&quot;https://sinelabore.com/lib/exe/detail.php/wiki/toolbox/after_at_time_events.svg?id=wiki%3Atoolbox%3Atime_events_in_state_machines&quot; class=&quot;media&quot; title=&quot;wiki:toolbox:after_at_time_events.svg&quot;&gt;&lt;img src=&quot;https://sinelabore.com/lib/exe/fetch.php/wiki/toolbox/after_at_time_events.svg?w=400&amp;amp;tok=d32d7a&quot; class=&quot;mediacenter&quot; loading=&quot;lazy&quot; title=&quot; UML specification of after / at time events&quot; alt=&quot; UML specification of after / at time events&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;
While this looks very clear at first sight, it is not sufficient for code generation. 
&lt;/p&gt;

&lt;p&gt;
The first major problem is that there is no standard way to specify a timer ID or timer name for the timeout event. However, this is required in practice to associate the timeout with an underlying timer service. In embedded systems, it is not practical to create a new timer from scratch every time an “after” or “at” trigger is encountered. Quite the opposite - you just want to create a timer and reuse it in multiple places in a diagram. Of course, you could specify a name or ID in a linked &lt;abbr title=&quot;Unified Modeling Language&quot;&gt;UML&lt;/abbr&gt; comment or similar, but that&amp;#039;s not really a nice solution.
&lt;/p&gt;

&lt;p&gt;
The other big problem is that not all &lt;abbr title=&quot;Unified Modeling Language&quot;&gt;UML&lt;/abbr&gt; tools allow the specification of time events. 
&lt;/p&gt;

&lt;p&gt;
Finally, the code generator should not introduce any restrictions or constraints on the system&amp;#039;s time services. However, a meaningful use of time events would require the code generator to specify how the time services are to be implemented. And that would certainly not always meet your needs and would only force unnecessary restrictions.
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Time Events in State Machines&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;time_events_in_state_machines&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:0,&amp;quot;secid&amp;quot;:1,&amp;quot;range&amp;quot;:&amp;quot;12-2176&amp;quot;} --&gt;
&lt;h2 class=&quot;sectionedit2&quot; id=&quot;so_what_is_the_proposed_solution_for_implementing_time_events_with_the_sinelaborertcode_generator&quot;&gt;So what is the proposed solution for implementing time events with the Sinelabore//RT// code generator?&lt;/h2&gt;
&lt;div class=&quot;level2&quot;&gt;

&lt;p&gt;
Two aspects must be considered when using timed transitions.
&lt;/p&gt;
&lt;ol&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; All different ways of realizing timers in embedded systems must be possible, and no restrictions should be introduced by using the code generator.&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; All relevant information should be contained in the state diagram itself&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;
The recommended way is not to use the time event specification of the &lt;abbr title=&quot;Unified Modeling Language&quot;&gt;UML&lt;/abbr&gt; tools, but to use regular signal events. Timers can be “manually”, created started or stopped in any action code. If static system initialization is required, timers can also be created at system startup. The underlying timer service of your choice (see below) simply sends the provided timeout events to the state machine input queue.  
To indicate in the diagram that an event is a timer, it is recommended to use a naming convention and start the name of the timeout event with, for example, &lt;code&gt;evTout&lt;/code&gt;.
&lt;/p&gt;

&lt;p&gt;
In the following figure a state machine uses two independent timers. One creates looping between &lt;code&gt;S11&lt;/code&gt; and &lt;code&gt;S12&lt;/code&gt; and is created as cyclic timer. The other second timeout stops this looping after some time (one shot timer) and stops timer1 at the transition to &lt;code&gt;S2&lt;/code&gt;.
&lt;/p&gt;

&lt;p&gt;
&lt;a href=&quot;https://sinelabore.com/lib/exe/detail.php/wiki/toolbox/not_using_after_at_time_events.svg?id=wiki%3Atoolbox%3Atime_events_in_state_machines&quot; class=&quot;media&quot; title=&quot;wiki:toolbox:not_using_after_at_time_events.svg&quot;&gt;&lt;img src=&quot;https://sinelabore.com/lib/exe/fetch.php/wiki/toolbox/not_using_after_at_time_events.svg&quot; class=&quot;mediacenter&quot; loading=&quot;lazy&quot; title=&quot; state machine diagram with cyclic and single-shot timer use&quot; alt=&quot; state machine diagram with cyclic and single-shot timer use&quot; /&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;So what is the proposed solution for implementing time events with the Sinelabore\/\/RT\/\/ code generator?&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;so_what_is_the_proposed_solution_for_implementing_time_events_with_the_sinelaborertcode_generator&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:0,&amp;quot;secid&amp;quot;:2,&amp;quot;range&amp;quot;:&amp;quot;2177-3558&amp;quot;} --&gt;
&lt;h2 class=&quot;sectionedit3&quot; id=&quot;rtos_based_designs&quot;&gt;RTOS based Designs&lt;/h2&gt;
&lt;div class=&quot;level2&quot;&gt;

&lt;p&gt;
Each &lt;abbr title=&quot;Real-Time Operating System&quot;&gt;RTOS&lt;/abbr&gt; offers the possibility to define software timers. If a timeout occurs, a user-defined timeout function is called. In this function, the timeout event is then placed in the state machine event queue. Examples can be found &lt;a href=&quot;https://sinelabore.com/doku.php/wiki/howto/vxworks&quot; class=&quot;wikilink1&quot; title=&quot;wiki:howto:vxworks&quot; data-wiki-id=&quot;wiki:howto:vxworks&quot;&gt;here&lt;/a&gt;, &lt;a href=&quot;https://sinelabore.com/doku.php/wiki/toolbox/using_state-machines_with_a_real-time_operating_system_rtos&quot; class=&quot;wikilink1&quot; title=&quot;wiki:toolbox:using_state-machines_with_a_real-time_operating_system_rtos&quot; data-wiki-id=&quot;wiki:toolbox:using_state-machines_with_a_real-time_operating_system_rtos&quot;&gt;here&lt;/a&gt; or &lt;a href=&quot;https://sinelabore.com/doku.php/wiki/howto/rtos&quot; class=&quot;wikilink1&quot; title=&quot;wiki:howto:rtos&quot; data-wiki-id=&quot;wiki:howto:rtos&quot;&gt; here&lt;/a&gt; for various real-time operating systems.
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;RTOS based Designs&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;rtos_based_designs&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:0,&amp;quot;secid&amp;quot;:3,&amp;quot;range&amp;quot;:&amp;quot;3559-4003&amp;quot;} --&gt;
&lt;h2 class=&quot;sectionedit4&quot; id=&quot;mainloop_designs&quot;&gt;Mainloop Designs&lt;/h2&gt;
&lt;div class=&quot;level2&quot;&gt;

&lt;p&gt;
In mainloop/foreground background designs, you need to provide some sort of timer service. Often there is a hardware timer that supplies the system tick. Within the system tick, a software timer service can be implemented. This software timer service checks each tick to see if a timeout has occurred, and then places the corresponding timeout event in the state machine&amp;#039;s event queue. An example of such a system is available &lt;a href=&quot;https://sinelabore.com/doku.php/wiki/news/02jan2015&quot; class=&quot;wikilink1&quot; title=&quot;wiki:news:02jan2015&quot; data-wiki-id=&quot;wiki:news:02jan2015&quot;&gt;here&lt;/a&gt;. And an example of a simple timer service that can be invoked by a timer irq can be found at &lt;a href=&quot;https://github.com/sinelabore/examples/blob/master/lib/&quot; class=&quot;urlextern&quot; title=&quot;https://github.com/sinelabore/examples/blob/master/lib/&quot; rel=&quot;ugc nofollow&quot;&gt;github&lt;/a&gt;.
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Mainloop Designs&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;mainloop_designs&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:0,&amp;quot;secid&amp;quot;:4,&amp;quot;range&amp;quot;:&amp;quot;4004-4650&amp;quot;} --&gt;
&lt;h2 class=&quot;sectionedit5&quot; id=&quot;conclusions&quot;&gt;Conclusions&lt;/h2&gt;
&lt;div class=&quot;level2&quot;&gt;

&lt;p&gt;
The use of timed transitions can be realized with signal events in a very flexible way for any kind of system architecture. All relevant information is available and represented in the state diagram so that 100% of the state machine code can be generated without requiring hidden specifications and introducing constraints on the design of your system.
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Conclusions&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;conclusions&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:0,&amp;quot;secid&amp;quot;:5,&amp;quot;range&amp;quot;:&amp;quot;4651-&amp;quot;} --&gt;</description>
            <author>anonymous@undisclosed.example.com (Anonymous)</author>
            <pubDate>Sun, 12 Mar 2023 17:14:14 +0000</pubDate>
        </item>
        <item>
            <title>Using Mscgen for nice looking State Flow Diagrams - Trace the flow of Events</title>
            <link>https://sinelabore.com/doku.php/wiki/toolbox/trace-the-event-flow</link>
            <description>
&lt;h1 class=&quot;sectionedit1&quot; id=&quot;using_mscgen_for_nice_looking_state_flow_diagrams_-_trace_the_flow_of_events&quot;&gt;Using Mscgen for nice looking State Flow Diagrams - Trace the flow of Events&lt;/h1&gt;
&lt;div class=&quot;level1&quot;&gt;

&lt;p&gt;
There are many cases where it is useful to monitor a system in real-time and trace the sequence of events. In this toolbox article we explain how to do code instrumentation and create a nice looking Sequence Diagram showing exactly the flow of events (trace) for a detailed analysis. For the graphics rendering we use &lt;code&gt;Mscgen&lt;/code&gt; available &lt;a href=&quot;http://www.mcternan.me.uk/mscgen/&quot; class=&quot;urlextern&quot; title=&quot;http://www.mcternan.me.uk/mscgen/&quot; rel=&quot;ugc nofollow&quot;&gt;here&lt;/a&gt;.The goal is to generate the following diagram more or less automatically.
&lt;a href=&quot;https://sinelabore.com/lib/exe/fetch.php/wiki/toolbox/msc.png&quot; class=&quot;media&quot; title=&quot;wiki:toolbox:msc.png&quot;&gt;&lt;img src=&quot;https://sinelabore.com/lib/exe/fetch.php/wiki/toolbox/msc.png&quot; class=&quot;mediacenter&quot; loading=&quot;lazy&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;
Figure 1: An example for a state flow we want to generate in this article (&lt;a href=&quot;https://sinelabore.com/lib/exe/fetch.php/wiki/toolbox/sc.png&quot; class=&quot;media mediafile mf_png&quot; title=&quot;wiki:toolbox:sc.png (42.3 KB)&quot;&gt;full picture&lt;/a&gt;).
&lt;/p&gt;

&lt;p&gt;
To make things really practical we use the &lt;a href=&quot;https://github.com/sinelabore/examples/tree/master/EnergiaBlink&quot; class=&quot;urlextern&quot; title=&quot;https://github.com/sinelabore/examples/tree/master/EnergiaBlink&quot; rel=&quot;ugc nofollow&quot;&gt;EnergiaBlink&lt;/a&gt; example available on GitHub. To follow the described steps yourself install Energia and one of the nice starter kits from TI. Here I use the &lt;a href=&quot;http://www.ti.com/tool/MSP-EXP430F5529LP&quot; class=&quot;urlextern&quot; title=&quot;http://www.ti.com/tool/MSP-EXP430F5529LP&quot; rel=&quot;ugc nofollow&quot;&gt;EXP430F5969&lt;/a&gt;.
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Using Mscgen for nice looking State Flow Diagrams - Trace the flow of Events&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;using_mscgen_for_nice_looking_state_flow_diagrams_-_trace_the_flow_of_events&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:0,&amp;quot;secid&amp;quot;:1,&amp;quot;range&amp;quot;:&amp;quot;1-1032&amp;quot;} --&gt;
&lt;h2 class=&quot;sectionedit2&quot; id=&quot;step_1instrumenting_your_code&quot;&gt;Step 1: Instrumenting your code&lt;/h2&gt;
&lt;div class=&quot;level2&quot;&gt;

&lt;p&gt;
As first step it is necessary to instrument the state machine code. Luckily this is done automatically from the code-generator. The command line switch &lt;code&gt;-Trace&lt;/code&gt; enables the generation of trace code. The following code snipped shows the result:
&lt;/p&gt;
&lt;pre class=&quot;code c&quot;&gt;  &lt;span class=&quot;kw1&quot;&gt;switch&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;stateVars.&lt;span class=&quot;me1&quot;&gt;stateVar&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
&amp;nbsp;
    &lt;span class=&quot;kw1&quot;&gt;case&lt;/span&gt; Slow&lt;span class=&quot;sy0&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;kw1&quot;&gt;switch&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;stateVars.&lt;span class=&quot;me1&quot;&gt;stateVarSlow&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
        &lt;span class=&quot;kw1&quot;&gt;case&lt;/span&gt; SlowLedOn&lt;span class=&quot;sy0&quot;&gt;:&lt;/span&gt;
          &lt;span class=&quot;kw1&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;msg&lt;span class=&quot;sy0&quot;&gt;==&lt;/span&gt;evTimeout&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
            &lt;span class=&quot;coMULTI&quot;&gt;/* Transition from SlowLedOn to SlowLedOff */&lt;/span&gt;
            evConsumed&lt;span class=&quot;sy0&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nu0&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;coMULTI&quot;&gt;/* OnEntry code of state SlowLedOff */&lt;/span&gt;
            digitalWrite&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;RED_LED&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; LOW&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&amp;nbsp;
            &lt;span class=&quot;coMULTI&quot;&gt;/* adjust state variables  */&lt;/span&gt;
            stateVarsCopy.&lt;span class=&quot;me1&quot;&gt;stateVarSlow&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;=&lt;/span&gt; SlowLedOff&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;sy0&quot;&gt;---&amp;gt;&lt;/span&gt;        StatemachineTraceEvent&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;nu0&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;    &lt;span class=&quot;sy0&quot;&gt;&amp;lt;----&lt;/span&gt;
          &lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;&lt;span class=&quot;kw1&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
            &lt;span class=&quot;coMULTI&quot;&gt;/* Intentionally left blank */&lt;/span&gt;
          &lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt; &lt;span class=&quot;coMULTI&quot;&gt;/*end of event selection */&lt;/span&gt;
         &lt;span class=&quot;kw2&quot;&gt;break&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;coMULTI&quot;&gt;/* end of case SlowLedOn  */&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;
Figure 2: The generated state machine code with the trace method call.
&lt;/p&gt;

&lt;p&gt;
The relevant line is the marked with the two arrows. Whenever this code executes the trace method is called. The content of this trace method can be freely defined. In our case we want to store the event for later usage. Figure 3 shows the required trace method. As you can see the event is already stored in the format needed later on from the &lt;code&gt;Mscgen&lt;/code&gt; tool.
&lt;/p&gt;
&lt;pre class=&quot;code c&quot;&gt;String event&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kw4&quot;&gt;void&lt;/span&gt; StatemachineTraceEvent&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;kw4&quot;&gt;int&lt;/span&gt; evt&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
  event &lt;span class=&quot;sy0&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;st0&quot;&gt;&amp;quot;[ &amp;quot;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
  event &lt;span class=&quot;sy0&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;st0&quot;&gt;&amp;quot;label = &lt;span class=&quot;es1&quot;&gt;\&amp;quot;&lt;/span&gt;&amp;quot;&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
  event &lt;span class=&quot;sy0&quot;&gt;+=&lt;/span&gt; myGeneratedSM.&lt;span class=&quot;me1&quot;&gt;getNameByEvent&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;STATEMACHINE_EVENT_T&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;evt&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
  event &lt;span class=&quot;sy0&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;st0&quot;&gt;&amp;quot; &lt;span class=&quot;es1&quot;&gt;\&amp;quot;&lt;/span&gt; ]&amp;quot;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;
Figure 3: Trace code automatically called from the state machine each time an event gets processed.
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Step 1: Instrumenting your code&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;step_1instrumenting_your_code&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:0,&amp;quot;secid&amp;quot;:2,&amp;quot;range&amp;quot;:&amp;quot;1033-2689&amp;quot;} --&gt;
&lt;h2 class=&quot;sectionedit3&quot; id=&quot;step_2writing_the_mscgen_text_to_the_serial_line&quot;&gt;Step 2: Writing the Mscgen text to the serial line&lt;/h2&gt;
&lt;div class=&quot;level2&quot;&gt;

&lt;p&gt;
The &lt;code&gt;Mscgen&lt;/code&gt; tool expects a specific input format and requires some definitions like available states, diagram width and so forth at the begin. This is printed in the setup code once after reset.
&lt;/p&gt;
&lt;pre class=&quot;code c&quot;&gt;Serial.&lt;span class=&quot;me1&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;&amp;quot;__start__&amp;quot;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
Serial.&lt;span class=&quot;me1&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
Serial.&lt;span class=&quot;me1&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
Serial.&lt;span class=&quot;me1&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;&amp;quot;msc {&lt;span class=&quot;es1&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;es1&quot;&gt;\n&lt;/span&gt;hscale = &lt;span class=&quot;es1&quot;&gt;\&amp;quot;&lt;/span&gt;2&lt;span class=&quot;es1&quot;&gt;\&amp;quot;&lt;/span&gt;;&lt;span class=&quot;es1&quot;&gt;\n&lt;/span&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
Serial.&lt;span class=&quot;me1&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;InnermostStates&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
Serial.&lt;span class=&quot;me1&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
Serial.&lt;span class=&quot;me1&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;
Figure 4: The initialise code executed once after reset to print the header of the &lt;code&gt;Scmgen&lt;/code&gt; file
&lt;/p&gt;

&lt;p&gt;
Then the code loops forever waiting for events to process (line 115). Whenever a transition is available we simply “ask” the state machine before it is executed what the current state is (line 127). Then the machine gets executed (line 131) and we ask again, what the current state is in the case the event was processed (line 134ff). In the case the event was not processed it is shown too in the diagram (line 140ff). See below the source code lines.
&lt;/p&gt;

&lt;p&gt;
&lt;a href=&quot;https://sinelabore.com/lib/exe/detail.php/wiki/toolbox/scgen_code.png?id=wiki%3Atoolbox%3Atrace-the-event-flow&quot; class=&quot;media&quot; title=&quot;wiki:toolbox:scgen_code.png&quot;&gt;&lt;img src=&quot;https://sinelabore.com/lib/exe/fetch.php/wiki/toolbox/scgen_code.png&quot; class=&quot;mediacenter&quot; loading=&quot;lazy&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;
Figure 5: Manually written code generating the input for the &lt;code&gt;Mscgen&lt;/code&gt; tool. This can be reused for each project again. 
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Step 2: Writing the Mscgen text to the serial line&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;step_2writing_the_mscgen_text_to_the_serial_line&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:2,&amp;quot;secid&amp;quot;:3,&amp;quot;range&amp;quot;:&amp;quot;2690-3874&amp;quot;} --&gt;
&lt;h3 class=&quot;sectionedit4&quot; id=&quot;step_3receiving_the_text_on_pc_side_and_generate_the_image&quot;&gt;Step 3: Receiving the text on PC side and generate the image&lt;/h3&gt;
&lt;div class=&quot;level3&quot;&gt;

&lt;p&gt;
There are many possibilities to realize the PC side software. The most basic way is to use a simple terminal program and paste the received trace code in a file. Then the file can be converted into an image like shown here:
&lt;/p&gt;
&lt;pre class=&quot;code bash&quot;&gt;mscgen &lt;span class=&quot;re5&quot;&gt;-T&lt;/span&gt; png &lt;span class=&quot;re5&quot;&gt;-i&lt;/span&gt; sc.sc &lt;span class=&quot;re5&quot;&gt;-o&lt;/span&gt; sc.png&lt;/pre&gt;

&lt;p&gt;
Figure 6: Flow diagram generation using &lt;code&gt;Mscgen&lt;/code&gt;.
&lt;/p&gt;

&lt;p&gt;
Another more comfortable way is to automatically save the received trace text into a file whenever a magic pattern is received from the embedded system (i.e. after restart). The following code realises this as a showcase and was tested on &lt;abbr title=&quot;Operating System&quot;&gt;OS&lt;/abbr&gt;-X but should also work on Linux. Full source code is available &lt;a href=&quot;https://sinelabore.com/lib/exe/fetch.php/wiki/toolbox/main.c&quot; class=&quot;media mediafile mf_c&quot; title=&quot;wiki:toolbox:main.c (2.9 KB)&quot;&gt;here&lt;/a&gt;.
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Step 3: Receiving the text on PC side and generate the image&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;step_3receiving_the_text_on_pc_side_and_generate_the_image&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:3,&amp;quot;secid&amp;quot;:4,&amp;quot;range&amp;quot;:&amp;quot;3875-4615&amp;quot;} --&gt;
&lt;h2 class=&quot;sectionedit5&quot; id=&quot;conclusions&quot;&gt;Conclusions&lt;/h2&gt;
&lt;div class=&quot;level2&quot;&gt;

&lt;p&gt;
With the help of the automatically generated trace code and a few lines of code it is possible to generate the required input for &lt;code&gt;Mscgen&lt;/code&gt;. &lt;code&gt;Mscgen&lt;/code&gt; then creates nice looking images showing the event flow in a very clearly arranged way. Hopefully this will help you to track down problems more easily in future. 
&lt;/p&gt;

&lt;p&gt;
Beside finding problems this is also a nice tool to document the behaviour of a system for defined sequences of events, specific test case etc.
&lt;/p&gt;

&lt;p&gt;
Finally let me recommend the two following articles which provide interesting insights into model based testing of state machines and how Sinelabore&lt;em&gt;RT&lt;/em&gt; can support you in this task.
&lt;/p&gt;
&lt;ul&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; &lt;a href=&quot;https://sinelabore.com/doku.php/wiki/toolbox/model-based_testing_of_state_machines_i&quot; class=&quot;wikilink1&quot; title=&quot;wiki:toolbox:model-based_testing_of_state_machines_i&quot; data-wiki-id=&quot;wiki:toolbox:model-based_testing_of_state_machines_i&quot;&gt;Model based testing of state machines part I&lt;/a&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; &lt;a href=&quot;https://sinelabore.com/doku.php/wiki/toolbox/model-based_testing_of_state_machines_ii&quot; class=&quot;wikilink1&quot; title=&quot;wiki:toolbox:model-based_testing_of_state_machines_ii&quot; data-wiki-id=&quot;wiki:toolbox:model-based_testing_of_state_machines_ii&quot;&gt; Model based testing of state machines part II&lt;/a&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
Have fun!
Peter
&lt;/p&gt;

&lt;p&gt;
~~DISCUSSION|Leave your comments~~
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Conclusions&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;conclusions&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:4,&amp;quot;secid&amp;quot;:5,&amp;quot;range&amp;quot;:&amp;quot;4616-&amp;quot;} --&gt;</description>
            <author>anonymous@undisclosed.example.com (Anonymous)</author>
            <pubDate>Sat, 13 Nov 2021 13:33:48 +0000</pubDate>
        </item>
        <item>
            <title>Using State-Machines in Low-Power Embedded Systems - Part II</title>
            <link>https://sinelabore.com/doku.php/wiki/toolbox/using_state_machines_in_low-power_embedded_systems_part_ii</link>
            <description>
&lt;h1 class=&quot;sectionedit1&quot; id=&quot;using_state-machines_in_low-power_embedded_systems_-_part_ii&quot;&gt;Using State-Machines in Low-Power Embedded Systems - Part II&lt;/h1&gt;
&lt;div class=&quot;level1&quot;&gt;

&lt;p&gt;
In the last part I&amp;#039;ve described a basic system design based on &lt;strong&gt;state machines&lt;/strong&gt;, &lt;strong&gt;timers&lt;/strong&gt; and &lt;strong&gt;queues&lt;/strong&gt;. In this short update I extend the existing design with a radio transmitting the measured temperature to a central server. The updated hardware diagram looks as follows:
&lt;/p&gt;

&lt;p&gt;
&lt;a href=&quot;https://sinelabore.com/lib/exe/detail.php/wiki/news/feb2015schematics.png?id=wiki%3Atoolbox%3Ausing_state_machines_in_low-power_embedded_systems_part_ii&quot; class=&quot;media&quot; title=&quot;wiki:news:feb2015schematics.png&quot;&gt;&lt;img src=&quot;https://sinelabore.com/lib/exe/fetch.php/wiki/news/feb2015schematics.png&quot; class=&quot;media&quot; loading=&quot;lazy&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;
One new hardware signal is the &lt;code&gt;/RTS&lt;/code&gt; line indicating readiness of the radio. The other one is an output signal to drive the radio into &lt;code&gt;sleep mode&lt;/code&gt; and back into &lt;code&gt;active&lt;/code&gt; mode.
&lt;/p&gt;

&lt;p&gt;
The updated state machine works as follows. To keep the battery driven system running as long as possible the radio is in low-power mode most of the time. Only just before sending the µC wakes-up the radio in &lt;code&gt;Step2a&lt;/code&gt;. The falling edge of the &lt;code&gt;/RTS&lt;/code&gt; signal indicates the radio readiness which leads into &lt;code&gt;Step2&lt;/code&gt;. In &lt;code&gt;Step2&lt;/code&gt; transmission takes place on interrupt basis (started by putchar()). During transmission &lt;code&gt;/RTS&lt;/code&gt; is high. If transmission is over &lt;code&gt;/RTS&lt;/code&gt; goes to low again. If this happens the radio is switched off again. In case transmission couldn’t completed the radio is switched off latest after 200ms. In &lt;code&gt;Step3&lt;/code&gt; we wait for 5s then the board signals the successful transmission with a short blink code (state &lt;code&gt;BlinkGood&lt;/code&gt;). An then the cycle begins again. Output PORT1/Bit1 is used for debugging purposes. In low power mode just the LED blinks two times slowly to indicate low battery.
&lt;/p&gt;

&lt;p&gt;
&lt;a href=&quot;https://sinelabore.com/lib/exe/detail.php/wiki/news/feb2015_toggle.png?id=wiki%3Atoolbox%3Ausing_state_machines_in_low-power_embedded_systems_part_ii&quot; class=&quot;media&quot; title=&quot;wiki:news:feb2015_toggle.png&quot;&gt;&lt;img src=&quot;https://sinelabore.com/lib/exe/fetch.php/wiki/news/feb2015_toggle.png&quot; class=&quot;media&quot; loading=&quot;lazy&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;
To feed in the /RTS signal into the state machine a new interrupt handler was added as shown below:
&lt;/p&gt;
&lt;pre class=&quot;code c&quot;&gt;&lt;span class=&quot;co2&quot;&gt;#pragma vector=PORT2_VECTOR&lt;/span&gt;
__interrupt &lt;span class=&quot;kw4&quot;&gt;void&lt;/span&gt; Port_2&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;kw4&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
	&lt;span class=&quot;kw1&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;fifoPut&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;&amp;amp;&lt;/span&gt;buf1&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; evFallingEdgeRTS&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
		globalErrHandler&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;co1&quot;&gt;// buffer full&lt;/span&gt;
	&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;&lt;span class=&quot;kw1&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
		P2IFG &lt;span class=&quot;sy0&quot;&gt;&amp;amp;=&lt;/span&gt; ~RADIO_RTS&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
		disableRtsIRQ&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
		&lt;span class=&quot;co1&quot;&gt;// wake up main routine to process state machines&lt;/span&gt;
		__bic_SR_register_on_exit&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;LPM3_bits&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;
Listing 1: The falling edge event is put into the fifo queue. The state machine takes out event by event from that queue processing the events.
&lt;/p&gt;

&lt;p&gt;
The main part of the UART code is the &lt;code&gt;putchar()&lt;/code&gt; function and the transmit interrupt.
&lt;/p&gt;
&lt;pre class=&quot;code c&quot;&gt;&lt;span class=&quot;co1&quot;&gt;// Send a character via serial interface. If no transmission is running&lt;/span&gt;
&lt;span class=&quot;co1&quot;&gt;// the character is directly put into the tx register, otherwise enqueued.&lt;/span&gt;
&lt;span class=&quot;kw4&quot;&gt;void&lt;/span&gt; &lt;a href=&quot;http://www.opengroup.org/onlinepubs/009695399/functions/putchar.html&quot;&gt;&lt;span class=&quot;kw3&quot;&gt;putchar&lt;/span&gt;&lt;/a&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;kw4&quot;&gt;uint8_t&lt;/span&gt; cByte&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
	TX_INT_DISABLE&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;co1&quot;&gt;// disable transmit interrupt (in IE2)&lt;/span&gt;
	&lt;span class=&quot;kw1&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;fifoIsEmpty&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;&amp;amp;&lt;/span&gt;txbuf&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;!&lt;/span&gt;txrunning&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt; &lt;span class=&quot;co1&quot;&gt;// queue empty and no transmission running&lt;/span&gt;
	    txrunning&lt;span class=&quot;sy0&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;kw2&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
	    TXBUF0 &lt;span class=&quot;sy0&quot;&gt;=&lt;/span&gt; cByte&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;co1&quot;&gt;// load tx register, inc index&lt;/span&gt;
	&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;&lt;span class=&quot;kw1&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
		fifoPut&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;&amp;amp;&lt;/span&gt;txbuf&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; cByte&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;
	TX_INT_ENABLE&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;co1&quot;&gt;// enable interrupt (in IE2)&lt;/span&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;
&amp;nbsp;
&amp;nbsp;
&amp;nbsp;
&lt;span class=&quot;co1&quot;&gt;// UART0 TX ISR. &lt;/span&gt;
&lt;span class=&quot;co1&quot;&gt;// The isr takes out the next char from the fifo.&lt;/span&gt;
&lt;span class=&quot;co2&quot;&gt;#pragma vector=USART0TX_VECTOR&lt;/span&gt;
__interrupt &lt;span class=&quot;kw4&quot;&gt;void&lt;/span&gt; usart0_tx &lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;kw4&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
&amp;nbsp;
	&lt;span class=&quot;kw4&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kw4&quot;&gt;uint8_t&lt;/span&gt; txchar&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&amp;nbsp;
	bool empty &lt;span class=&quot;sy0&quot;&gt;=&lt;/span&gt; fifoGet&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;&amp;amp;&lt;/span&gt;txbuf&lt;span class=&quot;sy0&quot;&gt;,&amp;amp;&lt;/span&gt;txchar&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
	_EINT&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;kw1&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;!&lt;/span&gt;empty&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
		TXBUF0 &lt;span class=&quot;sy0&quot;&gt;=&lt;/span&gt; txchar&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;&lt;span class=&quot;kw1&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;&lt;span class=&quot;co1&quot;&gt;// buffer empty, nothing to do&lt;/span&gt;
		txrunning&lt;span class=&quot;sy0&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;kw2&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
	&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;
The updated state machine design was created with the built-in state machine editor of Sinelabore&lt;em&gt;RT&lt;/em&gt;. The reason is simple: I wanted to use the development environment CCS from Texas Instruments on Linux. And Cadifra is only available on Windows. But this was no problem because every state machine can be automatically migrated to the internal editor.
Those of you not knowing CCS should really take a look on it. It has some really cool features - e.g. the power measurement option to just name one.
&lt;/p&gt;

&lt;p&gt;
Let me know if you are interested in the complete source code or need more explanation.
&lt;/p&gt;
&lt;div class=&quot;tags&quot;&gt;&lt;span&gt;
	&lt;a href=&quot;https://sinelabore.com/doku.php/tag/msp430?do=showtag&amp;amp;tag=%5BMSP430&quot; class=&quot;wikilink1&quot; title=&quot;tag:msp430&quot; rel=&quot;tag&quot;&gt;[MSP430&lt;/a&gt;,
	&lt;a href=&quot;https://sinelabore.com/doku.php/tag/application_example?do=showtag&amp;amp;tag=Application_Example%5D&quot; class=&quot;wikilink1&quot; title=&quot;tag:application_example&quot; rel=&quot;tag&quot;&gt;Application Example]&lt;/a&gt;
&lt;/span&gt;&lt;/div&gt;

&lt;/div&gt;
</description>
            <author>anonymous@undisclosed.example.com (Anonymous)</author>
            <pubDate>Sun, 25 Sep 2022 09:52:31 +0000</pubDate>
        </item>
        <item>
            <title>Using State-Machines in Low-Power Embedded Systems</title>
            <link>https://sinelabore.com/doku.php/wiki/toolbox/using_state_machines_in_low-power_embedded_systems</link>
            <description>
&lt;h1 class=&quot;sectionedit1&quot; id=&quot;using_state-machines_in_low-power_embedded_systems&quot;&gt;Using State-Machines in Low-Power Embedded Systems&lt;/h1&gt;
&lt;div class=&quot;level1&quot;&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Using State-Machines in Low-Power Embedded Systems&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;using_state-machines_in_low-power_embedded_systems&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:0,&amp;quot;secid&amp;quot;:1,&amp;quot;range&amp;quot;:&amp;quot;1-65&amp;quot;} --&gt;
&lt;h2 class=&quot;sectionedit2&quot; id=&quot;introduction&quot;&gt;Introduction&lt;/h2&gt;
&lt;div class=&quot;level2&quot;&gt;

&lt;p&gt;
I got requests from time to time asking how to integrate state-machines in a specific system design. Usually I can only give some general advice. But I like to present some design principles here which are hopefully useful for developers of deeply embedded systems in general and those of low power systems in particular. 
&lt;/p&gt;

&lt;p&gt;
The CPU in a low power system is usually only active from time to time to react on events triggered from outside (e.g. a pressed key) or triggered from inside the system (e.g. ADC ready, timer expired). After processing the event the CPU goes into low power mode again. 
&lt;/p&gt;

&lt;p&gt;
All this is done to keep the batteries running as long as possible. A good example for such a system is a wireless temperature sensor mounted outside the window sending temperature data from time to time to a central display, or a monitor attached to a bird to track the flight route or a bike computer etc. The longer the batteries last, the better. 
&lt;/p&gt;

&lt;p&gt;
But also systems connected to power all the time might benefit from a low-power design. Power consumption of a device is a real buying criteria nowadays.
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Introduction&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;introduction&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:0,&amp;quot;secid&amp;quot;:2,&amp;quot;range&amp;quot;:&amp;quot;66-1196&amp;quot;} --&gt;
&lt;h2 class=&quot;sectionedit3&quot; id=&quot;system_design&quot;&gt;System Design&lt;/h2&gt;
&lt;div class=&quot;level2&quot;&gt;

&lt;p&gt;
The following example is based on a small MSP430F1232 header board with just 256 bytes of RAM and 8K of program memory. For the development the Code Composer Studio from TI was used. At the end the program needs &amp;lt;2k Flash and 182 bytes RAM incl. stack. The following block diagram shows the controller with its I/O connections.
&lt;/p&gt;

&lt;p&gt;
&lt;img src=&quot;https://sinelabore.com/lib/exe/fetch.php/wiki/news/jan2015_schematics.png&quot; class=&quot;mediacenter&quot; loading=&quot;lazy&quot; alt=&quot;&quot; /&gt;
Figure 1: MSP430F1232 block diagram
&lt;/p&gt;

&lt;p&gt;
To not hide the design principles behind too much details the uC runs just two state machines fully generated from &lt;abbr title=&quot;Unified Modeling Language&quot;&gt;UML&lt;/abbr&gt; state diagrams. One machine is measuring the battery voltage every 2 seconds. The other one measures the temperature also on a cyclic basis using a TMP100 from TI connected via I2C to the uC. Temperature measurement happens only if battery voltage is high enough. Otherwise a LED is pulsed to indicate low voltage state (P1.3). The radio part which sends the temperature to a central server was omitted here.
&lt;/p&gt;

&lt;p&gt;
The two state machines realizing the user application are shown in figure 2 below. The state machines were designed with the built-in Java &lt;abbr title=&quot;Unified Modeling Language&quot;&gt;UML&lt;/abbr&gt; editor. To change or extend the functionality just modify the state machines, regenerate the state-machine code and then compile and link as usual. Changes on I/O port 1 were added to verify the timing via oscilloscope (see below).
&lt;/p&gt;

&lt;p&gt;
&lt;img src=&quot;https://sinelabore.com/lib/exe/fetch.php/wiki/news/jan2015_pwr.png&quot; class=&quot;mediacenter&quot; loading=&quot;lazy&quot; alt=&quot;&quot; /&gt;
&lt;img src=&quot;https://sinelabore.com/lib/exe/fetch.php/wiki/news/jan2015_toggle.png&quot; class=&quot;mediacenter&quot; loading=&quot;lazy&quot; alt=&quot;&quot; /&gt;
Figure 2: Application logic implemented as state machines. Top: Triggering the voltage measurement with a cyclic timeout. Bottom: Switching between two operation modes depending on supply voltage level. Single-shot timers are used for timing. 
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;System Design&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;system_design&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:0,&amp;quot;secid&amp;quot;:3,&amp;quot;range&amp;quot;:&amp;quot;1197-2872&amp;quot;} --&gt;
&lt;h2 class=&quot;sectionedit4&quot; id=&quot;reusable_library_layer&quot;&gt;Reusable Library Layer&lt;/h2&gt;
&lt;div class=&quot;level2&quot;&gt;

&lt;p&gt;
The design is based on the following library elements which can be reused from project to project:
&lt;/p&gt;
&lt;ul&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; A timer abstraction layer provides timers for the user application. The timer abstraction is based on a system tick realized with hardware &lt;code&gt;timer A&lt;/code&gt; here. If a timer has expired the &lt;code&gt;tick()&lt;/code&gt; routine returns &lt;code&gt;true&lt;/code&gt; and the CPU is woken-up. Otherwise the low power mode is entered again.&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;code c&quot;&gt;__interrupt &lt;span class=&quot;kw4&quot;&gt;void&lt;/span&gt; Timer_A0&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;kw4&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
  bool retVal&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
  P1OUT &lt;span class=&quot;sy0&quot;&gt;^=&lt;/span&gt; BIT0&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;        &lt;span class=&quot;co1&quot;&gt;// toggling bit for debugging&lt;/span&gt;
  retVal &lt;span class=&quot;sy0&quot;&gt;=&lt;/span&gt; tick&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;    &lt;span class=&quot;co1&quot;&gt;// timer service. Check if any timer has expired&lt;/span&gt;
&amp;nbsp;
  &lt;span class=&quot;kw1&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;retVal&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
    &lt;span class=&quot;co1&quot;&gt;// at least one timeout timer fired.&lt;/span&gt;
    &lt;span class=&quot;co1&quot;&gt;// wake up main loop&lt;/span&gt;
    __bic_SR_register_on_exit&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;LPM0_bits&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt; 
  &lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;
Listing 1: Timer interrupt service routine calling the timer handler &lt;em&gt;tick()&lt;/em&gt;.
&lt;/p&gt;
&lt;ul&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; The user code can create multiple timers and receive time-out events in case they expire. During timer creation the event queue and the timer event has to be provided. If a timer expires this event will be stored in the given event queue. The timer implementation can be found in the &lt;code&gt;library&lt;/code&gt; folder in files &lt;code&gt;timer.c&lt;/code&gt; and &lt;code&gt;timer.h&lt;/code&gt;. The &lt;code&gt;tick()&lt;/code&gt; function is the core of the timer library and shown below:&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;code c&quot;&gt;bool tick&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;kw4&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
  bool timeoutAvailable&lt;span class=&quot;sy0&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;kw2&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&amp;nbsp;
  &lt;span class=&quot;co1&quot;&gt;// Iterate over the timers and enque&lt;/span&gt;
  &lt;span class=&quot;co1&quot;&gt;// timer events once a timeout has happend.&lt;/span&gt;
  &lt;span class=&quot;kw1&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;kw4&quot;&gt;uint8_t&lt;/span&gt; i&lt;span class=&quot;sy0&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nu0&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt; i&lt;span class=&quot;sy0&quot;&gt;&amp;lt;&lt;/span&gt;MAX_TIMERS&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt; i&lt;span class=&quot;sy0&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
&amp;nbsp;
    &lt;span class=&quot;kw1&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;timers&lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;i&lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt;.&lt;span class=&quot;me1&quot;&gt;timerStatus&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;==&lt;/span&gt;ON&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
&amp;nbsp;
      timers&lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;i&lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt;.&lt;span class=&quot;me1&quot;&gt;elapsedTicksSinceStart&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;++;&lt;/span&gt;
&amp;nbsp;
      &lt;span class=&quot;kw1&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;timers&lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;i&lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt;.&lt;span class=&quot;me1&quot;&gt;elapsedTicksSinceStart&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;==&lt;/span&gt;timers&lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;i&lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt;.&lt;span class=&quot;me1&quot;&gt;preset&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
        &lt;span class=&quot;co1&quot;&gt;// timeout time elapsed.&lt;/span&gt;
        timers&lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;i&lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt;.&lt;span class=&quot;me1&quot;&gt;timerStatus&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;=&lt;/span&gt;OFF&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;co1&quot;&gt;// stop timer&lt;/span&gt;
        fifoPut&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;timers&lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;i&lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt;.&lt;span class=&quot;me1&quot;&gt;rbuf&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; timers&lt;span class=&quot;br0&quot;&gt;&amp;#91;&lt;/span&gt;i&lt;span class=&quot;br0&quot;&gt;&amp;#93;&lt;/span&gt;.&lt;span class=&quot;me1&quot;&gt;evTimeout&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;co1&quot;&gt;// enqueue timeout event&lt;/span&gt;
        timeoutAvailable&lt;span class=&quot;sy0&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;kw2&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;
    &lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;
  &lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;
&amp;nbsp;
  &lt;span class=&quot;kw1&quot;&gt;return&lt;/span&gt; timeoutAvailable&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;
&amp;nbsp;
&amp;nbsp;
&lt;span class=&quot;co1&quot;&gt;// starts timer&lt;/span&gt;
&lt;span class=&quot;co1&quot;&gt;// Returns either ON if started or OFF if not started (e.g. preset=0)&lt;/span&gt;
TIMER_STATE_T timerStart&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;kw4&quot;&gt;uint8_t&lt;/span&gt; t_id&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kw4&quot;&gt;uint16_t&lt;/span&gt; ticks&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&amp;nbsp;
&lt;span class=&quot;co1&quot;&gt;// stops timer&lt;/span&gt;
&lt;span class=&quot;kw4&quot;&gt;void&lt;/span&gt; timerStop&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;kw4&quot;&gt;uint8_t&lt;/span&gt; t_id&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&amp;nbsp;
&lt;span class=&quot;co1&quot;&gt;// either returns ON or OFF or PAUSE&lt;/span&gt;
TIMER_STATE_T timerStatus&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;kw4&quot;&gt;uint8_t&lt;/span&gt; t_id&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&amp;nbsp;
&lt;span class=&quot;co1&quot;&gt;// set timer timeout in ticks&lt;/span&gt;
&lt;span class=&quot;kw4&quot;&gt;void&lt;/span&gt; timerSet&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;kw4&quot;&gt;uint8_t&lt;/span&gt; t_id&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;kw4&quot;&gt;uint16_t&lt;/span&gt; ticks&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&amp;nbsp;
&lt;span class=&quot;co1&quot;&gt;// Timer function to be called from the timer irq handler.&lt;/span&gt;
&lt;span class=&quot;co1&quot;&gt;// If at least on timer fired the function returns 1. Otherwise 0.&lt;/span&gt;
bool tick&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;kw4&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&amp;nbsp;
&lt;span class=&quot;co1&quot;&gt;// pause timer&lt;/span&gt;
&lt;span class=&quot;kw4&quot;&gt;void&lt;/span&gt; timerPause&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;kw4&quot;&gt;uint8_t&lt;/span&gt; t_id&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&amp;nbsp;
&lt;span class=&quot;co1&quot;&gt;// resume timer&lt;/span&gt;
&lt;span class=&quot;kw4&quot;&gt;void&lt;/span&gt; timerCont&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;kw4&quot;&gt;uint8_t&lt;/span&gt; t_id&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&amp;nbsp;
&lt;span class=&quot;co1&quot;&gt;// Not yet implemented&lt;/span&gt;
&lt;span class=&quot;kw4&quot;&gt;void&lt;/span&gt; timerErase&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;kw4&quot;&gt;uint8_t&lt;/span&gt; t_id&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;
Listing 2: The timer interface and the tick handler. The tick handler is checking if any timer has elapsed. In this case the user provided event is stored in the corresponding queue.
&lt;/p&gt;
&lt;ul&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; A queue service. Queues are used to store events from timers or other event sources in fifo order. Multiple queues can be created usually one per state-machine. The queue code is available in the &lt;code&gt;library&lt;/code&gt;  folder in files &lt;code&gt;ringbuf.c&lt;/code&gt; and &lt;code&gt;ringbuf.h&lt;/code&gt;.&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;code c&quot;&gt;&lt;span class=&quot;kw4&quot;&gt;typedef&lt;/span&gt; &lt;span class=&quot;kw4&quot;&gt;struct&lt;/span&gt; Buffer &lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
    &lt;span class=&quot;kw4&quot;&gt;uint8_t&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;*&lt;/span&gt;data&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;kw4&quot;&gt;uint8_t&lt;/span&gt; mask&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;co1&quot;&gt;// size - 1&lt;/span&gt;
    &lt;span class=&quot;kw4&quot;&gt;uint8_t&lt;/span&gt; read&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;co1&quot;&gt;// index of oldest element&lt;/span&gt;
    &lt;span class=&quot;kw4&quot;&gt;uint8_t&lt;/span&gt; write&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;co1&quot;&gt;// index of field to write to&lt;/span&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt; FIFO_T&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&amp;nbsp;
&lt;span class=&quot;kw4&quot;&gt;void&lt;/span&gt; fifoInit&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;FIFO_T &lt;span class=&quot;sy0&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;kw4&quot;&gt;const&lt;/span&gt; buffer&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kw4&quot;&gt;uint8_t&lt;/span&gt;  &lt;span class=&quot;sy0&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;kw4&quot;&gt;const&lt;/span&gt; pByte&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kw4&quot;&gt;uint8_t&lt;/span&gt; size&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
bool fifoPut&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;FIFO_T &lt;span class=&quot;sy0&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;kw4&quot;&gt;const&lt;/span&gt; buffer&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kw4&quot;&gt;uint8_t&lt;/span&gt; byte&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
bool fifoGet&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;FIFO_T  &lt;span class=&quot;sy0&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;kw4&quot;&gt;const&lt;/span&gt; buffer&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kw4&quot;&gt;uint8_t&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;kw4&quot;&gt;const&lt;/span&gt; pByte&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
bool fifoPutHead&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;FIFO_T &lt;span class=&quot;sy0&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;kw4&quot;&gt;const&lt;/span&gt; buffer&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt;  &lt;span class=&quot;kw4&quot;&gt;uint8_t&lt;/span&gt; byte&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
bool fifoIsEmpty&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;kw4&quot;&gt;const&lt;/span&gt; FIFO_T &lt;span class=&quot;sy0&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;kw4&quot;&gt;const&lt;/span&gt; buffer&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;
Listing 3: The queue interface. Multiple queues can exist. A state machine usually has one input queue to pick the next event from.
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Reusable Library Layer&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;reusable_library_layer&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:0,&amp;quot;secid&amp;quot;:4,&amp;quot;range&amp;quot;:&amp;quot;2873-6439&amp;quot;} --&gt;
&lt;h2 class=&quot;sectionedit5&quot; id=&quot;weaving_the_state_machines_and_the_library_part_together&quot;&gt;Weaving the state machines and the library part together&lt;/h2&gt;
&lt;div class=&quot;level2&quot;&gt;

&lt;p&gt;
On top of the minimal abstraction layer (timers, queues) the application specific part is located. It is implemented as state-machines reacting on the events. The state machine code is fully generated. All is generated from the &lt;abbr title=&quot;Unified Modeling Language&quot;&gt;UML&lt;/abbr&gt; state machine diagrams. The main routine initializes the hardware and then enters a main-loop waiting in low-power mode. ADC and timer iqr handlers wake-up the CPU after they enqueued an event. When woken-up the main loop pulls out these events and calls the appropriate state-machine with the event as parameter. See the following code snippet for the implementation details:
&lt;/p&gt;
&lt;pre class=&quot;code c&quot;&gt;&lt;span class=&quot;coMULTI&quot;&gt;/**
 * Main loop initializes the hardware and software
 * and then waits in low power mode until new events
 * are present. Events are then pulled out of the
 * queues and forwareded to the apropriate state-machine.
 */&lt;/span&gt;
&lt;span class=&quot;kw4&quot;&gt;void&lt;/span&gt; main&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt; &lt;span class=&quot;kw4&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
  &lt;span class=&quot;co1&quot;&gt;// Stop watchdog timer to prevent time out reset&lt;/span&gt;
  WDTCTL &lt;span class=&quot;sy0&quot;&gt;=&lt;/span&gt; WDTPW &lt;span class=&quot;sy0&quot;&gt;+&lt;/span&gt; WDTHOLD&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&amp;nbsp;
  &lt;span class=&quot;co1&quot;&gt;// initialize timer &lt;/span&gt;
  TACCTL0 &lt;span class=&quot;sy0&quot;&gt;|=&lt;/span&gt; CCIE&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;                           &lt;span class=&quot;co1&quot;&gt;// CCR0 interrupt enabled&lt;/span&gt;
  TACCR0 &lt;span class=&quot;sy0&quot;&gt;=&lt;/span&gt;  41U&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
  TACTL &lt;span class=&quot;sy0&quot;&gt;=&lt;/span&gt; TASSEL_1 &lt;span class=&quot;sy0&quot;&gt;+&lt;/span&gt; MC_1 &lt;span class=&quot;sy0&quot;&gt;+&lt;/span&gt; ID_3&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;           &lt;span class=&quot;co1&quot;&gt;// SMCLK/8, upmode  &lt;/span&gt;
&amp;nbsp;
&amp;nbsp;
  P1OUT &lt;span class=&quot;sy0&quot;&gt;&amp;amp;=&lt;/span&gt; 0x00U&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;               &lt;span class=&quot;co1&quot;&gt;// Shut down everything&lt;/span&gt;
  P1DIR &lt;span class=&quot;sy0&quot;&gt;&amp;amp;=&lt;/span&gt; 0x00U&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
  P1DIR &lt;span class=&quot;sy0&quot;&gt;|=&lt;/span&gt; BIT0 &lt;span class=&quot;sy0&quot;&gt;+&lt;/span&gt; BIT1&lt;span class=&quot;sy0&quot;&gt;+&lt;/span&gt;BIT2&lt;span class=&quot;sy0&quot;&gt;+&lt;/span&gt;BIT3&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;       &lt;span class=&quot;co1&quot;&gt;// set pins to output the rest are input&lt;/span&gt;
  P1OUT &lt;span class=&quot;sy0&quot;&gt;|=&lt;/span&gt; BIT1 &lt;span class=&quot;sy0&quot;&gt;+&lt;/span&gt; BIT1&lt;span class=&quot;sy0&quot;&gt;+&lt;/span&gt;BIT2&lt;span class=&quot;sy0&quot;&gt;+&lt;/span&gt;BIT3&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;         &lt;span class=&quot;co1&quot;&gt;//Select pull-up mode&lt;/span&gt;
&amp;nbsp;
  fifoInit&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;&amp;amp;&lt;/span&gt;buf1&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; buf1data &lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;kw4&quot;&gt;sizeof&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;buf1data&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;kw4&quot;&gt;sizeof&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;kw4&quot;&gt;uint8_t&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
  fifoInit&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;&amp;amp;&lt;/span&gt;buf2&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; buf2data &lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;kw4&quot;&gt;sizeof&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;buf2data&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;kw4&quot;&gt;sizeof&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;kw4&quot;&gt;uint8_t&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&amp;nbsp;
  timerInit&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
  init_uart&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
  radio_init&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
  initWindSensor&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&amp;nbsp;
  &lt;span class=&quot;co1&quot;&gt;// run once to init&lt;/span&gt;
  toggle&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;&amp;amp;&lt;/span&gt;smToggle&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; TOGGLE_NO_MSG&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
  pwr&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;&amp;amp;&lt;/span&gt;smPwr&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; PWR_NO_MSG&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&amp;nbsp;
  &lt;span class=&quot;kw1&quot;&gt;while&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;nu0&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;                      &lt;span class=&quot;co1&quot;&gt;//Loop forever&lt;/span&gt;
&amp;nbsp;
    &lt;span class=&quot;kw4&quot;&gt;uint8_t&lt;/span&gt; retVal&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;kw4&quot;&gt;uint8_t&lt;/span&gt; bufVal&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&amp;nbsp;
    &lt;span class=&quot;kw1&quot;&gt;do&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;                         &lt;span class=&quot;co1&quot;&gt;// first process all events for task A&lt;/span&gt;
      retVal &lt;span class=&quot;sy0&quot;&gt;=&lt;/span&gt; fifoGet&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;&amp;amp;&lt;/span&gt;buf1&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;&amp;amp;&lt;/span&gt;bufVal&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;kw1&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;retVal&lt;span class=&quot;sy0&quot;&gt;!=&lt;/span&gt;QUEUE_EMPTY&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
        toggle&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;&amp;amp;&lt;/span&gt;smToggle&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; bufVal&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;
    &lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;&lt;span class=&quot;kw1&quot;&gt;while&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;retVal&lt;span class=&quot;sy0&quot;&gt;!=&lt;/span&gt;QUEUE_EMPTY&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&amp;nbsp;
    &lt;span class=&quot;kw1&quot;&gt;do&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;                        &lt;span class=&quot;co1&quot;&gt;// then all evenets for task B&lt;/span&gt;
      retVal &lt;span class=&quot;sy0&quot;&gt;=&lt;/span&gt; fifoGet&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;&amp;amp;&lt;/span&gt;buf2&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;sy0&quot;&gt;&amp;amp;&lt;/span&gt;bufVal&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;kw1&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;retVal&lt;span class=&quot;sy0&quot;&gt;!=&lt;/span&gt;QUEUE_EMPTY&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
        pwr&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;&amp;amp;&lt;/span&gt;smPwr&lt;span class=&quot;sy0&quot;&gt;,&lt;/span&gt; bufVal&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
      &lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;
    &lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;&lt;span class=&quot;kw1&quot;&gt;while&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;retVal&lt;span class=&quot;sy0&quot;&gt;!=&lt;/span&gt;QUEUE_EMPTY&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;co1&quot;&gt;// more tasks could follow here&lt;/span&gt;
&amp;nbsp;
    __bis_SR_register&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;LPM3_bits &lt;span class=&quot;sy0&quot;&gt;+&lt;/span&gt; GIE&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;  &lt;span class=&quot;co1&quot;&gt;// Enter low power mode once&lt;/span&gt;
    __no_operation&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;                    &lt;span class=&quot;co1&quot;&gt;// no more events must be processed&lt;/span&gt;
&amp;nbsp;
  &lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;
Listing 4: The main routine waiting in low power mode until events are available. Then these events are forwarded to the state machine handlers.
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Weaving the state machines and the library part together&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;weaving_the_state_machines_and_the_library_part_together&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:3,&amp;quot;secid&amp;quot;:5,&amp;quot;range&amp;quot;:&amp;quot;6440-9011&amp;quot;} --&gt;
&lt;h2 class=&quot;sectionedit6&quot; id=&quot;how_to_treat_with_longer_lasting_tasks&quot;&gt;How to treat with longer lasting tasks&lt;/h2&gt;
&lt;div class=&quot;level2&quot;&gt;

&lt;p&gt;
Execution time for handling events should be as short as possible. Longer lasting tasks should be split into chunks. Take the temperature measurement as an example. The temperature sensor TMP100 requires about 320ms conversion time according to the data sheet. The uC shouldn&amp;#039;t wait and burn CPU cycles but either wait in low-power mode or process other events. This can easily be done by starting the conversion in one state (&lt;code&gt;Step1&lt;/code&gt;) and then start a timer and enter low-power mode. If the timer fires we pick-up the conversion result (&lt;code&gt;Step2&lt;/code&gt;) and process it further.
&lt;/p&gt;

&lt;p&gt;
Another example is the wake-up procedure of the radio. After finishing low-power mode it takes a while before it is ready. Readiness is signalled via a transition of the RTS pin from high to low. After switching on the radio in state &lt;code&gt;Step2a&lt;/code&gt; we enter low-power mode again. The level change creates an irq and sends the event &lt;code&gt;evFallingEdgeRTS&lt;/code&gt;. Now the radio is ready to transmit data. 
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;How to treat with longer lasting tasks&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;how_to_treat_with_longer_lasting_tasks&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:4,&amp;quot;secid&amp;quot;:6,&amp;quot;range&amp;quot;:&amp;quot;9012-10030&amp;quot;} --&gt;
&lt;h2 class=&quot;sectionedit7&quot; id=&quot;object_diagram&quot;&gt;Object Diagram&lt;/h2&gt;
&lt;div class=&quot;level2&quot;&gt;

&lt;p&gt;
The software design  is shown in the next figure as &lt;abbr title=&quot;Unified Modeling Language&quot;&gt;UML&lt;/abbr&gt; object diagram. You can clearly see how the &lt;code&gt;queues decouple the event sources from the event consumers&lt;/code&gt;. The main-loop serves as event dispatcher being only active if events are available in one of the queues. The main loop can also be used to prioritize one state machine over an other or ensure the order in which state machines are executed.
&lt;/p&gt;

&lt;p&gt;
&lt;a href=&quot;https://sinelabore.com/lib/exe/detail.php/wiki/news/jan2015_objdiag.png?id=wiki%3Atoolbox%3Ausing_state_machines_in_low-power_embedded_systems&quot; class=&quot;media&quot; title=&quot;wiki:news:jan2015_objdiag.png&quot;&gt;&lt;img src=&quot;https://sinelabore.com/lib/exe/fetch.php/wiki/news/jan2015_objdiag.png&quot; class=&quot;mediacenter&quot; loading=&quot;lazy&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;
Figure 3: Object diagram of the whole application.
&lt;/p&gt;

&lt;p&gt;
To verify the overall system behavior some output port pins were used as follows:
&lt;/p&gt;
&lt;ul&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; Timer A interrupt routine shown als &lt;code&gt;clk&lt;/code&gt; in the first line. The port pin is inverted in each interrupt i.e. every 100 &lt;em&gt;ms&lt;/em&gt;.&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; The supply voltage goes down. As reaction the measurement stops (line 2) and the power fail LED starts flashing (line 4). The &lt;code&gt;evPowerFail&lt;/code&gt; starts from state &lt;code&gt;Running&lt;/code&gt;. As a result it can happen that the temperature measurement cycle just starts in case a &lt;code&gt;evPowerFail&lt;/code&gt; event happens but can&amp;#039;t finish. You can see this in the oscilloscope image. There is just one peak. To fix this let the &lt;code&gt;evPowerFail&lt;/code&gt; transition start from state &lt;code&gt;Step2&lt;/code&gt;. This would ensure that a measurement cycle always completes before state changes to &lt;code&gt;PowerFail&lt;/code&gt;.&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; Line 3 shows the timing of voltage measurement state machine (cycle of 2 seconds). &lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
&lt;a href=&quot;https://sinelabore.com/lib/exe/detail.php/wiki/news/jan2015_osci.png?id=wiki%3Atoolbox%3Ausing_state_machines_in_low-power_embedded_systems&quot; class=&quot;media&quot; title=&quot;wiki:news:jan2015_osci.png&quot;&gt;&lt;img src=&quot;https://sinelabore.com/lib/exe/fetch.php/wiki/news/jan2015_osci.png&quot; class=&quot;mediacenter&quot; loading=&quot;lazy&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;
Figure 4: Oscilloscope image showing the timing of the whole application. Line 1: system tick. Line 2: timing of the temperature measurement phases. Measurement only happens if the supply voltage is above a defined threshold. Line 2: Supply voltage measurement. Line 3: LED output plus: Analog line: battery voltage.
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Object Diagram&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;object_diagram&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:4,&amp;quot;secid&amp;quot;:7,&amp;quot;range&amp;quot;:&amp;quot;10031-11762&amp;quot;} --&gt;
&lt;h2 class=&quot;sectionedit8&quot; id=&quot;discussion&quot;&gt;Discussion&lt;/h2&gt;
&lt;div class=&quot;level2&quot;&gt;
&lt;ul&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; This article shows the principle concepts for designing low power embedded systems using state-machines, timers and queues.&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; Queues and timers as basic services which are application independent and can be reused from system to system. Timer resolution and number of timers and queues can be adjusted to optimize memory needs.&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; The user application is modeled as state machines receiving events from the outside or inside sources via queues. I.e. decoupling is done with queues.&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; State-machine processing time must be short enough to ensure that no events get lost and overall response time is ensured.&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
The source code is just meant for demonstration purposes. I&amp;#039;m happy to receive suggestions for improvement which I will add and make available for others again. The code composer workspace is available for &lt;a href=&quot;https://sinelabore.com/lib/exe/fetch.php/wiki/news/jan2015_sample_design.zip&quot; class=&quot;media mediafile mf_zip&quot; title=&quot;wiki:news:jan2015_sample_design.zip (91.9 KB)&quot;&gt;download here&lt;/a&gt;.
&lt;/p&gt;

&lt;p&gt;
Hope you enjoyed this article. Let me know your feedback!
&lt;/p&gt;

&lt;p&gt;
Peter Mueller
&lt;/p&gt;
&lt;div class=&quot;tags&quot;&gt;&lt;span&gt;
	&lt;a href=&quot;https://sinelabore.com/doku.php/tag/msp430?do=showtag&amp;amp;tag=%5BMSP430&quot; class=&quot;wikilink1&quot; title=&quot;tag:msp430&quot; rel=&quot;tag&quot;&gt;[MSP430&lt;/a&gt;,
	&lt;a href=&quot;https://sinelabore.com/doku.php/tag/application_example?do=showtag&amp;amp;tag=Application_Example%5D&quot; class=&quot;wikilink1&quot; title=&quot;tag:application_example&quot; rel=&quot;tag&quot;&gt;Application Example]&lt;/a&gt;
&lt;/span&gt;&lt;/div&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Discussion&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;discussion&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:4,&amp;quot;secid&amp;quot;:8,&amp;quot;range&amp;quot;:&amp;quot;11763-&amp;quot;} --&gt;</description>
            <author>anonymous@undisclosed.example.com (Anonymous)</author>
            <pubDate>Sun, 25 Sep 2022 09:51:20 +0000</pubDate>
        </item>
        <item>
            <title>Using Statemachines with the embOS Real-Time Operating System (RTOS)</title>
            <link>https://sinelabore.com/doku.php/wiki/toolbox/using_state-machines_with_a_real-time_operating_system_rtos</link>
            <description>


&lt;h1 class=&quot;sectionedit1&quot; id=&quot;using_statemachines_with_the_embos_real-time_operating_system_rtos&quot;&gt;Using Statemachines with the embOS Real-Time Operating System (RTOS)&lt;/h1&gt;
&lt;div class=&quot;level1&quot;&gt;

&lt;p&gt;
This article shows how to use state charts in the context of a real-time operating system. In this example the WIN32 version of embOS from &lt;a href=&quot;http://www.segger.com/&quot; class=&quot;urlextern&quot; title=&quot;http://www.segger.com/&quot; rel=&quot;ugc nofollow&quot;&gt;Segger&lt;/a&gt; is used as an &lt;abbr title=&quot;Real-Time Operating System&quot;&gt;RTOS&lt;/abbr&gt;. So you can build, modify and run the example yourself!
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Using Statemachines with the embOS Real-Time Operating System (RTOS)&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;using_statemachines_with_the_embos_real-time_operating_system_rtos&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:0,&amp;quot;secid&amp;quot;:1,&amp;quot;range&amp;quot;:&amp;quot;344-676&amp;quot;} --&gt;
&lt;h3 class=&quot;sectionedit2&quot; id=&quot;the_starting_point&quot;&gt;The Starting Point&lt;/h3&gt;
&lt;div class=&quot;level3&quot;&gt;

&lt;p&gt;
System partitioning often requires to run state machines in different tasks, timer handlers or interrupt service routines. The different state machines then typically communicate through interprocess communication mechanisms provided from the operating system such as queues or messages (aka active objects). The following figure shows a fictive system with different active parts and their relation. 
&lt;/p&gt;

&lt;p&gt;
&lt;img src=&quot;https://sinelabore.com/lib/exe/fetch.php/wiki/articles/sm_with_rtos_class_diagram.jpg&quot; class=&quot;mediacenter&quot; loading=&quot;lazy&quot; alt=&quot;&quot; /&gt;
&lt;/p&gt;

&lt;p&gt;
In this example the two blue marked parts (a task and a timer) are modelled as state machines. The Sender periodically sends different events to the Receiver. The receiver task then reacts on the received events. The two state machines are kept simple and just print out some trace messages. But this is enough to understand the design principle.
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;The Starting Point&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;the_starting_point&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:0,&amp;quot;secid&amp;quot;:2,&amp;quot;range&amp;quot;:&amp;quot;677-1518&amp;quot;} --&gt;
&lt;h3 class=&quot;sectionedit3&quot; id=&quot;implementation&quot;&gt;Implementation&lt;/h3&gt;
&lt;div class=&quot;level3&quot;&gt;

&lt;/div&gt;

&lt;h4 id=&quot;step_1modelling_the_sender_receiver_state_machines&quot;&gt;Step 1: Modelling the sender &amp;amp; receiver state machines&lt;/h4&gt;
&lt;div class=&quot;level4&quot;&gt;

&lt;p&gt;
For each state machine an own &lt;abbr title=&quot;Unified Modeling Language&quot;&gt;UML&lt;/abbr&gt; state diagram has to be developed. The diagram for the Receiver is shown first. The two accepted events are ‘ev1’ and ‘ev2’. Whenever an event is received a state change happens. The code provided after the ‘action‘ keyword (right note) is inserted from the code generator at the beginning of the state machine handler. This code reads the next available event from a mailbox, otherwise it blocks. The code following the ‘header‘ keyword (left note) is inserted at the beginning of the generated code. It includes the required header files and declares the needed variables (e.g. the shared mailbox).
&lt;/p&gt;

&lt;p&gt;
&lt;img src=&quot;https://sinelabore.com/lib/exe/fetch.php/wiki/articles/sm_with_rtos_sm_receiver.jpg&quot; class=&quot;mediacenter&quot; loading=&quot;lazy&quot; alt=&quot;&quot; /&gt;
&lt;/p&gt;

&lt;p&gt;
The next diagram shows the sender machine. Whenever the timer fires a state change happens (evTimeout). The action code in the transitions put new messages in the message box. The timer is re-triggered (→ see action code) after each timeout.
&lt;/p&gt;

&lt;p&gt;
&lt;img src=&quot;https://sinelabore.com/lib/exe/fetch.php/wiki/articles/sm_with_rtos_sm_sender.png&quot; class=&quot;mediacenter&quot; loading=&quot;lazy&quot; alt=&quot;&quot; /&gt;
&lt;/p&gt;

&lt;/div&gt;

&lt;h4 id=&quot;step_2integrate_the_state_machines&quot;&gt;Step 2: Integrate the state machines&lt;/h4&gt;
&lt;div class=&quot;level4&quot;&gt;

&lt;p&gt;
In our example the sender state machine is called from within the embOS timer callback function. 
&lt;/p&gt;
&lt;pre class=&quot;code c&quot;&gt;&lt;span class=&quot;co1&quot;&gt;// embOS timeout callback function&lt;/span&gt;
&lt;span class=&quot;kw4&quot;&gt;void&lt;/span&gt; TimerHandler&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;kw4&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
   sender&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;&amp;amp;&lt;/span&gt;sndInst&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;
The receiver state machine is called from the task body.
&lt;/p&gt;
&lt;pre class=&quot;code c&quot;&gt;&lt;span class=&quot;co1&quot;&gt;// receiver task&lt;/span&gt;
&lt;span class=&quot;kw4&quot;&gt;void&lt;/span&gt; Task0&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;kw4&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt; &lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
   &lt;span class=&quot;kw1&quot;&gt;while&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;nu0&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#123;&lt;/span&gt;
       OS_Delay&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;nu0&quot;&gt;50&lt;/span&gt;&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;
       receiver&lt;span class=&quot;br0&quot;&gt;&amp;#40;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;&amp;amp;&lt;/span&gt;recInst&lt;span class=&quot;br0&quot;&gt;&amp;#41;&lt;/span&gt;&lt;span class=&quot;sy0&quot;&gt;;&lt;/span&gt;  &lt;span class=&quot;co1&quot;&gt;// state machine function blocks if no event is available&lt;/span&gt;
   &lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;
&lt;span class=&quot;br0&quot;&gt;&amp;#125;&lt;/span&gt;&lt;/pre&gt;

&lt;p&gt;
Nothing else is required. The generated code does not need any other runtime libraries!
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Implementation&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;implementation&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:0,&amp;quot;secid&amp;quot;:3,&amp;quot;range&amp;quot;:&amp;quot;1519-3198&amp;quot;} --&gt;
&lt;h3 class=&quot;sectionedit4&quot; id=&quot;conclusions&quot;&gt;Conclusions&lt;/h3&gt;
&lt;div class=&quot;level3&quot;&gt;

&lt;p&gt;
As you can see it is quite simple to use generated state machine code in the context of an real-time operating system. It is also possible to run a state machine function from within an interrupt service handler. Checkout the manual on how to set the related generator flags.
&lt;/p&gt;

&lt;p&gt;
To change the state diagram you need the Cadifra &lt;abbr title=&quot;Unified Modeling Language&quot;&gt;UML&lt;/abbr&gt; editor which was used to design the example. Demo versions of Cadifra and the Sinelabore code-generator are available in the download area. To compile the code you  also need the Visual C++ Express Edition from Microsoft. The source code and the executable is provided for download below. After starting the exe the trace output is written to c:\trace.txt. No other output is shown on the screen!
&lt;/p&gt;

&lt;p&gt;
Download the embos example &lt;a href=&quot;https://sinelabore.com/lib/exe/fetch.php/wiki/articles/sm_with_rtos_embos.zip&quot; class=&quot;media mediafile mf_zip&quot; title=&quot;wiki:articles:sm_with_rtos_embos.zip (671.6 KB)&quot;&gt;here&lt;/a&gt;.
&lt;/p&gt;

&lt;p&gt;
~~DISCUSSION|Leave your comments~~
&lt;/p&gt;
&lt;div class=&quot;tags&quot;&gt;&lt;span&gt;
	&lt;a href=&quot;https://sinelabore.com/doku.php/tag/mbos?do=showtag&amp;amp;tag=%5BMBOS&quot; class=&quot;wikilink1&quot; title=&quot;tag:mbos&quot; rel=&quot;tag&quot;&gt;[MBOS&lt;/a&gt;,
	&lt;a href=&quot;https://sinelabore.com/doku.php/tag/rtos?do=showtag&amp;amp;tag=RTOS%5D&quot; class=&quot;wikilink1&quot; title=&quot;tag:rtos&quot; rel=&quot;tag&quot;&gt;RTOS]&lt;/a&gt;
&lt;/span&gt;&lt;/div&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Conclusions&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;conclusions&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:2,&amp;quot;secid&amp;quot;:4,&amp;quot;range&amp;quot;:&amp;quot;3199-&amp;quot;} --&gt;</description>
            <author>anonymous@undisclosed.example.com (Anonymous)</author>
            <pubDate>Wed, 08 Mar 2023 20:07:26 +0000</pubDate>
        </item>
    </channel>
</rss>
