/*! @page q_fsm Finite State Machines (FSM)
* @tableofcontents
*
* @section q_fsm_overview Overview
* The state machine is one of the fundamental programming patterns that are
* most commonly used. This approach breaks down the design into a series of
* finite steps called "states" that perform some narrowly defined actions.
* Every state can change to another as a consequence of incoming stimuli also
* called events or signals. This elemental mechanism allows designers to solve
* complex engineering problems in a very straightforward way. Knowing the
* importance of this approach in the development of embedded applications,
* the OS adopts this design pattern as a kernel extension.
*
* In an effort to maximize efficiency and minimize complexity, the extension
* implements the basic features of the Harel statecharts to represent
* hierarchical state machines. These features form a proper subset that
* approaches in a very minimalist way, some of the specifications of the
* UML statecharts, including:
*
* - Nested states with proper handling of group transitions and group reactions.
* - Guaranteed execution of entry/exit actions upon entering/exiting states.
* - Straightforward transitions and guards.
*
* In addition to this, the provided implementation also features a powerful
* coding abstraction including transition tables and timeout signals, allowing
* to build scalable solutions from simple flat state-machines to complex
* statecharts.
*
* @section qfsm_approach The provided approach
* In QuarkTS++, a state machine must be instantiated with an object of type qOS::stateMachine.
* States are represented as instances of the qOS::sm::state object.
*
* <center>
* @htmlonly
* <!DOCTYPE html>
* <html>
* <head>
* <title>fsmarch++</title>
* <meta charset="utf-8"/>
* </head>
* <body><div class="mxgraph" style="max-width:100%;border:1px solid transparent;" data-mxgraph="{&quot;highlight&quot;:&quot;#0000ff&quot;,&quot;nav&quot;:true,&quot;zoom&quot;:1.5,&quot;resize&quot;:true,&quot;toolbar&quot;:&quot;zoom layers tags lightbox&quot;,&quot;edit&quot;:&quot;_blank&quot;,&quot;xml&quot;:&quot;&lt;mxfile host=\&quot;app.diagrams.net\&quot; modified=\&quot;2023-04-21T05:26:00.192Z\&quot; agent=\&quot;Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36\&quot; etag=\&quot;2kR0i4V1xqM2amiRx-S4\&quot; version=\&quot;21.2.1\&quot; type=\&quot;google\&quot;&gt;\n  &lt;diagram name=\&quot;Página-1\&quot; id=\&quot;G2x3a1t9-ksZxGX4sUb1\&quot;&gt;\n    &lt;mxGraphModel dx=\&quot;615\&quot; dy=\&quot;-344\&quot; grid=\&quot;1\&quot; gridSize=\&quot;10\&quot; guides=\&quot;1\&quot; tooltips=\&quot;1\&quot; connect=\&quot;1\&quot; arrows=\&quot;1\&quot; fold=\&quot;1\&quot; page=\&quot;1\&quot; pageScale=\&quot;1\&quot; pageWidth=\&quot;1169\&quot; pageHeight=\&quot;827\&quot; math=\&quot;0\&quot; shadow=\&quot;0\&quot;&gt;\n      &lt;root&gt;\n        &lt;mxCell id=\&quot;0\&quot; /&gt;\n        &lt;mxCell id=\&quot;1\&quot; parent=\&quot;0\&quot; /&gt;\n        &lt;mxCell id=\&quot;dN6sw1qnDhJNe45-whcC-1\&quot; value=\&quot;&amp;lt;span style=&amp;quot;color: rgb(128, 128, 128); font-family: &amp;amp;quot;Lucida Console&amp;amp;quot;; font-size: 10px; text-align: center;&amp;quot;&amp;gt;&amp;amp;nbsp; (sm::state*)current*&amp;lt;/span&amp;gt;&amp;lt;br style=&amp;quot;color: rgb(128, 128, 128); font-family: &amp;amp;quot;Lucida Console&amp;amp;quot;; font-size: 10px; text-align: center;&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: rgb(128, 128, 128); font-family: &amp;amp;quot;Lucida Console&amp;amp;quot;; font-size: 10px; text-align: center;&amp;quot;&amp;gt;&amp;amp;nbsp; (sm::handler_t)handler&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;/span&amp;gt;\&quot; style=\&quot;rounded=0;whiteSpace=wrap;html=1;strokeColor=#808080;fillColor=none;fontFamily=Helvetica;strokeWidth=2;align=left;\&quot; vertex=\&quot;1\&quot; parent=\&quot;1\&quot;&gt;\n          &lt;mxGeometry x=\&quot;692.57\&quot; y=\&quot;1172.75\&quot; width=\&quot;250\&quot; height=\&quot;130\&quot; as=\&quot;geometry\&quot; /&gt;\n        &lt;/mxCell&gt;\n        &lt;mxCell id=\&quot;dN6sw1qnDhJNe45-whcC-2\&quot; value=\&quot;(stateMachine)FSM\&quot; style=\&quot;rounded=0;whiteSpace=wrap;html=1;strokeColor=#808080;fillColor=#E6E6E6;fontColor=#808080;fontStyle=0;fontFamily=Lucida Console;strokeWidth=2;fontSize=10;\&quot; vertex=\&quot;1\&quot; parent=\&quot;1\&quot;&gt;\n          &lt;mxGeometry x=\&quot;692.57\&quot; y=\&quot;1153.5\&quot; width=\&quot;250\&quot; height=\&quot;20\&quot; as=\&quot;geometry\&quot; /&gt;\n        &lt;/mxCell&gt;\n        &lt;mxCell id=\&quot;dN6sw1qnDhJNe45-whcC-3\&quot; value=\&quot;(sm::state)Top\&quot; style=\&quot;rounded=0;whiteSpace=wrap;html=1;strokeColor=#808080;fillColor=#E6E6E6;fontColor=#808080;fontStyle=0;fontFamily=Lucida Console;strokeWidth=2;fontSize=10;\&quot; vertex=\&quot;1\&quot; parent=\&quot;1\&quot;&gt;\n          &lt;mxGeometry x=\&quot;711.32\&quot; y=\&quot;1228.75\&quot; width=\&quot;126.25\&quot; height=\&quot;20\&quot; as=\&quot;geometry\&quot; /&gt;\n        &lt;/mxCell&gt;\n        &lt;mxCell id=\&quot;dN6sw1qnDhJNe45-whcC-4\&quot; value=\&quot;\&quot; style=\&quot;rounded=0;whiteSpace=wrap;html=1;strokeColor=#808080;fillColor=none;fontFamily=Helvetica;strokeWidth=2;\&quot; vertex=\&quot;1\&quot; parent=\&quot;1\&quot;&gt;\n          &lt;mxGeometry x=\&quot;711.32\&quot; y=\&quot;1248.75\&quot; width=\&quot;126.25\&quot; height=\&quot;44\&quot; as=\&quot;geometry\&quot; /&gt;\n        &lt;/mxCell&gt;\n        &lt;mxCell id=\&quot;dN6sw1qnDhJNe45-whcC-5\&quot; value=\&quot;xCallbackFcn&amp;lt;br&amp;gt;parent*\&quot; style=\&quot;text;html=1;strokeColor=none;fillColor=none;align=left;verticalAlign=middle;whiteSpace=wrap;rounded=0;fillStyle=solid;fontSize=10;fontColor=#808080;fontStyle=0;fontFamily=Lucida Console;\&quot; vertex=\&quot;1\&quot; parent=\&quot;1\&quot;&gt;\n          &lt;mxGeometry x=\&quot;717.8900000000001\&quot; y=\&quot;1252.75\&quot; width=\&quot;109.68\&quot; height=\&quot;30\&quot; as=\&quot;geometry\&quot; /&gt;\n        &lt;/mxCell&gt;\n        &lt;mxCell id=\&quot;dN6sw1qnDhJNe45-whcC-6\&quot; value=\&quot;&amp;lt;span style=&amp;quot;color: rgb(128, 128, 128); font-family: &amp;amp;quot;Lucida Console&amp;amp;quot;; font-size: 10px; text-align: left;&amp;quot;&amp;gt;sm::status OnSignal( sm::handler_t )&amp;lt;/span&amp;gt;\&quot; style=\&quot;rounded=0;whiteSpace=wrap;html=1;strokeColor=#808080;fillColor=none;fontFamily=Helvetica;strokeWidth=2;\&quot; vertex=\&quot;1\&quot; parent=\&quot;1\&quot;&gt;\n          &lt;mxGeometry x=\&quot;692.57\&quot; y=\&quot;1302.75\&quot; width=\&quot;250\&quot; height=\&quot;20\&quot; as=\&quot;geometry\&quot; /&gt;\n        &lt;/mxCell&gt;\n        &lt;mxCell id=\&quot;dN6sw1qnDhJNe45-whcC-7\&quot; value=\&quot;(sm::state)StateC\&quot; style=\&quot;rounded=0;whiteSpace=wrap;html=1;strokeColor=#808080;fillColor=#E6E6E6;fontColor=#808080;fontStyle=0;fontFamily=Lucida Console;strokeWidth=2;fontSize=10;\&quot; vertex=\&quot;1\&quot; parent=\&quot;1\&quot;&gt;\n          &lt;mxGeometry x=\&quot;892.94\&quot; y=\&quot;1343.37\&quot; width=\&quot;126.25\&quot; height=\&quot;20\&quot; as=\&quot;geometry\&quot; /&gt;\n        &lt;/mxCell&gt;\n        &lt;mxCell id=\&quot;dN6sw1qnDhJNe45-whcC-8\&quot; value=\&quot;&amp;lt;span style=&amp;quot;color: rgb(128, 128, 128); font-family: &amp;amp;quot;Lucida Console&amp;amp;quot;; font-size: 10px;&amp;quot;&amp;gt;&amp;amp;nbsp; xCallbackFcn&amp;lt;/span&amp;gt;&amp;lt;br style=&amp;quot;color: rgb(128, 128, 128); font-family: &amp;amp;quot;Lucida Console&amp;amp;quot;; font-size: 10px;&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: rgb(128, 128, 128); font-family: &amp;amp;quot;Lucida Console&amp;amp;quot;; font-size: 10px;&amp;quot;&amp;gt;&amp;amp;nbsp; parent*&amp;lt;/span&amp;gt;\&quot; style=\&quot;rounded=0;whiteSpace=wrap;html=1;strokeColor=#808080;fillColor=none;fontFamily=Helvetica;strokeWidth=2;align=left;\&quot; vertex=\&quot;1\&quot; parent=\&quot;1\&quot;&gt;\n          &lt;mxGeometry x=\&quot;892.94\&quot; y=\&quot;1363.37\&quot; width=\&quot;126.25\&quot; height=\&quot;44\&quot; as=\&quot;geometry\&quot; /&gt;\n        &lt;/mxCell&gt;\n        &lt;mxCell id=\&quot;dN6sw1qnDhJNe45-whcC-9\&quot; value=\&quot;(sm::state)StateA\&quot; style=\&quot;rounded=0;whiteSpace=wrap;html=1;strokeColor=#808080;fillColor=#E6E6E6;fontColor=#808080;fontStyle=0;fontFamily=Lucida Console;strokeWidth=2;fontSize=10;\&quot; vertex=\&quot;1\&quot; parent=\&quot;1\&quot;&gt;\n          &lt;mxGeometry x=\&quot;692.82\&quot; y=\&quot;1331.9899999999998\&quot; width=\&quot;126.25\&quot; height=\&quot;20\&quot; as=\&quot;geometry\&quot; /&gt;\n        &lt;/mxCell&gt;\n        &lt;mxCell id=\&quot;dN6sw1qnDhJNe45-whcC-10\&quot; value=\&quot;&amp;lt;span style=&amp;quot;color: rgb(128, 128, 128); font-family: &amp;amp;quot;Lucida Console&amp;amp;quot;; font-size: 10px;&amp;quot;&amp;gt;&amp;amp;nbsp; xCallbackFcn&amp;lt;/span&amp;gt;&amp;lt;br style=&amp;quot;color: rgb(128, 128, 128); font-family: &amp;amp;quot;Lucida Console&amp;amp;quot;; font-size: 10px;&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: rgb(128, 128, 128); font-family: &amp;amp;quot;Lucida Console&amp;amp;quot;; font-size: 10px;&amp;quot;&amp;gt;&amp;amp;nbsp; parent*&amp;lt;/span&amp;gt;\&quot; style=\&quot;rounded=0;whiteSpace=wrap;html=1;strokeColor=#808080;fillColor=none;fontFamily=Helvetica;strokeWidth=2;align=left;\&quot; vertex=\&quot;1\&quot; parent=\&quot;1\&quot;&gt;\n          &lt;mxGeometry x=\&quot;692.82\&quot; y=\&quot;1351.9899999999998\&quot; width=\&quot;126.25\&quot; height=\&quot;44\&quot; as=\&quot;geometry\&quot; /&gt;\n        &lt;/mxCell&gt;\n        &lt;mxCell id=\&quot;dN6sw1qnDhJNe45-whcC-11\&quot; value=\&quot;(sm::state)StateB\&quot; style=\&quot;rounded=0;whiteSpace=wrap;html=1;strokeColor=#808080;fillColor=#E6E6E6;fontColor=#808080;fontStyle=0;fontFamily=Lucida Console;strokeWidth=2;fontSize=10;\&quot; vertex=\&quot;1\&quot; parent=\&quot;1\&quot;&gt;\n          &lt;mxGeometry x=\&quot;692.82\&quot; y=\&quot;1406.37\&quot; width=\&quot;126.25\&quot; height=\&quot;20\&quot; as=\&quot;geometry\&quot; /&gt;\n        &lt;/mxCell&gt;\n        &lt;mxCell id=\&quot;dN6sw1qnDhJNe45-whcC-12\&quot; value=\&quot;&amp;lt;span style=&amp;quot;color: rgb(128, 128, 128); font-family: &amp;amp;quot;Lucida Console&amp;amp;quot;; font-size: 10px;&amp;quot;&amp;gt;&amp;amp;nbsp; xCallbackFcn&amp;lt;/span&amp;gt;&amp;lt;br style=&amp;quot;color: rgb(128, 128, 128); font-family: &amp;amp;quot;Lucida Console&amp;amp;quot;; font-size: 10px;&amp;quot;&amp;gt;&amp;lt;span style=&amp;quot;color: rgb(128, 128, 128); font-family: &amp;amp;quot;Lucida Console&amp;amp;quot;; font-size: 10px;&amp;quot;&amp;gt;&amp;amp;nbsp; parent*&amp;lt;/span&amp;gt;\&quot; style=\&quot;rounded=0;whiteSpace=wrap;html=1;strokeColor=#808080;fillColor=none;fontFamily=Helvetica;strokeWidth=2;align=left;\&quot; vertex=\&quot;1\&quot; parent=\&quot;1\&quot;&gt;\n          &lt;mxGeometry x=\&quot;692.82\&quot; y=\&quot;1426.37\&quot; width=\&quot;126.25\&quot; height=\&quot;44\&quot; as=\&quot;geometry\&quot; /&gt;\n        &lt;/mxCell&gt;\n        &lt;mxCell id=\&quot;dN6sw1qnDhJNe45-whcC-13\&quot; value=\&quot;\&quot; style=\&quot;endArrow=classic;html=1;rounded=0;shadow=0;dashed=1;fontFamily=Lucida Console;fontSize=10;fontColor=#B3B3B3;strokeColor=#007FFF;strokeWidth=2;\&quot; edge=\&quot;1\&quot; parent=\&quot;1\&quot;&gt;\n          &lt;mxGeometry width=\&quot;50\&quot; height=\&quot;50\&quot; relative=\&quot;1\&quot; as=\&quot;geometry\&quot;&gt;\n            &lt;mxPoint x=\&quot;847.9300000000001\&quot; y=\&quot;1193.99\&quot; as=\&quot;sourcePoint\&quot; /&gt;\n            &lt;mxPoint x=\&quot;1013.9399999999999\&quot; y=\&quot;1343.99\&quot; as=\&quot;targetPoint\&quot; /&gt;\n            &lt;Array as=\&quot;points\&quot;&gt;\n              &lt;mxPoint x=\&quot;956.94\&quot; y=\&quot;1193.99\&quot; /&gt;\n              &lt;mxPoint x=\&quot;1013.9399999999999\&quot; y=\&quot;1193.99\&quot; /&gt;\n            &lt;/Array&gt;\n          &lt;/mxGeometry&gt;\n        &lt;/mxCell&gt;\n        &lt;mxCell id=\&quot;dN6sw1qnDhJNe45-whcC-14\&quot; value=\&quot;\&quot; style=\&quot;endArrow=classic;html=1;rounded=0;shadow=0;fontFamily=Lucida Console;fontSize=10;fontColor=#B3B3B3;strokeColor=#007FFF;strokeWidth=2;startArrow=oval;startFill=1;\&quot; edge=\&quot;1\&quot; parent=\&quot;1\&quot;&gt;\n          &lt;mxGeometry width=\&quot;50\&quot; height=\&quot;50\&quot; relative=\&quot;1\&quot; as=\&quot;geometry\&quot;&gt;\n            &lt;mxPoint x=\&quot;892.57\&quot; y=\&quot;1392.75\&quot; as=\&quot;sourcePoint\&quot; /&gt;\n            &lt;mxPoint x=\&quot;822.57\&quot; y=\&quot;1342.75\&quot; as=\&quot;targetPoint\&quot; /&gt;\n            &lt;Array as=\&quot;points\&quot;&gt;\n              &lt;mxPoint x=\&quot;842.57\&quot; y=\&quot;1392.75\&quot; /&gt;\n              &lt;mxPoint x=\&quot;842.57\&quot; y=\&quot;1342.75\&quot; /&gt;\n            &lt;/Array&gt;\n          &lt;/mxGeometry&gt;\n        &lt;/mxCell&gt;\n        &lt;mxCell id=\&quot;dN6sw1qnDhJNe45-whcC-15\&quot; value=\&quot;\&quot; style=\&quot;endArrow=classic;html=1;rounded=0;shadow=0;fontFamily=Lucida Console;fontSize=10;fontColor=#B3B3B3;strokeColor=#007FFF;strokeWidth=2;startArrow=oval;startFill=1;entryX=0;entryY=0.396;entryDx=0;entryDy=0;entryPerimeter=0;dashed=1;\&quot; edge=\&quot;1\&quot; parent=\&quot;1\&quot; target=\&quot;dN6sw1qnDhJNe45-whcC-8\&quot;&gt;\n          &lt;mxGeometry width=\&quot;50\&quot; height=\&quot;50\&quot; relative=\&quot;1\&quot; as=\&quot;geometry\&quot;&gt;\n            &lt;mxPoint x=\&quot;872.94\&quot; y=\&quot;1323.37\&quot; as=\&quot;sourcePoint\&quot; /&gt;\n            &lt;mxPoint x=\&quot;962.94\&quot; y=\&quot;1403.37\&quot; as=\&quot;targetPoint\&quot; /&gt;\n            &lt;Array as=\&quot;points\&quot;&gt;\n              &lt;mxPoint x=\&quot;872.94\&quot; y=\&quot;1323.37\&quot; /&gt;\n              &lt;mxPoint x=\&quot;872.57\&quot; y=\&quot;1380.75\&quot; /&gt;\n            &lt;/Array&gt;\n          &lt;/mxGeometry&gt;\n        &lt;/mxCell&gt;\n        &lt;mxCell id=\&quot;dN6sw1qnDhJNe45-whcC-16\&quot; value=\&quot;\&quot; style=\&quot;endArrow=open;html=1;rounded=0;shadow=0;fontFamily=Lucida Console;fontSize=10;fontColor=#B3B3B3;strokeColor=#007FFF;strokeWidth=2;startArrow=box;startFill=0;endFill=0;\&quot; edge=\&quot;1\&quot; parent=\&quot;1\&quot;&gt;\n          &lt;mxGeometry width=\&quot;50\&quot; height=\&quot;50\&quot; relative=\&quot;1\&quot; as=\&quot;geometry\&quot;&gt;\n            &lt;mxPoint x=\&quot;977.07\&quot; y=\&quot;1232.5\&quot; as=\&quot;sourcePoint\&quot; /&gt;\n            &lt;mxPoint x=\&quot;942.57\&quot; y=\&quot;1272.75\&quot; as=\&quot;targetPoint\&quot; /&gt;\n            &lt;Array as=\&quot;points\&quot;&gt;\n              &lt;mxPoint x=\&quot;962.57\&quot; y=\&quot;1232.75\&quot; /&gt;\n              &lt;mxPoint x=\&quot;962.57\&quot; y=\&quot;1272.75\&quot; /&gt;\n            &lt;/Array&gt;\n          &lt;/mxGeometry&gt;\n        &lt;/mxCell&gt;\n        &lt;mxCell id=\&quot;dN6sw1qnDhJNe45-whcC-17\&quot; value=\&quot;childs of Top\&quot; style=\&quot;text;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;shadow=1;fontColor=#808080;fontFamily=Helvetica;rounded=0;strokeWidth=2;\&quot; vertex=\&quot;1\&quot; parent=\&quot;1\&quot;&gt;\n          &lt;mxGeometry x=\&quot;721.08\&quot; y=\&quot;1470.37\&quot; width=\&quot;76.25\&quot; height=\&quot;20.25\&quot; as=\&quot;geometry\&quot; /&gt;\n        &lt;/mxCell&gt;\n        &lt;mxCell id=\&quot;dN6sw1qnDhJNe45-whcC-18\&quot; value=\&quot;childs of StateA\&quot; style=\&quot;text;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;shadow=1;fontColor=#808080;fontFamily=Helvetica;rounded=0;strokeWidth=2;\&quot; vertex=\&quot;1\&quot; parent=\&quot;1\&quot;&gt;\n          &lt;mxGeometry x=\&quot;908.07\&quot; y=\&quot;1407.37\&quot; width=\&quot;95.99\&quot; height=\&quot;20.25\&quot; as=\&quot;geometry\&quot; /&gt;\n        &lt;/mxCell&gt;\n        &lt;mxCell id=\&quot;dN6sw1qnDhJNe45-whcC-19\&quot; value=\&quot;on &amp;#xa;signal\&quot; style=\&quot;text;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;spacingLeft=4;spacingRight=4;overflow=hidden;points=[[0,0.5],[1,0.5]];portConstraint=eastwest;rotatable=0;shadow=1;fontColor=#808080;fontFamily=Helvetica;rounded=0;strokeWidth=2;\&quot; vertex=\&quot;1\&quot; parent=\&quot;1\&quot;&gt;\n          &lt;mxGeometry x=\&quot;967.9499999999999\&quot; y=\&quot;1222.25\&quot; width=\&quot;43.38\&quot; height=\&quot;30.25\&quot; as=\&quot;geometry\&quot; /&gt;\n        &lt;/mxCell&gt;\n        &lt;mxCell id=\&quot;dN6sw1qnDhJNe45-whcC-20\&quot; value=\&quot;\&quot; style=\&quot;endArrow=open;html=1;rounded=0;shadow=0;fontFamily=Lucida Console;fontSize=10;fontColor=#B3B3B3;strokeColor=#007FFF;strokeWidth=2;startArrow=none;startFill=0;endFill=0;entryX=1;entryY=0.75;entryDx=0;entryDy=0;\&quot; edge=\&quot;1\&quot; parent=\&quot;1\&quot;&gt;\n          &lt;mxGeometry width=\&quot;50\&quot; height=\&quot;50\&quot; relative=\&quot;1\&quot; as=\&quot;geometry\&quot;&gt;\n            &lt;mxPoint x=\&quot;942.57\&quot; y=\&quot;1272.75\&quot; as=\&quot;sourcePoint\&quot; /&gt;\n            &lt;mxPoint x=\&quot;884.4399999999999\&quot; y=\&quot;1302.7500000000002\&quot; as=\&quot;targetPoint\&quot; /&gt;\n            &lt;Array as=\&quot;points\&quot;&gt;\n              &lt;mxPoint x=\&quot;902.57\&quot; y=\&quot;1272.75\&quot; /&gt;\n              &lt;mxPoint x=\&quot;884.57\&quot; y=\&quot;1272.75\&quot; /&gt;\n            &lt;/Array&gt;\n          &lt;/mxGeometry&gt;\n        &lt;/mxCell&gt;\n        &lt;mxCell id=\&quot;dN6sw1qnDhJNe45-whcC-21\&quot; value=\&quot;\&quot; style=\&quot;endArrow=open;html=1;rounded=0;shadow=0;fontFamily=Lucida Console;fontSize=10;fontColor=#B3B3B3;strokeColor=#007FFF;strokeWidth=2;startArrow=none;startFill=0;endFill=0;entryX=0.711;entryY=-0.033;entryDx=0;entryDy=0;entryPerimeter=0;\&quot; edge=\&quot;1\&quot; parent=\&quot;1\&quot; target=\&quot;dN6sw1qnDhJNe45-whcC-6\&quot;&gt;\n          &lt;mxGeometry width=\&quot;50\&quot; height=\&quot;50\&quot; relative=\&quot;1\&quot; as=\&quot;geometry\&quot;&gt;\n            &lt;mxPoint x=\&quot;850.33\&quot; y=\&quot;1212.5\&quot; as=\&quot;sourcePoint\&quot; /&gt;\n            &lt;mxPoint x=\&quot;870.33\&quot; y=\&quot;1292.5\&quot; as=\&quot;targetPoint\&quot; /&gt;\n            &lt;Array as=\&quot;points\&quot;&gt;\n              &lt;mxPoint x=\&quot;870.33\&quot; y=\&quot;1212.5\&quot; /&gt;\n            &lt;/Array&gt;\n          &lt;/mxGeometry&gt;\n        &lt;/mxCell&gt;\n        &lt;mxCell id=\&quot;dN6sw1qnDhJNe45-whcC-22\&quot; value=\&quot;\&quot; style=\&quot;endArrow=oval;html=1;rounded=0;shadow=0;fontFamily=Lucida Console;fontSize=10;fontColor=#B3B3B3;strokeColor=#007FFF;strokeWidth=2;endFill=1;entryX=0.007;entryY=0.614;entryDx=0;entryDy=0;entryPerimeter=0;\&quot; edge=\&quot;1\&quot; parent=\&quot;1\&quot;&gt;\n          &lt;mxGeometry width=\&quot;50\&quot; height=\&quot;50\&quot; relative=\&quot;1\&quot; as=\&quot;geometry\&quot;&gt;\n            &lt;mxPoint x=\&quot;692.95\&quot; y=\&quot;1275.58\&quot; as=\&quot;sourcePoint\&quot; /&gt;\n            &lt;mxPoint x=\&quot;711.20375\&quot; y=\&quot;1275.7659999999998\&quot; as=\&quot;targetPoint\&quot; /&gt;\n          &lt;/mxGeometry&gt;\n        &lt;/mxCell&gt;\n        &lt;mxCell id=\&quot;dN6sw1qnDhJNe45-whcC-23\&quot; value=\&quot;\&quot; style=\&quot;endArrow=classic;html=1;rounded=0;shadow=0;fontFamily=Lucida Console;fontSize=10;fontColor=#B3B3B3;strokeColor=#007FFF;strokeWidth=2;startArrow=oval;startFill=1;\&quot; edge=\&quot;1\&quot; parent=\&quot;1\&quot;&gt;\n          &lt;mxGeometry width=\&quot;50\&quot; height=\&quot;50\&quot; relative=\&quot;1\&quot; as=\&quot;geometry\&quot;&gt;\n            &lt;mxPoint x=\&quot;692.57\&quot; y=\&quot;1382.75\&quot; as=\&quot;sourcePoint\&quot; /&gt;\n            &lt;mxPoint x=\&quot;712.57\&quot; y=\&quot;1242.75\&quot; as=\&quot;targetPoint\&quot; /&gt;\n            &lt;Array as=\&quot;points\&quot;&gt;\n              &lt;mxPoint x=\&quot;662.57\&quot; y=\&quot;1382.75\&quot; /&gt;\n              &lt;mxPoint x=\&quot;662.57\&quot; y=\&quot;1242.75\&quot; /&gt;\n            &lt;/Array&gt;\n          &lt;/mxGeometry&gt;\n        &lt;/mxCell&gt;\n        &lt;mxCell id=\&quot;dN6sw1qnDhJNe45-whcC-24\&quot; value=\&quot;\&quot; style=\&quot;endArrow=classic;html=1;rounded=0;shadow=0;fontFamily=Lucida Console;fontSize=10;fontColor=#B3B3B3;strokeColor=#007FFF;strokeWidth=2;startArrow=oval;startFill=1;\&quot; edge=\&quot;1\&quot; parent=\&quot;1\&quot;&gt;\n          &lt;mxGeometry width=\&quot;50\&quot; height=\&quot;50\&quot; relative=\&quot;1\&quot; as=\&quot;geometry\&quot;&gt;\n            &lt;mxPoint x=\&quot;692.57\&quot; y=\&quot;1455.75\&quot; as=\&quot;sourcePoint\&quot; /&gt;\n            &lt;mxPoint x=\&quot;712.19\&quot; y=\&quot;1231.12\&quot; as=\&quot;targetPoint\&quot; /&gt;\n            &lt;Array as=\&quot;points\&quot;&gt;\n              &lt;mxPoint x=\&quot;642.57\&quot; y=\&quot;1455.75\&quot; /&gt;\n              &lt;mxPoint x=\&quot;642.57\&quot; y=\&quot;1230.75\&quot; /&gt;\n            &lt;/Array&gt;\n          &lt;/mxGeometry&gt;\n        &lt;/mxCell&gt;\n      &lt;/root&gt;\n    &lt;/mxGraphModel&gt;\n  &lt;/diagram&gt;\n&lt;/mxfile&gt;\n&quot;}"></div>
* <script type="text/javascript" src="https://viewer.diagrams.net/js/viewer-static.min.js"></script>
* </body>
* </html>
* @endhtmlonly
* <em>FSM module design</em>
* </center>
*
* One important attribute of the @ref qOS::sm::state object is the callback function,
* which is used to describe the behavior specific to the state. Also, there is a
* pointer to the parent state to define the nesting of the state and its place in
* the hierarchical topology. As shown in figure above, a state machine consists
* of a least one state, the "top-level" state. So concrete state machine are
* built by adding an arbitrary number of states and defining callback functions.
* The only purpose of the top state is to provide the root of the hierarchy, so
* that the highest level can return to the top as their parent state.
*
* @section q_fsmsetup Setting up a state machine
* Like any other OS object, a Finite State Machine (FSM) must be explicitly
* initialized before it can be used. The @ref qOS::stateMachine::setup() method initializes
* the instance, sets the callback for the top state, sets the initial state and
* the surrounding callback function.
*
* @section q_fsm_subscribe_states Subscribing states and defining callbacks
* State machines are constructed by composition, therefore, the topology of a
* state machine is determined upon construction. In this FSM implementation,
* there is no distinction between composite states(states containing substates)
* and leaf states. All states are potentially composite. The method
* @ref qOS::stateMachine::add() should be used to initialize the state and
* define its position in the topology.
*
* A state callback-functions takes a qOS::sm::handler_t object as input argument and
* returns a @c sm::status value. An example is shown in the following code snippet:
*
*  @code{.c}
*  sm::status ExampleState_Callback( sm::handler_t h ) {
*      /* TODO: State code */
*      return sm::status::SUCCESS;
*  }
*  @endcode
*
* States can also be defined using the object-oriented programming approach. In
* this particular case, a class must be defined that inherits from qOS::sm::state and
* the @c activities method, where the behavior of the state resides, must be
* overridden.
*
*  @code{.c}
*  class myCustomState : public sm::state {
*      sm::status activities( sm::handler_t h ) override {
*          // TODO : State code
*          return sm::status::SUCCESS;
*      }
*  };
*  @endcode
*
* @section q_fsmhandler The state callback handler: performing transitions and retrieving data
* Because callback functions are methods derived from the state-machine object,
* they have direct access to some attributes via the @ref qOS::sm::handler_t argument.
* The usage of this object it's required to make the FSM moves between states
* and additionally get extra data. The provided attributes are:
*
* - @ref qOS::sm::handler_t::nextState() : Method to set the desired next state.
* The application writer should use this method passing another state to produce
*  a state transition in the next FSM's cycle. Changing this field will only
* take effect when the state is executed under user custom-defined signals or in
* the absence of signals @c signalID::QSM_SIGNAL_NONE.
* In additon the user can specify as second argument the history mode. Use this
* argument option if the transition is to a composite state. This argument
* defines how the story should be handled.
* If this argument is ignored, @c sm::historyMode::NO_HISTORY is assumed.
* The possible values for this attribute are:
*     - @c sm::historyMode::NO_HISTORY : History is not preserved. Composite states
*       will start according to their default transition.
*     - @c sm::historyMode::SHALLOW_HISTORY : History will be kept to allow the
*       return to only the top-most sub-state of the most recent state
*       configuration, which is entered using the default entry rule.
*     - @c sm::historyMode::DEEP_HISTORY : History will be kept to allow full state
*       configuration of the most recent visit to the containing region.
* - @ref qOS::sm::handler_t::startState() : Desired nested initial state (substate). The
* application writer should change this field to set the initial transition if
* the current state is a parent(or composite state). Changing this field
* attribute only takes effect when the state is executed under the
* @c signalID::SIGNAL_START signal.
* - @ref qOS::sm::handler_t::signal() : Method to read the received signal. Can return any of the
* following values:
*     - @c signalID::SIGNAL_NONE if no signal is available.
*     - @c signalID::SIGNAL_ENTRY if the current state has just entered from another state.
*     - @c signalID::SIGNAL_START to set nested initial transitions by using the
*       qOS::sm::handler_t::startState() method.
*     - @c signalID::SIGNAL_EXIT if the current state has just exited to another state.
*     - Any other user-defined signal will reside here, including the
*       qOS::sm::SIGNAL_TIMEOUT() signals.
* - @ref qOS::sm::handler_t::SignalData (read-only) : Pointer to the data associated with
* the signal. For internal signals, including timeout signals, its value will
* be @c nullptr.
* - @ref qOS::sm::handler_t::lastStatus() :  Retrieve the exit(or return) status of the last
* state. Should be used in the Surrounding callback to perform the corresponding
* actions for every value. On states callback will take the value @c sm::status::ABSENT
* - @ref qOS::sm::handler_t::thisMachine() : Method to get a reference to the container
* state machine.
* - @ref qOS::sm::handler_t::thisState() : Method to get a reference to the state
* being evaluated.
* - @ref qOS::sm::handler_t::Data (read-only) : State-machine associated data. If the FSM
* is running as a task, the associated event data can be queried through this
* field. (here, a cast to qOS::event_t is mandatory).
* - @ref qOS::sm::handler_t::StateData (read-only) : State associated data. Storage-pointer.
*
*
* Within the callback function of every state or the @c activities method, only one
* level of dispatching (based on the signal) is necessary. Typically this is
* archived using a single-level switch statement. Callback functions communicate
* with the state machine engine through the qOS::sm::handler_t and the return
* value of type @c sm::status.
*
* The semantic is simple, if a signal is processed, the callback functions
* returns the status value @c sm::status::SIGNAL_HANDLED. Otherwise, it throws the
* signal for further processing by higher-level states. Also, this returning
* mechanism can be used to handle exceptions by using the surrounding callback.
*
* @a Entry/Exit actions and default transitions are also implemented inside the
* callback function in the response to pre-defined signals. @c sm::signalID::SIGNAL_ENTRY,
* @c sm::signalID::SIGNAL_EXIT and @c sm::signalID::SIGNAL_START. The state machine generates and
* dispatches these signals to appropriate handlers upon state transitions.
*
* The example below shows what a status callback should look like including the
* use of the handler.
*
*  @code{.c}
*  sm::status ExampleState_Callback ( sm::handler_t h ) {
*      switch ( h.signal() ) {
*          case sm::signalID::SIGNAL_START:
*              break;
*          case sm::signalID::SIGNAL_ENTRY:
*              break;
*          case sm::signalID::SIGNAL_EXIT:
*              break;
*          case USER_DEFINED_SIGNAL :
*              h.nextState( OtherState ); /*transition*/
*              break;
*          default:
*              break;
*      }
*      return sm::status::SUCCESS;
*  }
*  @endcode
*
* As shown above, the return value represents the exit status of the state, and
* it can be handled with an additional surrounding callback function \f$ S_u \f$
* established at the moment of the FSM setup. The values allowed to return are
* listed below.
*
* - @c sm::status::SUCCESS
* - @c sm::status::FAILURE
* - @c sm::status::SIGNAL_HANDLED
* - Any other integer value between @c -32762 and @c 32767
*
* To code initial transitions, the application writer should catch the
* @c sm::signalID::SIGNAL_START, perform the required actions and then designate the target
* sub-state by using the qOS::sm::handler_t::startState() method. Regular
* transitions are coded in a very similar way, except that
* here, you catch the custom-defined signal and then use the qOS::sm::handler_t::nextState()
* method. The developer is free to write and control state transitions.
* Transitions are only allowed under the availability of user custom-defined
* signals. Regular transitions are not allowed at an entry point
* (@c signalID::SIGNAL_ENTRY), exit point (@c signalID::SIGNAL_EXIT), or a start
* point (@c signalID::SIGNAL_START).
*
* @note User should not target the top state in a transition and use it as
* transition source either. The only customizable aspect of the top state is
* the initial transition.
*
* @section q_fsm_surrounding The surrounding callback
* It is a checkpoint before and after each state executes its activities
* through its state callback. The behavior of this surrounding callback must be
* defined by the programmer.
*
* <center>
* @htmlonly
* <!DOCTYPE html>
* <html>
* <head>
* <title>surrounding</title>
* <meta charset="utf-8"/>
* </head>
* <body><div class="mxgraph" style="max-width:100%;border:1px solid transparent;" data-mxgraph="{&quot;highlight&quot;:&quot;#0000ff&quot;,&quot;nav&quot;:true,&quot;resize&quot;:true,&quot;zoom&quot;:1.5,&quot;toolbar&quot;:&quot;zoom layers tags lightbox&quot;,&quot;edit&quot;:&quot;_blank&quot;,&quot;xml&quot;:&quot;&lt;mxfile host=\&quot;app.diagrams.net\&quot; modified=\&quot;2022-10-19T05:34:37.293Z\&quot; agent=\&quot;5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 Safari/537.36\&quot; etag=\&quot;poDBqKg0qx6tawrUZqnR\&quot; version=\&quot;20.2.2\&quot; type=\&quot;google\&quot;&gt;&lt;diagram id=\&quot;4V9vBTZxQXj7jBstcZzX\&quot; name=\&quot;Página-1\&quot;&gt; &lt;/diagram&gt;&lt;/mxfile&gt;&quot;}"></div>
* <script type="text/javascript" src="https://viewer.diagrams.net/js/viewer-static.min.js"></script>
* </body>
* </html>
* @endhtmlonly
* <em>Surrounding callback invocation after and before the current state</em>
* </center>
*
* The surrounding callback \f$ S_u \f$ invocation occurs after and before the
* current state \f$ P \f$. When the surrounding callback is executed, indicates
* its own checkpoint through the @c Status attribute of the sm::handler_t
* argument.
* Unlike a state callback, the surrounding callback should not return anything,
* thus, the callback should be written as:
*
*  @code{.c}
*  void SurroundingCallback_Example( sm::handler_t h ) {
*      switch ( h.lastStatus() ) {
*          case sm::status::BEFORE_ANY:
*              /* TODO: before any code */
*              break;
*          case sm::status::FAILURE:
*              /* TODO: failure code */
*              break;
*          case sm::status::SUCCESS:
*              /* TODO: success code */
*              break;
*          case sm::status::SIGNAL_HANDLED:
*              /* TODO: signal handled code */
*              break;
*          case 5: /*user-defined return value*/
*              /* TODO: used defined*/
*              break;
*          default:
*              /*handle the unexpected*/
*              break
*      }
*  }
*  @endcode
*
* As you can see in the example below, the surrounding execution case its
* verified through the FSM handle by reading the @c Status field.
*
* @section q_fsm_astask Adding a state machine as a task
* The best strategy to run a FSM is delegating it to a task. For this, an overload
* of qOS::core::add() that takes an state-machine object as argument is provided.
* Here, the task does not have a specific callback, instead, it will evaluate
* the active state of the FSM, and later, all the other possible states in response
* to events that mark their own transition. The task will be scheduled to run
* every @c t seconds in qOS::task::PERIODIC mode.
*
* By using this method, the kernel will take care of the FSM by itself, so the
* usage of qOS::stateMachine::run()  can be omitted.
*
* Now that a task is running a dedicated state machine, the specific task
* event-information can be obtained in every state callback through the @c Data
* field of the qOS::sm::handler_t argument.
*
* Check the example below:
*
*  @code{.c}
*  sm::status Example_State( sm::handler_t h ) {
*      event_t *e = h.Data;
*      /* Get the event info of the task that owns this state machine*/
*      switch ( h.signal() ) {
*          case sm::signalID::SIGNAL_ENTRY:
*              break;
*          case sm::signalID::SIGNAL_EXIT:
*              break;
*          default:
*              switch ( e->getTrigger() ) {
*                  case trigger::byTimeElapsed:
*                      /* TODO: Code for this case */
*                  break;
*                  case trigger::byNotificationSimple:
*                      /* TODO: Code for this case */
*                  break;
*                  case trigger::byQueueCount:
*                      /* TODO: Code for this case */
*                  break;
*                  default: break;
*              }
*              /* TODO: State code */
*              break;
*      }
*      return sm::status::SUCCESS;
*  }
*  @endcode
*
* @section q_fsm_example1 A demonstrative example for a FSM
* In this example, one press of the button turns on the LED, a second push of
* the button will make the LED blink and if the button is pressed again, the
* LED will turn off. Also, our system must turn off the LED after a period of
* inactivity. If the button hasn't been pressed in the last 10 seconds, the
* LED will turn off.
*
* <center>
* @htmlonly
* <!DOCTYPE html>
* <html>
* <head>
* <title>ledfsm++</title>
* <meta charset="utf-8"/>
* </head>
* <body><div class="mxgraph" style="max-width:100%;border:1px solid transparent;" data-mxgraph="{&quot;highlight&quot;:&quot;#0000ff&quot;,&quot;lightbox&quot;:false,&quot;nav&quot;:true,&quot;zoom&quot;:1.5,&quot;resize&quot;:true,&quot;toolbar&quot;:&quot;zoom layers tags&quot;,&quot;edit&quot;:&quot;_blank&quot;,&quot;xml&quot;:&quot;&lt;mxfile host=\&quot;app.diagrams.net\&quot; modified=\&quot;2023-07-17T21:19:21.646Z\&quot; agent=\&quot;Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36\&quot; etag=\&quot;5-bU9w446gBWmJucko_s\&quot; version=\&quot;21.2.9\&quot; type=\&quot;google\&quot;&gt;\n  &lt;diagram name=\&quot;Página-1\&quot; id=\&quot;PPq_TbZygOE9Y1frLE7i\&quot;&gt;\n    &lt;mxGraphModel dx=\&quot;1108\&quot; dy=\&quot;453\&quot; grid=\&quot;1\&quot; gridSize=\&quot;10\&quot; guides=\&quot;1\&quot; tooltips=\&quot;1\&quot; connect=\&quot;1\&quot; arrows=\&quot;1\&quot; fold=\&quot;1\&quot; page=\&quot;1\&quot; pageScale=\&quot;1\&quot; pageWidth=\&quot;1169\&quot; pageHeight=\&quot;827\&quot; math=\&quot;0\&quot; shadow=\&quot;0\&quot;&gt;\n      &lt;root&gt;\n        &lt;mxCell id=\&quot;0\&quot; /&gt;\n        &lt;mxCell id=\&quot;1\&quot; parent=\&quot;0\&quot; /&gt;\n        &lt;mxCell id=\&quot;BJD9Ttu0zg7xfjPafxcG-1\&quot; value=\&quot;&amp;lt;font&amp;gt;&amp;lt;b&amp;gt;Off&amp;lt;/b&amp;gt;&amp;lt;/font&amp;gt;\&quot; style=\&quot;rounded=0;whiteSpace=wrap;html=1;strokeColor=#808080;fillColor=#E6E6E6;fontFamily=Helvetica;strokeWidth=2;fontColor=#808080;\&quot; parent=\&quot;1\&quot; vertex=\&quot;1\&quot;&gt;\n          &lt;mxGeometry x=\&quot;124.99999999999994\&quot; y=\&quot;1285.9999999999998\&quot; width=\&quot;100\&quot; height=\&quot;20\&quot; as=\&quot;geometry\&quot; /&gt;\n        &lt;/mxCell&gt;\n        &lt;mxCell id=\&quot;BJD9Ttu0zg7xfjPafxcG-2\&quot; value=\&quot;&amp;amp;nbsp;&amp;lt;b&amp;gt;entry&amp;lt;/b&amp;gt;:&amp;lt;br&amp;gt;&amp;amp;nbsp;BSP_LED_OFF();\&quot; style=\&quot;rounded=0;whiteSpace=wrap;html=1;strokeColor=#808080;fillColor=none;fontFamily=Lucida Console;strokeWidth=2;align=left;fontSize=10;fontColor=#808080;\&quot; parent=\&quot;1\&quot; vertex=\&quot;1\&quot;&gt;\n          &lt;mxGeometry x=\&quot;124.99999999999994\&quot; y=\&quot;1305.9999999999998\&quot; width=\&quot;100\&quot; height=\&quot;40\&quot; as=\&quot;geometry\&quot; /&gt;\n        &lt;/mxCell&gt;\n        &lt;mxCell id=\&quot;BJD9Ttu0zg7xfjPafxcG-3\&quot; value=\&quot;&amp;lt;font&amp;gt;&amp;lt;b&amp;gt;On&amp;lt;/b&amp;gt;&amp;lt;/font&amp;gt;\&quot; style=\&quot;rounded=0;whiteSpace=wrap;html=1;strokeColor=#808080;fillColor=#E6E6E6;fontFamily=Helvetica;strokeWidth=2;fontColor=#808080;\&quot; parent=\&quot;1\&quot; vertex=\&quot;1\&quot;&gt;\n          &lt;mxGeometry x=\&quot;294.99999999999994\&quot; y=\&quot;1229.9999999999998\&quot; width=\&quot;200\&quot; height=\&quot;20\&quot; as=\&quot;geometry\&quot; /&gt;\n        &lt;/mxCell&gt;\n        &lt;mxCell id=\&quot;BJD9Ttu0zg7xfjPafxcG-4\&quot; value=\&quot;&amp;amp;nbsp;&amp;lt;b&amp;gt;entry&amp;lt;/b&amp;gt;:&amp;lt;br&amp;gt;&amp;amp;nbsp;BSP_LED_ON();&amp;lt;br&amp;gt;&amp;amp;nbsp;timeout.set( 10000 );\&quot; style=\&quot;rounded=0;whiteSpace=wrap;html=1;strokeColor=#808080;fillColor=none;fontFamily=Lucida Console;strokeWidth=2;align=left;fontSize=10;fontColor=#808080;\&quot; parent=\&quot;1\&quot; vertex=\&quot;1\&quot;&gt;\n          &lt;mxGeometry x=\&quot;294.99999999999994\&quot; y=\&quot;1249.9999999999998\&quot; width=\&quot;200\&quot; height=\&quot;40\&quot; as=\&quot;geometry\&quot; /&gt;\n        &lt;/mxCell&gt;\n        &lt;mxCell id=\&quot;BJD9Ttu0zg7xfjPafxcG-5\&quot; value=\&quot;&amp;lt;font&amp;gt;&amp;lt;b&amp;gt;Blink&amp;lt;/b&amp;gt;&amp;lt;/font&amp;gt;\&quot; style=\&quot;rounded=0;whiteSpace=wrap;html=1;strokeColor=#808080;fillColor=#E6E6E6;fontFamily=Helvetica;strokeWidth=2;fontColor=#808080;\&quot; parent=\&quot;1\&quot; vertex=\&quot;1\&quot;&gt;\n          &lt;mxGeometry x=\&quot;238.99999999999994\&quot; y=\&quot;1347.9999999999998\&quot; width=\&quot;270\&quot; height=\&quot;20\&quot; as=\&quot;geometry\&quot; /&gt;\n        &lt;/mxCell&gt;\n        &lt;mxCell id=\&quot;BJD9Ttu0zg7xfjPafxcG-6\&quot; value=\&quot;&amp;amp;nbsp;&amp;lt;b&amp;gt;entry&amp;lt;/b&amp;gt;:&amp;lt;br&amp;gt;&amp;amp;nbsp;timeout.set( 10000 );&amp;lt;br&amp;gt;&amp;lt;b&amp;gt;&amp;amp;nbsp;default:&amp;lt;br&amp;gt;&amp;lt;/b&amp;gt;&amp;amp;nbsp;if( blinktime.freeRun( 500) ) {&amp;lt;br&amp;gt;&amp;amp;nbsp; &amp;amp;nbsp; &amp;amp;nbsp;BSP_LED_TOGGLE();&amp;lt;br&amp;gt;&amp;amp;nbsp;}\&quot; style=\&quot;rounded=0;whiteSpace=wrap;html=1;strokeColor=#808080;fillColor=none;fontFamily=Lucida Console;strokeWidth=2;align=left;fontSize=10;fontColor=#808080;\&quot; parent=\&quot;1\&quot; vertex=\&quot;1\&quot;&gt;\n          &lt;mxGeometry x=\&quot;238.99999999999994\&quot; y=\&quot;1367.9999999999998\&quot; width=\&quot;270\&quot; height=\&quot;80\&quot; as=\&quot;geometry\&quot; /&gt;\n        &lt;/mxCell&gt;\n        &lt;mxCell id=\&quot;BJD9Ttu0zg7xfjPafxcG-7\&quot; value=\&quot;\&quot; style=\&quot;curved=1;endArrow=classic;html=1;rounded=0;shadow=0;fontFamily=Lucida Console;fontSize=10;fontColor=#808080;strokeColor=#007FFF;strokeWidth=2;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0;entryY=0.25;entryDx=0;entryDy=0;\&quot; parent=\&quot;1\&quot; source=\&quot;BJD9Ttu0zg7xfjPafxcG-1\&quot; target=\&quot;BJD9Ttu0zg7xfjPafxcG-4\&quot; edge=\&quot;1\&quot;&gt;\n          &lt;mxGeometry width=\&quot;50\&quot; height=\&quot;50\&quot; relative=\&quot;1\&quot; as=\&quot;geometry\&quot;&gt;\n            &lt;mxPoint x=\&quot;314.99999999999994\&quot; y=\&quot;1153.4999999999998\&quot; as=\&quot;sourcePoint\&quot; /&gt;\n            &lt;mxPoint x=\&quot;444.99999999999994\&quot; y=\&quot;1033.4999999999998\&quot; as=\&quot;targetPoint\&quot; /&gt;\n            &lt;Array as=\&quot;points\&quot;&gt;\n              &lt;mxPoint x=\&quot;254.99999999999994\&quot; y=\&quot;1237.9999999999998\&quot; /&gt;\n            &lt;/Array&gt;\n          &lt;/mxGeometry&gt;\n        &lt;/mxCell&gt;\n        &lt;mxCell id=\&quot;BJD9Ttu0zg7xfjPafxcG-8\&quot; value=\&quot;\&quot; style=\&quot;curved=1;endArrow=classic;html=1;rounded=0;shadow=0;fontFamily=Lucida Console;fontSize=10;fontColor=#808080;strokeColor=#007FFF;strokeWidth=2;entryX=0.469;entryY=1.064;entryDx=0;entryDy=0;entryPerimeter=0;exitX=0;exitY=0.5;exitDx=0;exitDy=0;\&quot; parent=\&quot;1\&quot; source=\&quot;BJD9Ttu0zg7xfjPafxcG-6\&quot; target=\&quot;BJD9Ttu0zg7xfjPafxcG-2\&quot; edge=\&quot;1\&quot;&gt;\n          &lt;mxGeometry width=\&quot;50\&quot; height=\&quot;50\&quot; relative=\&quot;1\&quot; as=\&quot;geometry\&quot;&gt;\n            &lt;mxPoint x=\&quot;214.99999999999994\&quot; y=\&quot;1427.9999999999998\&quot; as=\&quot;sourcePoint\&quot; /&gt;\n            &lt;mxPoint x=\&quot;433.24999999999994\&quot; y=\&quot;1358.5799999999997\&quot; as=\&quot;targetPoint\&quot; /&gt;\n            &lt;Array as=\&quot;points\&quot;&gt;\n              &lt;mxPoint x=\&quot;234.99999999999994\&quot; y=\&quot;1407.9999999999998\&quot; /&gt;\n              &lt;mxPoint x=\&quot;174.99999999999994\&quot; y=\&quot;1397.9999999999998\&quot; /&gt;\n            &lt;/Array&gt;\n          &lt;/mxGeometry&gt;\n        &lt;/mxCell&gt;\n        &lt;mxCell id=\&quot;BJD9Ttu0zg7xfjPafxcG-10\&quot; value=\&quot;BUTTON_PRESSED || &amp;lt;br style=&amp;quot;font-size: 8px;&amp;quot;&amp;gt;timeout.expired()\&quot; style=\&quot;text;html=1;align=right;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;fontSize=8;fontFamily=Lucida Console;fontColor=#808080;\&quot; parent=\&quot;1\&quot; vertex=\&quot;1\&quot;&gt;\n          &lt;mxGeometry x=\&quot;119.99999999999994\&quot; y=\&quot;1409.64\&quot; width=\&quot;110\&quot; height=\&quot;30\&quot; as=\&quot;geometry\&quot; /&gt;\n        &lt;/mxCell&gt;\n        &lt;mxCell id=\&quot;BJD9Ttu0zg7xfjPafxcG-11\&quot; value=\&quot;\&quot; style=\&quot;curved=1;endArrow=classic;html=1;rounded=0;shadow=0;fontFamily=Lucida Console;fontSize=10;fontColor=#808080;strokeColor=#007FFF;strokeWidth=2;exitX=0.684;exitY=1.007;exitDx=0;exitDy=0;exitPerimeter=0;\&quot; parent=\&quot;1\&quot; source=\&quot;BJD9Ttu0zg7xfjPafxcG-4\&quot; target=\&quot;BJD9Ttu0zg7xfjPafxcG-2\&quot; edge=\&quot;1\&quot;&gt;\n          &lt;mxGeometry width=\&quot;50\&quot; height=\&quot;50\&quot; relative=\&quot;1\&quot; as=\&quot;geometry\&quot;&gt;\n            &lt;mxPoint x=\&quot;258.87999999999994\&quot; y=\&quot;1261.9999999999998\&quot; as=\&quot;sourcePoint\&quot; /&gt;\n            &lt;mxPoint x=\&quot;231.12999999999994\&quot; y=\&quot;1320.5799999999997\&quot; as=\&quot;targetPoint\&quot; /&gt;\n            &lt;Array as=\&quot;points\&quot;&gt;\n              &lt;mxPoint x=\&quot;404.99999999999994\&quot; y=\&quot;1325.9999999999998\&quot; /&gt;\n              &lt;mxPoint x=\&quot;264.99999999999994\&quot; y=\&quot;1337.9999999999998\&quot; /&gt;\n            &lt;/Array&gt;\n          &lt;/mxGeometry&gt;\n        &lt;/mxCell&gt;\n        &lt;mxCell id=\&quot;BJD9Ttu0zg7xfjPafxcG-12\&quot; value=\&quot;timeout.expired()\&quot; style=\&quot;text;html=1;align=right;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;fontSize=8;fontFamily=Lucida Console;fontColor=#808080;\&quot; parent=\&quot;1\&quot; vertex=\&quot;1\&quot;&gt;\n          &lt;mxGeometry x=\&quot;271.99999999999994\&quot; y=\&quot;1307.9999999999998\&quot; width=\&quot;110\&quot; height=\&quot;20\&quot; as=\&quot;geometry\&quot; /&gt;\n        &lt;/mxCell&gt;\n        &lt;mxCell id=\&quot;BJD9Ttu0zg7xfjPafxcG-13\&quot; value=\&quot;\&quot; style=\&quot;curved=1;endArrow=classic;html=1;rounded=0;shadow=0;fontFamily=Lucida Console;fontSize=10;fontColor=#808080;strokeColor=#007FFF;strokeWidth=2;entryX=0.475;entryY=0.029;entryDx=0;entryDy=0;entryPerimeter=0;\&quot; parent=\&quot;1\&quot; edge=\&quot;1\&quot;&gt;\n          &lt;mxGeometry width=\&quot;50\&quot; height=\&quot;50\&quot; relative=\&quot;1\&quot; as=\&quot;geometry\&quot;&gt;\n            &lt;mxPoint x=\&quot;473.2763157894735\&quot; y=\&quot;1288.7099999999998\&quot; as=\&quot;sourcePoint\&quot; /&gt;\n            &lt;mxPoint x=\&quot;434.99999999999994\&quot; y=\&quot;1347.2899999999997\&quot; as=\&quot;targetPoint\&quot; /&gt;\n            &lt;Array as=\&quot;points\&quot;&gt;\n              &lt;mxPoint x=\&quot;482.74999999999994\&quot; y=\&quot;1306.7099999999998\&quot; /&gt;\n            &lt;/Array&gt;\n          &lt;/mxGeometry&gt;\n        &lt;/mxCell&gt;\n        &lt;mxCell id=\&quot;BJD9Ttu0zg7xfjPafxcG-14\&quot; value=\&quot;\&quot; style=\&quot;curved=1;endArrow=classic;html=1;rounded=0;shadow=0;fontFamily=Lucida Console;fontSize=10;fontColor=#808080;strokeColor=#007FFF;strokeWidth=2;entryX=0.475;entryY=0.029;entryDx=0;entryDy=0;entryPerimeter=0;startArrow=oval;startFill=1;\&quot; parent=\&quot;1\&quot; edge=\&quot;1\&quot;&gt;\n          &lt;mxGeometry width=\&quot;50\&quot; height=\&quot;50\&quot; relative=\&quot;1\&quot; as=\&quot;geometry\&quot;&gt;\n            &lt;mxPoint x=\&quot;94.99999999999994\&quot; y=\&quot;1267.9999999999998\&quot; as=\&quot;sourcePoint\&quot; /&gt;\n            &lt;mxPoint x=\&quot;124.99999999999994\&quot; y=\&quot;1285.9999999999998\&quot; as=\&quot;targetPoint\&quot; /&gt;\n            &lt;Array as=\&quot;points\&quot;&gt;\n              &lt;mxPoint x=\&quot;94.99999999999994\&quot; y=\&quot;1277.9999999999998\&quot; /&gt;\n            &lt;/Array&gt;\n          &lt;/mxGeometry&gt;\n        &lt;/mxCell&gt;\n        &lt;mxCell id=\&quot;BJD9Ttu0zg7xfjPafxcG-15\&quot; value=\&quot;BUTTON_PRESSED\&quot; style=\&quot;text;html=1;align=right;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;fontSize=8;fontFamily=Lucida Console;fontColor=#808080;\&quot; parent=\&quot;1\&quot; vertex=\&quot;1\&quot;&gt;\n          &lt;mxGeometry x=\&quot;154.99999999999994\&quot; y=\&quot;1237.9999999999998\&quot; width=\&quot;90\&quot; height=\&quot;20\&quot; as=\&quot;geometry\&quot; /&gt;\n        &lt;/mxCell&gt;\n        &lt;mxCell id=\&quot;BJD9Ttu0zg7xfjPafxcG-16\&quot; value=\&quot;BUTTON_PRESSED\&quot; style=\&quot;text;html=1;align=right;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;fontSize=8;fontFamily=Lucida Console;fontColor=#808080;\&quot; parent=\&quot;1\&quot; vertex=\&quot;1\&quot;&gt;\n          &lt;mxGeometry x=\&quot;459.99999999999994\&quot; y=\&quot;1315.9999999999998\&quot; width=\&quot;90\&quot; height=\&quot;20\&quot; as=\&quot;geometry\&quot; /&gt;\n        &lt;/mxCell&gt;\n      &lt;/root&gt;\n    &lt;/mxGraphModel&gt;\n  &lt;/diagram&gt;\n&lt;/mxfile&gt;\n&quot;}"></div>
* <script type="text/javascript" src="https://viewer.diagrams.net/js/viewer-static.min.js"></script>
* </body>
* </html>
* @endhtmlonly
* <em>Flat FSM example with three states</em>
* </center>
*
*
* To start the implementation, let's define the necessary global variables...
*
*  @code{.c}
*  task LED_Task; /*The task node*/
*  stateMachine LED_FSM; /*The state -machine handle*/
*  sm::state State_LEDOff, State_LEDOn, State_LEDBlink;
*  @endcode
*
* Then, we define our states as the flow diagram shown in the figure above.
*
*  @code{.c}
*  sm::status State_LEDOff_Callback( sm::handler_t h ) {
*      switch ( h.signal() ) {
*          case sm::signalID::SIGNAL_ENTRY:
*              BSP_LED_OFF();
*              break;
*          case sm::signalID::SIGNAL_EXIT: case sm::signalID::SIGNAL_START: /*Ignore*/
*              break;
*          default:
*              if ( BUTTON_PRESSED ) {
*                  h.nextState( State_LEDOn );
*              }
*              break;
*      }
*      return sm::status::SUCCESS;
*  }
*  /*---------------------------------------------------------------------*/
*  sm::status State_LEDOn_Callback( sm::handler_t h ) {
*      static timer timeout;
*      switch ( h.signal() ) {
*          case sm::signalID::SIGNAL_ENTRY:
*              timeout.set( 10_sec );
*              BSP_LED_ON();
*              break;
*          case sm::signalID::SIGNAL_EXIT: case sm::signalID::SIGNAL_START: /*Ignore*/
*              break;
*          default:
*              if ( timeout.expired() ) {
*                  h.nextState( State_LEDOff );
*              }
*              if ( BUTTON_PRESSED ) {
*                  h.nextState( State_LEDBlink );
*              }
*              break;
*      }
*      return sm::status::SUCCESS;
*  }
*  /*---------------------------------------------------------------------*/
*  sm::status State_LEDBlink_Callback( sm::handler_t h ) {
*      static timer timeout;
*      static timer blinktime;
*
*      switch ( h.signal() ) {
*          case sm::signalID::SIGNAL_ENTRY:
*              timeout.set( 10_sec );
*              break;
*          case sm::signalID::SIGNAL_EXIT: case sm::signalID::SIGNAL_START: /*Ignore*/
*              break;
*          default:
*              if ( timeout.expired() || BUTTON_PRESSED ) {
*                  h.nextState( State_LEDOff );
*              }
*              if ( blinktime.freeRun( 500_ms ) ) {
*                 BSP_LED_TOGGLE();
*              }
*              break;
*      }
*      return sm::status::SUCCESS;
*  }
*  @endcode
*
* Finally, we add the task to the scheduling scheme running the dedicated state
* machine. Remember that you must set up the scheduler before adding a task to
* the scheduling scheme.
*
*  @code{.c}
*  LED_FSM.setup( nullptr, State_LEDOff );
*  LED_FSM.add( State_LEDOff, State_LEDOff_Callback );
*  LED_FSM.add( State_LEDOn, State_LEDOn_Callback );
*  LED_FSM.add( State_LEDBlink, State_LEDBlink_Callback );
*  os.add( LED_Task , LED_FSM , core::MEDIUM_PRIORITY, 100_ms );
*  @endcode
*
* @section q_fsmsendsignals Sending signals
* To communicate within and between state machines or even other contexts, use
* signals. A signal is a simple value that can be used to abstract an incoming
* event. In the receiving state machine, a queue or an exclusion variable
* receives the signal and holds it until the state machine can evaluate it.
*
* When coding state machines, the application writer can benefit from this
* simple event-abstraction mechanism. On the one hand, there would be a more
* uniform programming when writing state callbacks and on the other hand, the
* communication of the state machine from other contexts becomes easier.
*
* To send a signal to a state machine, use the qOS::stateMachine::sendSignal() method.
* This method can manage their delivery to one of these possible destinations:
* an <em>exclusion variable</em> or a <em>signal queue</em>:
* - An <em>exclusion variable</em> its a variable with an important distinction,
* it can only be written if it is empty. The empty situation only happens, if
* the engine has already propagated the signal within the state machine. If the
* signal has not yet propagated, the signal sending cannot be carried out.
* - When a <em>signal queue</em> is used, the signal is put into a FIFO structure
* and the engine takes care of dispatching the signal in an orderly manner. The
* only situation where the signal cannot be delivered is if the queue is full.
* This is the preferred destination, as long as there is a previously
* installed signal queue.
*
* @note If the signal-queue its available, the qOS::stateMachine.sendSignal() method will
* always select it as the default destination.
* @warning If a state machine, a task, or another context sends a signal to a
* full queue, a queue overflow occurs. The result of the queue overflow it that
* the state machine drops the new signal.
*
* @section q_fsminstallsignalqueue Installing a signal queue
* A state machine can have a FIFO queue to allow the delivery of signals from
* another contexts. If the signal queue is installed, the state-machine engine
* constantly monitors the queue for available signals. The engine then
* propagates the signal through the hierarchy until it is processed. To enable
* this functionality in your state machine, the queue must be installed by using
* the qOS::stateMachine::install() method.
*
* The install operation should be performed after both, the queue and the FSM
* are correctly initialized by using qOS::queue::setup() and qOS::stateMachine::setup()
* respectively.
*
* @note  Make sure that queues are enabled in the @c config.h header file
* @attention Use the qOS::sm::signalQueue struct to instantiate a signal queue for
* FSM. If not, user should setup explicitly the signal queue with
* qOS::queue::setup(), and size it based on the type @ref qOS::sm::signal_t.
* @note If the state machines its delegated to a task, make sure to install the
* queue prior to setting up the task. In this way, a kernel connection can be
* performed between the FSM signal queue and the FSM-task, allowing the OS to
* catch signals to produce a task event, this prevents the wait of the task for
* the specified period, resulting in faster handling of incoming signals.
*
* @section q_fsm_ttable Using a transition table
* In this approach, the FSM is coded in tables with the outgoing transitions of
* every state, where each entry relates signals, actions and the target state.
* This is an elegant method to translate the FSM to actual implementation as the
* handling for every state and event combination is encapsulated in the table.
*
* Here, the application writer gets a quick picture of the FSM and the embedded
* software maintenance is also much more under control. A transition table
* should be  explicitly installed in the target state with the corresponding
* entries, an n-sized array of @c sm::transition elements following the layout
* described below:
*
* The method qOS::sm::state::install(), should be used to perform the
* transition table installation to a specific state.
*
* <center>
* <table>
* <caption id="multi_row">General transition table layout for a state</caption>
* <tr><th>Signal Id <th>Signal action/guard <th>Target state  <th>History mode  <th>Signal data
* <tr><th>@c sm::signalID <th>@c signalAction_t <th>@c sm::state& <th>@c historyMode <th> @c void*
* <tr><td> @c Signal1 <td>@c nullptr <td>@c StateB <td>@c 0 <td>@c nullptr
* <tr><td> @c Signal3 <td>@c DoOnSignal3 <td>@c StateD <td>@c 0 <td>@c &sig3data
* <tr><td> ... <td>... <td> ... <td> ... <td> ...
* <tr><td> @c Signal6 <td>@c nullptr <td>@c StateA <td>@c 0 <td>@c nullptr
* </table>
* </center>
*
* <center>
* <table>
* <caption id="multi_row">reduced transition table layout for a state</caption>
* <tr><th>Signal Id <th>Target state
* <tr><th>@c sm::signalID <th>@c sm::state*
* <tr><td> @c Signal1 <td>@c StateB
* <tr><td> ... <td>...
* <tr><td> @c Signal6 <td>@c StateA
* </table>
* </center>
*
* <b> Caveats: </b>
*
* - State transitions are not limited to the specification of the transition
* table. A state callback owns the higher precedence to change a state. The
* application writer can use both, a transition table and the qOS::sm::handler_t::nextState()
* method in state callbacks to perform a transition to the FSM.
* - Special care is required when the table grows very large, that is, when
* there are many invalid state/event combinations, leading to a waste of memory.
* There is also a memory penalty as the number of states and events grows. The
* application writer needs to accurately account for this during the initial design.
* A statechart pattern can be used to improve the design and reduce the number
* of transition entries.
* - The user is responsible for defining the transitions according to the
* topology of the state machine. Undefined behaviors can occur if the topology
* is broken with poorly defined transitions.
*
* @subsection q_fsm_sigactions Signal actions and guards
* Transition tables allow the usage of this feature. When an event-signal is
* received from the queue, the signal-action, if available, is evaluated before
* the transition is triggered. This action is user-defined and should be coded
* as a function that takes a qOS::sm::handler_t object and returns a value of type
* @c bool.
*
*  @code{.c}
*  bool Signal_Action( sm::handler_t h ) {
*      /* TODO : Event -signal action*/
*      return true; /*allow the state transition*/
*  }
*  @endcode
*
* The return value is checked after to allow or reject the state transition. The
* application writer can code a boolean expression to implement
* <em>statechart guards</em> or perform some pre-transition procedure.
*
* @remark If a signal-action returns @c false, the event-signal is rejected,
* preventing the state transition to be performed in the calling FSM.
* @note When a transition entry is defined. the signal-action should be located
* as the third parameter of the entry. Please see the transition layout. A
* @c nullptr value will act as a NOT-defined, always allowing the state-transition.
*
* @subsection q_fsm_timeout FSM Timeout specification
* A timeout specification is a mechanism to simplify the notion of time passage
* inside states. The basic usage model of the timeout signals is as follows:
*
* A timeout specification allocates one or more timer objects. The user relates
* in a table each specific timeout operation within the state where are they
* going to operate. So, according to the table, when a state needs to arrange
* for a timeout, the engine can set or reset the given timer. When the FSM
* engine detects that the appropriate moment has arrived (a timer expiration
* occurs), it inserts the timeout signal directly into the recipient's event
* queue. The recipient then processes the timeout signal just like any other
* signal.
*
* Given the above explanation, it is evident that for its operation, the state
* machine requires an installed signal queue.
* A timeout specification is referenced by an object of type qOS::sm::timeoutSpec
* and must be installed inside the state machine using the method
* qOS::stateMachine::install(). Then, timeout operations can be defined
* in a table for each state by using the qOS::sm::state::install().
*
* A timeout specification element is defined as a structure of type
* qOS::sm::timeoutStateDefinition and should follow this layout:
*
* <center>
* <table>
* <caption id="multi_row">Timeout specification layout</caption>
* <tr><th>Timeout value  <th>Options
* </table>
* </center>
*
* The options for every timeout its a bitwise value that indicates which timeout
* should be used and the operations than should be performed internally by the
* state-machine engine. These options can be combined with a bitwise OR and are
* detailed as follows:
*
* - @c sm::TIMEOUT_USE_SIGNAL(index) : To select the timeout signal to be used
* in the specification. Should be a value between @c 0 and @c Q_FSM_MAX_TIMEOUTS-1
* - @c sm::TIMEOUT_SET_ENTRY : To set the timeout when the specified state its
* entering.
* - @c sm::TIMEOUT_RST_ENTRY : To reset the timeout when the specified state its
* entering.
* - @c sm::TIMEOUT_SET_EXIT : To set the timeout when the specified state its exiting.
* - @c sm::TIMEOUT__RST_EXIT : To reset the timeout when the specified state its
* exiting.
* - @c sm::TIMEOUT_KEEP_IF_SET : To apply the Set operation only if the timeout its
* in a reset state.
* - @c sm::TIMEOUT_PERIODIC : To put the timeout in periodic mode.
*
* @note Data associated with timeout signals should be set to @c nullptr. Any other
* value will be ignored and will be passed as @c nullptr to the FSM handler.
* @attention The user is responsible for writing timeout specifications
* correctly. Care must be taken that the specifications do not collide between
* hierarchical states to avoid overwriting operations.
* @note You can increase the number of available timeouts instances by changing
* the @c Q_FSM_MAX_TIMEOUTS configuration macro inside @c config.h.
*
* @subsection q_fsm_example2 Demonstrative example using transition tables
* The following example shows the implementation of the led-button FSM presented
* above by using the transition table approach with signal-queue and a timeout
* specification.
*
* Before getting started, the required variables should be defined:
*
*  @code{.c}
*  /*define the FSM application event-signals*/
*  enum : sm::signalIDType {
*      SIGNAL_BUTTON_PRESSED = sm::SIGNAL_USER( 1 ),
*      SIGNAL_DELAY          = sm::SIGNAL_TIMEOUT( 0 ),
*      SIGNAL_BLINK          = sm::SIGNAL_TIMEOUT( 1 ),
*  };
*
*  task LED_Task; /*The task node*/
*  stateMachine LED_FSM; /*The state-machine handler*/
*  sm::state State_LEDOff, State_LEDOn, State_LEDBlink;
*  sm::signalQueue<5> LEDsigqueue;
*  sm::timeoutSpec tm_spectimeout;
*
*  /*create the transition tables for every state*/
*  sm::transition LEDOff_transitions[] = {
*      { SIGNAL_BUTTON_PRESSED, State_LEDOn}
*  };
*
*  sm::transition LEDOn_transitions[] = {
*      { SIGNAL_DELAY,          State_LEDOff   },
*      { SIGNAL_BUTTON_PRESSED, State_LEDBlink }
*  };
*
*  sm::transition LEDBlink_transitions[] = {
*      { SIGNAL_DELAY,          State_LEDOff },
*      { SIGNAL_BUTTON_PRESSED, State_LEDOff }
*  };
*
*  /*define the timeout specifications */
*  sm::timeoutStateDefinition LedOn_Timeouts[] = {
*      { 10_sec,  sm::TIMEOUT_USE_SIGNAL( 0 ) | sm::TIMEOUT_SET_ENTRY | sm::TIMEOUT_RST_EXIT },
*  };
*
*  sm::timeoutStateDefinition LEDBlink_timeouts[] = {
*      { 10_sec,  sm::TIMEOUT_USE_SIGNAL( 0 ) | sm::TIMEOUT_SET_ENTRY  | sm::TIMEOUT_RST_EXIT },
*      { 0.5_sec, sm::TIMEOUT_USE_SIGNAL( 1 ) | sm::TIMEOUT_SET_ENTRY  | sm::TIMEOUT_RST_EXIT | sm::TIMEOUT_PERIODIC }
*  };
*  @endcode
*
* Then, we define the callback for the states.
*
*  @code{.c}
*  sm::status State_LEDOff_Callback( sm::handler_t h ) {
*      switch ( h.signal() ) {
*          case sm::signalID::SIGNAL_ENTRY:
*              BSP_LED_OFF();
*              break;
*          default:
*              break;
*      }
*      return sm::status::SUCCESS;
*  }
*  /*---------------------------------------------------------------------*/
*  sm::status State_LEDOn_Callback( sm::handler_t h ) {
*      switch ( h.signal() ) {
*          case sm::signalID::SIGNAL_ENTRY:
*              BSP_LED_ON();
*              break;
*          default:
*              break;
*      }
*      return sm::status::SUCCESS;
*  }
*  /*---------------------------------------------------------------------*/
*  sm::status State_LEDBlink_Callback( sm::handler_t h ) {
*      switch ( h.signal() ) {
*          case SIGNAL_BLINK:
*              BSP_LED_TOGGLE();
*              break;
*          default:
*              break;
*      }
*      return sm::status::SUCCESS;
*  }
*  @endcode
*
* In the previous code snippet, we assumed that @c SIGNAL_BUTTON_PRESSED can be
* delivered from either the interrupt context or another task.
*
* To finish the setup, a task is added to handle the FSM and then, the
* transition table can be installed with the other required objects.
*
*  @code{.c}
*  LED_FSM.setup( nullptr, State_LEDOff );
*  LED_FSM.add( State_LEDOff, State_LEDOff_Callback );
*  LED_FSM.add( State_LEDOn, State_LEDOn_Callback );
*  LED_FSM.add( State_LEDBlink, State_LEDBlink_Callback );
*
*  LED_FSM.install( LEDsigqueue );
*  LED_FSM.install( tm_spectimeout );
*
*  State_LEDOff.install( LEDOff_transitions );
*  State_LEDOn.install( LEDOn_transitions, LedOn_Timeouts );
*  State_LEDBlink.install( LEDBlink_transitions, LEDBlink_timeouts );
*
*  os.add( LED_Task, LED_FSM, core::MEDIUM_PRIORITY, 100_ms );
*  @endcode
*
* @section qfsm_happroach Using the hierarchical approach
* In conventional state machine designs, all states are considered at the same
* level. The design does not capture the commonality that exists among states.
* In real life, many states handle most transitions in similar fashion and
* differ only in a few key components. Even when the actual handling differs,
* there is still some commonality. It is in these situations where the
* hierarchical designs make the most sense.
*
* A hierarchical state-machine is characterized by having compound states. A
* composite state is defined as state that has inner states and can be used as a
* decomposition mechanism that allows factoring of common behaviors and their
* reuse. And this is the biggest advantage of this design, because it captures
* the commonality by organizing the states as a hierarchy. The states at the
* higher level in the hierarchy perform the common handling, while the lower level
* states inherit the commonality from higher level ones and perform the state
* specific functions.
*
* @subsection q_fsm_example3 Example using a hierarchical FSM
* This example takes the "Cruise Control" study case, a real-time system that
* manages the speed of an automobile based on inputs from the driver.
*
* <center>
* @htmlonly
* <!DOCTYPE html>
* <html>
* <head>
* <title>hsm</title>
* <meta charset="utf-8"/>
* </head>
* <body><div class="mxgraph" style="max-width:100%;border:1px solid transparent;" data-mxgraph="{&quot;highlight&quot;:&quot;#0000ff&quot;,&quot;nav&quot;:true,&quot;zoom&quot;:1.5,&quot;resize&quot;:true,&quot;toolbar&quot;:&quot;zoom layers tags lightbox&quot;,&quot;edit&quot;:&quot;_blank&quot;,&quot;xml&quot;:&quot;&lt;mxfile host=\&quot;app.diagrams.net\&quot; modified=\&quot;2022-10-19T16:51:35.501Z\&quot; agent=\&quot;5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 Safari/537.36\&quot; etag=\&quot;QdIZd3r2DwtN3vC1hyVB\&quot; version=\&quot;20.2.2\&quot; type=\&quot;google\&quot;&gt;&lt;diagram id=\&quot;Ucjj-E1xw4AO6E8yxrXi\&quot; name=\&quot;Página-1\&quot;&gt; &lt;/diagram&gt;&lt;/mxfile&gt;&quot;}"></div>
* <script type="text/javascript" src="https://viewer.diagrams.net/js/viewer-static.min.js"></script>
* </body>
* </html>
* @endhtmlonly
* <em>Cruise control FSM example</em>
* </center>
*
* The behavior of this system is state-dependent in that the executed actions
* correspond not only to the driver input, but also to the current state of the
* system and with the status of the engine and the brake.
* The figure above illustrates the modeling of this system with the
* "Automated Control" state acting as composite.
*
* Before getting started, the required user-defined signals, variables, and
* entries of the transition table should be defined:
*
*  @code{.c}
*  enum : sm::signalIDType {
*      SIGNAL_ENGINE_ON         = sm::SIGNAL_USER( 1 ),
*      SIGNAL_ACCEL             = sm::SIGNAL_USER( 2 ),
*      SIGNAL_RESUME            = sm::SIGNAL_USER( 3 ),
*      SIGNAL_OFF               = sm::SIGNAL_USER( 4 ),
*      SIGNAL_BRAKE_PRESSED     = sm::SIGNAL_USER( 5 ),
*      SIGNAL_CRUISE            = sm::SIGNAL_USER( 6 ),
*      SIGNAL_REACHED_CRUISING  = sm::SIGNAL_USER( 7 ),
*      SIGNAL_ENGINE_OFF        = sm::SIGNAL_USER( 8 ),
*  };
*
*  task CruiseControlTask;
*  stateMachine Top_SM;
*
*  /*highest level states*/
*  sm::state state_idle, state_initial, state_cruisingoff, state_automatedcontrol;
*  /*states inside the state_automatedcontrol*/
*  sm::state state_accelerating, state_cruising, state_resuming;
*  sm::signalQueue<10> top_sigqueue;
*
*  /*=======================================================================*/
*  /*                             TRANSITION TABLES                         */
*  /*=======================================================================*/
*  sm::transition idle_transitions[] = {
*       { SIGNAL_ENGINE_ON, SigAct_ClearDesiredSpeed, state_initial }
*  };
*
*  sm::transition initial_transitions[] = {
*       { SIGNAL_ACCEL, SigAct_BrakeOff, state_accelerating }
*  };
*
*  sm::transition accel_transitions[] = {
*       { SIGNAL_CRUISE, state_cruising }
*  };
*
*  sm::transition cruising_transitions[] = {
*       { SIGNAL_OFF,   state_cruisingoff },
*       { SIGNAL_ACCEL, state_accelerating }
*  };
*
*  sm::transition resuming_transitions[] = {
*       { SIGNAL_OFF,              state_cruisingoff },
*       { SIGNAL_ACCEL,            state_accelerating },
*       { SIGNAL_REACHED_CRUISING, state_cruising }
*  };
*
*  sm::transition cruisingoff_transitions[] = {
*       { SIGNAL_ACCEL,      SigAct_BrakeOff, state_accelerating },
*       { SIGNAL_RESUME,     SigAct_BrakeOff, state_resuming },
*       { SIGNAL_ENGINE_OFF, state_idle  }
*  };
*
*  sm::transition automated_transitions[] = {
*       { SIGNAL_BRAKE_PRESSED, state_cruisingoff }
*  };
*  /*---------------------------------------------------------------------*/
*  @endcode
*
* Then, signal-actions and state callbacks are later defined
*
*  @code{.c}
*  /*=======================================================================*/
*  /*                      EVENT-SIGNAL ACTIONS AND GUARDS                  */
*  /*=======================================================================*/
*  bool SigAct_ClearDesiredSpeed( sm::handler_t h ) {
*      (void)h;
*      Speed_ClearDesired();
*      return true;
*  }
*  /*---------------------------------------------------------------------*/
*  bool SigAct_BrakeOff( sm::handler_t h ) {
*      (void)h; /*unused*/
*      return ( BSP_BREAK_READ() == OFF ) ? true : false;  /*check guard*/
*  }
*  /*=======================================================================*/
*  /*                  STATE CALLBACK FOR THE TOP FSM                      */
*  /*=======================================================================*/
*  sm::status state_top_callback( sm::handler_t h ) {
*      sm::status RetVal = sm::status::SUCCESS;
*      switch ( h.signal() ) {
*          case sm::signalID::SIGNAL_ENTRY:
*              break;
*          case sm::signalID::SIGNAL_EXIT:
*              break;
*      }
*      return RetVal;
*  }
*  /*=======================================================================*/
*  /*                  CALLBACKS FOR THE STATES ABOVE TOP                    */
*  /*=======================================================================*/
*  sm::status state_idle_callback( sm::handler_t h ) {
*      /*TODO : state activities*/
*      return sm::status::SUCCESS;
*  }
*  /*---------------------------------------------------------------------*/
*  sm::status state_initial_callback( sm::handler_t h ) {
*      /*TODO : state activities*/
*      return sm::status::SUCCESS;
*  }
*  /*---------------------------------------------------------------------*/
*  sm::status state_cruisingoff_callback( sm::handler_t h ) {
*      /*TODO : state activities*/
*      return sm::status::SUCCESS;
*  }
*  /*---------------------------------------------------------------------*/
*  sm::status state_automatedcontrol_callback( sm::handler_t h ) {
*      /*TODO : state activities*/
*      return sm::status::SUCCESS;
*  }
*  /*=======================================================================*/
*  /*          STATE CALLBACKS FOR THE AUTOMATED CONTROL FSM                */
*  /*=======================================================================*/
*  sm::status state_accelerating_callback( sm::handler_t h ) {
*      switch ( h.signal() ) {
*          case sm::signalID::SIGNAL_EXIT:
*              Speed_SelectDesired();
*              break;
*          default:
*              Speed_Increase();
*              break;
*      }
*      return sm::status::SUCCESS;
*  }
*  /*---------------------------------------------------------------------*/
*  sm::status state_resuming_callback( sm::handler_t h ) {
*      Cruising_Resume();
*      return sm::status::SUCCESS;
*  }
*  /*---------------------------------------------------------------------*/
*  sm::status state_cruising_callback( sm::handler_t h ) {
*      Speed_Maintain();
*      return sm::status::SUCCESS;
*  }
*
*  @endcode
*
* Finally, the dedicated task for the FSM and related objects are configured.
*
*  @code{.c}
*  Top_SM.setup( state_top_callback, state_idle );
*  /*subscribe to the highest level states*/
*  Top_SM.add( state_idle, state_idle_callback );
*  Top_SM.add( state_initial, state_initial_callback );
*  Top_SM.add( state_cruisingoff, state_cruisingoff_callback );
*  Top_SM.add( state_automatedcontrol, state_automatedcontrol_callback );
*  /*subscribe to the states within the state_automatedcontrol*/
*  state_automatedcontrol.add( state_accelerating, state_accelerating_callback );
*  state_automatedcontrol.add( state_resuming, state_resuming_callback );
*  state_automatedcontrol.add( state_cruising, state_cruising_callback );
*  Top_SM.install( top_sigqueue );
*
*  state_idle.install( idle_transitions );
*  state_initial.install( initial_transitions );
*  state_cruisingoff.install( cruisingoff_transitions );
*  state_automatedcontrol.install( automated_transitions );
*  state_accelerating.install( accel_transitions );
*  state_resuming.install( resuming_transitions );
*  state_cruising.install( cruising_transitions );
*
*  os.add( CruiseControlTask, Top_SM, core::MEDIUM_PRIORITY, 100_ms );
*  @endcode
*
* @subsection q_fsm_example4 Example with history pseudo-states
* State transitions defined in high-level composite states often deal with
* events that require immediate attention; however, after handling them, the
* system should return to the most recent substate of the given composite state.
* UML statecharts address this situation with two kinds of history pseudostates:
* @a "shallow history" and @a "deep history"( denoted as the circled @c H and
* @c H* icon respectively in the figure).
*
* <center>
* @htmlonly
* <!DOCTYPE html>
* <html>
* <head>
* <title>fsmhist</title>
* <meta charset="utf-8"/>
* </head>
* <body><div class="mxgraph" style="max-width:100%;border:1px solid transparent;" data-mxgraph="{&quot;highlight&quot;:&quot;#0000ff&quot;,&quot;nav&quot;:true,&quot;zoom&quot;:1.5,&quot;resize&quot;:true,&quot;toolbar&quot;:&quot;zoom layers tags lightbox&quot;,&quot;edit&quot;:&quot;_blank&quot;,&quot;xml&quot;:&quot;&lt;mxfile host=\&quot;app.diagrams.net\&quot; modified=\&quot;2022-10-19T18:43:21.516Z\&quot; agent=\&quot;5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 Safari/537.36\&quot; etag=\&quot;Ch7yXC-GbSBqROWlSNdq\&quot; version=\&quot;20.4.1\&quot; type=\&quot;google\&quot;&gt;&lt;diagram id=\&quot;sgRdDsJHhmN2pV4VL9Bt\&quot; name=\&quot;Página-1\&quot;&gt; &lt;/diagram&gt;&lt;/mxfile&gt;&quot;}"></div>
* <script type="text/javascript" src="https://viewer.diagrams.net/js/viewer-static.min.js"></script>
* </body>
* </html>
* @endhtmlonly
* <em>Example with history pseudo-states</em>
* </center>
*
* - @a Shallow @a history : A transition to the shallow history state in a
* composite state invokes the last state that was active, at the same depth as
* the history state itself, prior to the most recent exit of the composite state.
* - @a Deep @a history : A transition to the deep history state within a
* composite state invokes the state that was active, immediately before the most
* recent exit of the composite state. The last active state can be nested at any
* depth.
*
* Here, the way to specify this type of transition in QuarkTS++ is very
* straightforward, you only need to assign the history-mode in the last entry
* of the transition as shown below:
*
*  @code{.c}
*  enum : sm::signalIDType {
*      SIGNAL_A  = sm::SIGNAL_USER( 1 ),
*      SIGNAL_B  = sm::SIGNAL_USER( 2 ),
*      SIGNAL_C  = sm::SIGNAL_USER( 3 ),
*      SIGNAL_D  = sm::SIGNAL_USER( 4 ),
*      SIGNAL_E  = sm::SIGNAL_USER( 5 ),
*      SIGNAL_F  = sm::SIGNAL_USER( 6 ),
*  };
*
*  sm::signalQueue<10> sigqueue;
*  stateMachine super;
*  sm::state state1 , state2 , state3 , state4 , state5 , state6;
*
*  sm::transition state1_transitions [] = {
*      { SIGNAL_A , state2 , sm::historyMode::SHALLOW_HISTORY },
*      { SIGNAL_B , state2 , sm::historyMode::DEEP_HISTORY },
*      { SIGNAL_C , state2 }
*  };
*
*  sm::transition state2_transitions [] = {
*      { SIGNAL_D , state1  }
*  };
*
*  sm::transition state3_transitions [] = {
*      { SIGNAL_E , state4 }
*  };
*
*  sm::transition state5_transitions [] = {
*      { SIGNAL_F , state6 }
*  };
*  @endcode
*
* Next, the configuration and topology of the state-machine is presented,
* including the default transitions (the small circles filled with black).
* Please do not forget to define the callbacks for each state.
*
*  @code{.c}
*  super.setup( state_top_callback , state1 );
*  super.add( state1 , state1_callback );
*  super.add( state2 , state2_callback, state3 );
*  state2.add( state3, state3_callback );
*  state2.add( state4, state4_callback, state5 );
*  state4.add( state5, state5_callback );
*  state4.add( state6, state6_callback );
*
*  super.installSignalQueue( sigqueue );
*  state1.install( state1_transitions );
*  state2.install( state2_transitions );
*  state3.install( state3_transitions );
*  state5.install( state5_transitions );
*  os.add( SMTask , super , core::MEDIUM_PRIORITY, 100_ms );
*  @endcode
*
*/
