/*! @page q_foundations Fundamentals
* @tableofcontents
*
* @section rtcmodel RTC(Run To Completion) model
* In this pattern each task runs until it finishes or explicitly yields control
* back to the scheduler. Events are serviced by the kernel in the scheduler
* loop. If an event is available, it is posted to the task based on
* the scheduling @ref q_osrules "rules", and then the dispatcher triggers the
* task. The task executes the actions associated with that event and then
* returns to the scheduler.
*
* This pattern means that in the absence of exceptions or asynchronous
* destruction of the task execution, a pending event occurrence is dispatched
* only after the processing of the previous occurrence is completed, and a
* stable task-scheme configuration has been reached. That is, an event
* occurrence will never be dispatched while the task execution is busy
* processing the previous one. This behavioral paradigm was chosen to avoid
* complications arising from concurrency conflicts that may occur when a task
* tries to respond to multiple concurrent or overlapping events. This also
* provides better power efficiency. In the absence of events, the developer
* can use CPU low-power modes and make the core active only during the
* execution of a RTC step.
*
* The provided features enables you to implement task procedures that does not
* have to execute all the way down to the last line of code. Instead execution
* can be broken down into different entities by using @ref q_fsm or by using
* @ref q_qcoroutines where the procedure execution can be suspended and resumed
* at defined locations.
*
* @section q_timmingapproach Timing Approach
* The kernel implements a <a style="font-weight:bold" href="https://en.wikipedia.org/wiki/Time-triggered_architecture">Time-Triggered Architecture (TTA)</a>
* , in which the tasks are triggered by comparing the corresponding task-time
* with a reference clock. The reference clock must be real-time and follow a
* monotonic behavior. Usually, all embedded systems can provide this kind of
* reference with a constant tick generated by a periodic background
* hardware-timer, typically, at @c 1Khz or @c 1mS tick.
*
* For this, the kernel allows you to select the reference clock source among
* these two scenarios:
*
* - <b>When tick already provided</b>: The reference is supplied by the Hardware
* Abstraction Layer (HAL) of the device. It is the simplest scenario and it
* occurs when the framework or SDK of the embedded system includes a HAL-API
* that provides the time elapsed since the system starts, usually in milliseconds
* by returning a 32-bit counter variable.
*
* - <b>When the tick is not provided</b>: The application writer should use bare-metal
* code to configure the device and feed the reference clock manually. Here, a
* hardware timer should raise an interrupt periodically. After the <em>Interrupt
* Service Routine(ISR)</em> has been implemented using the platform-dependent code,
* the qOS::clock::sysTick() method must be called inside. It is recommended that the
* reserved ISR should only be used by QuarkTS++.
*
* The initialization and configuration of QuarkTS++ through qOS::core::init() will allow
* you to set the reference clock source in addition to specifying @ref q_idletask "Idle task"
* activities.
*
* @note The call to qOS::core::init() is mandatory and must be called once in the
* application main thread before any kind of interaction with the other OS
* functions.
*
* Usage example:
* - Scenario 1 : When tick is already provided
*  @code{.c}
*  #include "QuarkTS.h"
*  #include "HAL.h"
*
*  using namespace qOS;
*
*  void main( void ) {
*      HAL_Init();
*      os.init( HAL_GetTick , IdleTask_Callback );
*      // TODO: add Tasks to the scheduler scheme and run the OS
*  }
*  @endcode
*
* - Scenario 2 : When the tick is not provided
*  @code{.c}
*  #include "QuarkTS.h"
*  #include "DeviceHeader.h"
*
*  using namespace qOS;
*
*  void Interrupt_Timer0( void ) {
*      clock::sysTick();
*  }
*
*  void main( void ) {
       MCU_Init();
*      HAL_Init();
*      os.init( nullptr , IdleTask_Callback );
*      // TODO: add Tasks to the scheduler scheme and run the OS
*  }
*  @endcode
*
* @section q_tasks Tasks
* Like many operating systems, the basic unit of work is the task. Tasks can
* perform certain functions, which could require periodic or one-time execution,
* update specific variables or wait for specific events. Tasks also could
* be controlling specific hardware or be triggered by hardware interrupts. In
* the QuarkTS++ OS, a task is seen as a node concept that links together:
*
* - Program code performing specific task activities (callback function)
* - Execution interval (time)
* - Number of execution (iterations)
* - Event-based data
*
* The OS uses a <b>Task Control Block (TCB)</b> to represent each task, storing
* essential information about task management and execution. Part of this
* information also includes link-pointers that allow it to be part of one of
* the lists available in the <b>Kernel Control Block (KCB)</b>.
*
* <center>
* @htmlonly
* <!DOCTYPE html>
* <html>
* <head>
* <title>tasknode</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-18T13:11:02.654Z\&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;QycpXy9CV1RyLdRAMmhi\&quot; version=\&quot;20.2.2\&quot; type=\&quot;google\&quot;&gt;&lt;diagram id=\&quot;Wp6tzC3tOU-Ykbh8yUCR\&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>Task node illustration</em>
* </center>
*
* Each task performs its activities via a @a callback function and each of them is
* responsible for supporting cooperative multitasking by being “good neighbors”,
* i.e., running their callback methods quickly in a non-blocking way and
* releasing control back to the scheduler as soon as possible (returning).
*
* Every task node, must be defined using the qOS::task class and the callback
* is defined as a function that returns void and takes a qOS::event_t data structure
* as its only parameter (This input argument can be used later to get the event
* information, see @ref eventdata).
*
*  @code{.c}
*  task UserTask;
*  void UserTask_Callback( event_t e ) {
*      // TODO : Task code
*  }
*  @endcode
*
* Tasks can also be defined using the object-oriented programming approach. In
* this particular case, a class must be defined that inherits from qOS::task and
* the @c activities method, where the behavior of the task resides, must be
* overridden.
*
*  @code{.c}
*  class myCustomTask : public task {
*      void activities( event_t e ) override {
*          // TODO : Task code
*      }
*  };
*  @endcode
*
* @note All tasks in QuarkTS++ must ensure their completion to return the CPU
* control back to the scheduler to follow the @ref rtcmodel, otherwise, the
* scheduler will hold the execution state for that task, preventing the
* activation of other tasks.
*
* @subsection q_idletask The idle task
* It's a special task loaded by the OS scheduler when there is nothing else to
* do (no task in the whole scheme has reached the ready state). The idle task is
* already hard-coded into the kernel, ensuring that at least, one task is able
* to run. Additionally, the OS setup this task with the lowest possible priority
* to ensure that does not use any CPU time if there are higher priority
* application tasks able to run. The idle task doesn't perform any active
* functions, but the user can decide if it should perform some activities
* defining a callback function for it. This could be done at the beginning of
* the kernel setup. Of course, the callback must follow the same function
* prototype for tasks.
* @note To disable the idle-task activities, a @c nullptr should be passed as
* argument on qOS::core::init() or qOS::core::setIdleTask().
*
* @subsection q_addtasks Adding tasks to the scheme
* After setting up the kernel with qOS::core::init(), the user can proceed to deploy
* the multitasking application by adding tasks. If the task node and their
* respective callback is already defined, the task can be added to the scheme
* using qOS::core::add(). This method can schedule a task to run every @c t seconds,
* @c n executions times and invoking the @c callbackFcn method on every pass.
*
* <b> Caveats: </b>
*
* -# A task with time argument @c t defined as qOS::clock::IMMEDIATE, will always
* get the @c READY state in every scheduling cycle, as consequence, the idle
* task will never get dispatched.
* -# Tasks do not remember the number of iterations set initially by the
* @c n executions argument. After the iterations are done, the internal iteration
* counter decreases until reaches zero. If another set of iterations is
* needed, the user should set the number of iterations again and resume the
* task explicitly.
* -# Tasks that performed all their iterations, put their own state to
* qOS::taskState::DISABLED_STATE. Asynchronous triggers do not affect the iteration counter.
* -# The @c arg parameter can be used as a storage pointer, so, for multiple data,
* create a structure with the required members and pass a pointer to that
* structure.
*
* Invoking qOS::core::add() is the most generic way to add tasks to the scheme,
* supporting a mixture of time-triggered and event-triggered tasks, state-machine
* tasks, command-line interface tasks and input-watcher objects,
* additional simplified method functions are also provided to add specific purpose
* tasks:
*
* @subsection q_eventtasks Event-triggered tasks
* An event-triggered task reacts asynchronously to the occurrence of events in
* the system, such as external interrupts or changes in the available resources.
*
* The method qOS::core::add() can also support add this kind of tasks, keeping it
* in a @c SUSPENDED state. Only asynchronous events followed
* by their priority value dictate when a task can change to the @c RUNNING state.
*
* @subsection q_removetask Removing a task
* The qOS::core::remove() function removes the task from the scheduling scheme.
* This means the task node will be disconnected from the kernel chain,
* preventing additional overhead provided by the scheduler when it does checks
* over it and course, preventing it from running.
*
* <b> Caveats: </b>
*
* Task nodes are variables like any other. They allow your application code to
* reference a task, but there is no link back the other way and the kernel
* doesn't know anything about the variables, where the variable is allocated
* (stack, global, static, etc.) or how many copies of the variable you have
* made, or even if the variable still exists. So the qOS::core::remove() method
* cannot automatically free the resources allocated by the variable. If the task
* node has been dynamically allocated, the application writer it's responsible
* to free the memory block after a removal call.
*
* @section q_runos Running the OS
* After preparing the multitasking environment for your application, a call to
* qOS::core::run() is required to execute the scheduling scheme. This function is
* responsible to run the following OS main components:
*
* - <b>The Scheduler</b> : Select the tasks to be submitted into the system and decide
* with of them are able to run.
* - <b>The Dispatcher</b> : When the scheduler completes its job of selecting ready
* tasks, it is the dispatcher which takes that task to the running state. This
* procedure gives a task control over the CPU after it has been selected by the
* scheduler. This involves the following:
*    -# Preparing the resources before the task execution
*    -# Execute the task activities (via the callback function)
*    -# Releasing the resources after the task execution
*
* The states involved in the interaction between the scheduler and dispatcher
* are described @ref q_globalstates "here".
*
* @note  After calling qOS::core::run(), the OS scheduler will now be running, and the
* following line should never be reached, however, the user can optionally
* release it explicitly with qOS::core::schedulerRelease() method function.
*
* @subsection q_releasescheduler Releasing the scheduler
* This functionality must be enabled from the #Q_ALLOW_SCHEDULER_RELEASE
* macro. This method stops the kernel scheduling. In consequence, the main thread
* will continue after the qOS::core::run() call.
*
* Although producing this action is not a typical desired behavior in any
* application, it can be used to handle a critical exception.
*
* When used, the release will take place after the current scheduling cycle
* finishes. The kernel can optionally include a release callback function that can
* be configured to get called if the scheduler is released. Defining the release
* callback, will help to take actions over the exception that caused the release
* action. To perform a release action, the qOS::core::setSchedulerReleaseCallback()
* method should be used
*
* @note When a scheduler release is performed, resources are not freed. After
* released, the application can invoke the qOS::core::run() again to resume the
* scheduling activities
*
* @section q_globalstates Global states and scheduling rules
* A task can be in one of the four global states: @c RUNNING , @c READY , @c SUSPENDED or
* @c WAITING. Each of these states is tracked implicitly by putting the task in one of the
* associated kernel lists.
*
* These global states are described below:
*
* <center>
* @htmlonly
* <!DOCTYPE html>
* <html>
* <head>
* <title>taskstates++o</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;2023-04-21T05:03:17.324Z\&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;UdQzn4KYBgQScD1aLgyi\&quot; version=\&quot;21.2.1\&quot; type=\&quot;google\&quot;&gt;\n  &lt;diagram name=\&quot;Página-1\&quot; id=\&quot;WyOlZytWH3t5zvuPR2X6\&quot;&gt;\n    &lt;mxGraphModel dx=\&quot;1077\&quot; dy=\&quot;846\&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;6Vs2WzXcYxmmKBJyMSKu-1\&quot; value=\&quot;&amp;lt;b&amp;gt;&amp;lt;font color=&amp;quot;#808080&amp;quot;&amp;gt;RUNNING&amp;lt;/font&amp;gt;&amp;lt;/b&amp;gt;\&quot; style=\&quot;rounded=0;whiteSpace=wrap;html=1;strokeColor=#007FFF;fillColor=none;fontFamily=Helvetica;strokeWidth=2;\&quot; vertex=\&quot;1\&quot; parent=\&quot;1\&quot;&gt;\n          &lt;mxGeometry x=\&quot;100\&quot; y=\&quot;323\&quot; width=\&quot;90\&quot; height=\&quot;30\&quot; as=\&quot;geometry\&quot; /&gt;\n        &lt;/mxCell&gt;\n        &lt;mxCell id=\&quot;6Vs2WzXcYxmmKBJyMSKu-2\&quot; value=\&quot;\&quot; style=\&quot;rounded=0;whiteSpace=wrap;html=1;strokeColor=#999999;fillColor=none;fontFamily=Helvetica;strokeWidth=2;dashed=1;\&quot; vertex=\&quot;1\&quot; parent=\&quot;1\&quot;&gt;\n          &lt;mxGeometry x=\&quot;80\&quot; y=\&quot;412\&quot; width=\&quot;330\&quot; height=\&quot;151\&quot; as=\&quot;geometry\&quot; /&gt;\n        &lt;/mxCell&gt;\n        &lt;mxCell id=\&quot;6Vs2WzXcYxmmKBJyMSKu-3\&quot; value=\&quot;Dispatcher\&quot; style=\&quot;text;strokeColor=none;fillColor=none;align=left;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;fontStyle=1\&quot; vertex=\&quot;1\&quot; parent=\&quot;1\&quot;&gt;\n          &lt;mxGeometry x=\&quot;84\&quot; y=\&quot;283\&quot; width=\&quot;80\&quot; height=\&quot;30\&quot; as=\&quot;geometry\&quot; /&gt;\n        &lt;/mxCell&gt;\n        &lt;mxCell id=\&quot;6Vs2WzXcYxmmKBJyMSKu-4\&quot; value=\&quot;\&quot; style=\&quot;endArrow=classic;html=1;rounded=0;strokeColor=#007FFF;shadow=0;curved=1;strokeWidth=2;exitX=0;exitY=0;exitDx=0;exitDy=25;exitPerimeter=0;startArrow=none;\&quot; edge=\&quot;1\&quot; parent=\&quot;1\&quot; source=\&quot;6Vs2WzXcYxmmKBJyMSKu-11\&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;230\&quot; y=\&quot;338\&quot; as=\&quot;sourcePoint\&quot; /&gt;\n            &lt;mxPoint x=\&quot;190\&quot; y=\&quot;338\&quot; as=\&quot;targetPoint\&quot; /&gt;\n          &lt;/mxGeometry&gt;\n        &lt;/mxCell&gt;\n        &lt;mxCell id=\&quot;6Vs2WzXcYxmmKBJyMSKu-5\&quot; value=\&quot;\&quot; style=\&quot;verticalLabelPosition=bottom;verticalAlign=top;html=1;shape=mxgraph.basic.layered_rect;dx=10;outlineConnect=0;rounded=0;fontSize=16;strokeColor=#007FFF;strokeWidth=2;fillColor=#CCE5FF;\&quot; vertex=\&quot;1\&quot; parent=\&quot;1\&quot;&gt;\n          &lt;mxGeometry x=\&quot;279\&quot; y=\&quot;313\&quot; width=\&quot;100\&quot; height=\&quot;60\&quot; as=\&quot;geometry\&quot; /&gt;\n        &lt;/mxCell&gt;\n        &lt;mxCell id=\&quot;6Vs2WzXcYxmmKBJyMSKu-6\&quot; value=\&quot;READY\&quot; style=\&quot;text;strokeColor=none;fillColor=none;align=left;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;fontStyle=1\&quot; vertex=\&quot;1\&quot; parent=\&quot;1\&quot;&gt;\n          &lt;mxGeometry x=\&quot;296\&quot; y=\&quot;323\&quot; width=\&quot;80\&quot; height=\&quot;30\&quot; as=\&quot;geometry\&quot; /&gt;\n        &lt;/mxCell&gt;\n        &lt;mxCell id=\&quot;6Vs2WzXcYxmmKBJyMSKu-7\&quot; value=\&quot;\&quot; style=\&quot;verticalLabelPosition=bottom;verticalAlign=top;html=1;shape=mxgraph.basic.layered_rect;dx=10;outlineConnect=0;rounded=0;fontSize=16;strokeColor=#007FFF;strokeWidth=2;fillColor=#CCE5FF;\&quot; vertex=\&quot;1\&quot; parent=\&quot;1\&quot;&gt;\n          &lt;mxGeometry x=\&quot;95\&quot; y=\&quot;473\&quot; width=\&quot;100\&quot; height=\&quot;60\&quot; as=\&quot;geometry\&quot; /&gt;\n        &lt;/mxCell&gt;\n        &lt;mxCell id=\&quot;6Vs2WzXcYxmmKBJyMSKu-8\&quot; value=\&quot;SUSPENDED\&quot; style=\&quot;text;strokeColor=none;fillColor=none;align=left;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;fontStyle=1\&quot; vertex=\&quot;1\&quot; parent=\&quot;1\&quot;&gt;\n          &lt;mxGeometry x=\&quot;100\&quot; y=\&quot;482\&quot; width=\&quot;87\&quot; height=\&quot;30\&quot; as=\&quot;geometry\&quot; /&gt;\n        &lt;/mxCell&gt;\n        &lt;mxCell id=\&quot;6Vs2WzXcYxmmKBJyMSKu-9\&quot; value=\&quot;\&quot; style=\&quot;verticalLabelPosition=bottom;verticalAlign=top;html=1;shape=mxgraph.basic.layered_rect;dx=10;outlineConnect=0;rounded=0;fontSize=16;strokeColor=#007FFF;strokeWidth=2;fillColor=#CCE5FF;\&quot; vertex=\&quot;1\&quot; parent=\&quot;1\&quot;&gt;\n          &lt;mxGeometry x=\&quot;281\&quot; y=\&quot;472\&quot; width=\&quot;100\&quot; height=\&quot;60\&quot; as=\&quot;geometry\&quot; /&gt;\n        &lt;/mxCell&gt;\n        &lt;mxCell id=\&quot;6Vs2WzXcYxmmKBJyMSKu-10\&quot; value=\&quot;WAITING\&quot; style=\&quot;text;strokeColor=none;fillColor=none;align=left;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;fontStyle=1\&quot; vertex=\&quot;1\&quot; parent=\&quot;1\&quot;&gt;\n          &lt;mxGeometry x=\&quot;293\&quot; y=\&quot;482\&quot; width=\&quot;87\&quot; height=\&quot;30\&quot; as=\&quot;geometry\&quot; /&gt;\n        &lt;/mxCell&gt;\n        &lt;mxCell id=\&quot;6Vs2WzXcYxmmKBJyMSKu-11\&quot; value=\&quot;\&quot; style=\&quot;rounded=0;whiteSpace=wrap;html=1;fontSize=16;fontColor=#808080;strokeColor=#007FFF;strokeWidth=2;labelBackgroundColor=#3399FF;fillStyle=solid;fillColor=#007FFF;\&quot; vertex=\&quot;1\&quot; parent=\&quot;1\&quot;&gt;\n          &lt;mxGeometry x=\&quot;230\&quot; y=\&quot;313\&quot; width=\&quot;10\&quot; height=\&quot;50\&quot; as=\&quot;geometry\&quot; /&gt;\n        &lt;/mxCell&gt;\n        &lt;mxCell id=\&quot;6Vs2WzXcYxmmKBJyMSKu-12\&quot; value=\&quot;\&quot; style=\&quot;endArrow=none;html=1;rounded=0;strokeColor=#007FFF;shadow=0;curved=1;strokeWidth=2;exitX=0;exitY=0;exitDx=0;exitDy=25;exitPerimeter=0;\&quot; edge=\&quot;1\&quot; parent=\&quot;1\&quot; source=\&quot;6Vs2WzXcYxmmKBJyMSKu-5\&quot; target=\&quot;6Vs2WzXcYxmmKBJyMSKu-11\&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;279\&quot; y=\&quot;338\&quot; as=\&quot;sourcePoint\&quot; /&gt;\n            &lt;mxPoint x=\&quot;190\&quot; y=\&quot;338\&quot; as=\&quot;targetPoint\&quot; /&gt;\n          &lt;/mxGeometry&gt;\n        &lt;/mxCell&gt;\n        &lt;mxCell id=\&quot;6Vs2WzXcYxmmKBJyMSKu-13\&quot; value=\&quot;\&quot; style=\&quot;rounded=0;whiteSpace=wrap;html=1;fontSize=16;fontColor=#808080;strokeColor=#007FFF;strokeWidth=2;labelBackgroundColor=#3399FF;fillStyle=solid;fillColor=#007FFF;rotation=-90;\&quot; vertex=\&quot;1\&quot; parent=\&quot;1\&quot;&gt;\n          &lt;mxGeometry x=\&quot;321\&quot; y=\&quot;412\&quot; width=\&quot;10\&quot; height=\&quot;50\&quot; as=\&quot;geometry\&quot; /&gt;\n        &lt;/mxCell&gt;\n        &lt;mxCell id=\&quot;6Vs2WzXcYxmmKBJyMSKu-14\&quot; value=\&quot;\&quot; style=\&quot;endArrow=classic;html=1;rounded=0;exitX=0;exitY=0;exitDx=45;exitDy=0;strokeColor=#007FFF;shadow=0;curved=1;strokeWidth=2;exitPerimeter=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;\&quot; edge=\&quot;1\&quot; parent=\&quot;1\&quot; source=\&quot;6Vs2WzXcYxmmKBJyMSKu-9\&quot; target=\&quot;6Vs2WzXcYxmmKBJyMSKu-13\&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;27\&quot; y=\&quot;169\&quot; as=\&quot;sourcePoint\&quot; /&gt;\n            &lt;mxPoint x=\&quot;-13\&quot; y=\&quot;169\&quot; as=\&quot;targetPoint\&quot; /&gt;\n          &lt;/mxGeometry&gt;\n        &lt;/mxCell&gt;\n        &lt;mxCell id=\&quot;6Vs2WzXcYxmmKBJyMSKu-15\&quot; value=\&quot;\&quot; style=\&quot;endArrow=classic;html=1;rounded=0;exitX=1;exitY=0.5;exitDx=0;exitDy=0;strokeColor=#007FFF;shadow=0;curved=1;strokeWidth=2;\&quot; edge=\&quot;1\&quot; parent=\&quot;1\&quot; source=\&quot;6Vs2WzXcYxmmKBJyMSKu-13\&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;326\&quot; y=\&quot;409\&quot; as=\&quot;sourcePoint\&quot; /&gt;\n            &lt;mxPoint x=\&quot;326\&quot; y=\&quot;375\&quot; as=\&quot;targetPoint\&quot; /&gt;\n          &lt;/mxGeometry&gt;\n        &lt;/mxCell&gt;\n        &lt;mxCell id=\&quot;6Vs2WzXcYxmmKBJyMSKu-16\&quot; value=\&quot;\&quot; style=\&quot;endArrow=classic;html=1;rounded=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;strokeColor=#007FFF;shadow=0;curved=1;strokeWidth=2;\&quot; edge=\&quot;1\&quot; parent=\&quot;1\&quot; source=\&quot;6Vs2WzXcYxmmKBJyMSKu-1\&quot; target=\&quot;6Vs2WzXcYxmmKBJyMSKu-7\&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;336\&quot; y=\&quot;419\&quot; as=\&quot;sourcePoint\&quot; /&gt;\n            &lt;mxPoint x=\&quot;145\&quot; y=\&quot;433\&quot; as=\&quot;targetPoint\&quot; /&gt;\n          &lt;/mxGeometry&gt;\n        &lt;/mxCell&gt;\n        &lt;mxCell id=\&quot;6Vs2WzXcYxmmKBJyMSKu-17\&quot; value=\&quot;system &amp;#xa;available\&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;fontStyle=2;fontSize=11;\&quot; vertex=\&quot;1\&quot; parent=\&quot;1\&quot;&gt;\n          &lt;mxGeometry x=\&quot;195\&quot; y=\&quot;283\&quot; width=\&quot;80\&quot; height=\&quot;30\&quot; as=\&quot;geometry\&quot; /&gt;\n        &lt;/mxCell&gt;\n        &lt;mxCell id=\&quot;6Vs2WzXcYxmmKBJyMSKu-18\&quot; value=\&quot;event &amp;#xa;condition&amp;#xa;fulfilled\&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;fontStyle=2;fontSize=11;\&quot; vertex=\&quot;1\&quot; parent=\&quot;1\&quot;&gt;\n          &lt;mxGeometry x=\&quot;341\&quot; y=\&quot;416\&quot; width=\&quot;80\&quot; height=\&quot;45\&quot; as=\&quot;geometry\&quot; /&gt;\n        &lt;/mxCell&gt;\n        &lt;mxCell id=\&quot;6Vs2WzXcYxmmKBJyMSKu-19\&quot; value=\&quot;not meet&amp;#xa;the condition\&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;fontStyle=2;fontSize=11;\&quot; vertex=\&quot;1\&quot; parent=\&quot;1\&quot;&gt;\n          &lt;mxGeometry x=\&quot;199\&quot; y=\&quot;437\&quot; width=\&quot;80\&quot; height=\&quot;45\&quot; as=\&quot;geometry\&quot; /&gt;\n        &lt;/mxCell&gt;\n        &lt;mxCell id=\&quot;6Vs2WzXcYxmmKBJyMSKu-20\&quot; value=\&quot;\&quot; style=\&quot;endArrow=classic;html=1;rounded=0;exitX=0;exitY=0;exitDx=0;exitDy=12.5;strokeColor=#007FFF;shadow=0;curved=1;strokeWidth=2;exitPerimeter=0;\&quot; edge=\&quot;1\&quot; parent=\&quot;1\&quot; source=\&quot;6Vs2WzXcYxmmKBJyMSKu-9\&quot; target=\&quot;6Vs2WzXcYxmmKBJyMSKu-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;336\&quot; y=\&quot;442\&quot; as=\&quot;sourcePoint\&quot; /&gt;\n            &lt;mxPoint x=\&quot;336\&quot; y=\&quot;385\&quot; as=\&quot;targetPoint\&quot; /&gt;\n            &lt;Array as=\&quot;points\&quot;&gt;\n              &lt;mxPoint x=\&quot;240\&quot; y=\&quot;473\&quot; /&gt;\n            &lt;/Array&gt;\n          &lt;/mxGeometry&gt;\n        &lt;/mxCell&gt;\n        &lt;mxCell id=\&quot;6Vs2WzXcYxmmKBJyMSKu-21\&quot; value=\&quot;\&quot; style=\&quot;endArrow=classic;html=1;rounded=0;strokeColor=#007FFF;shadow=0;curved=1;strokeWidth=2;entryX=0;entryY=0;entryDx=0;entryDy=37.5;entryPerimeter=0;\&quot; edge=\&quot;1\&quot; parent=\&quot;1\&quot; target=\&quot;6Vs2WzXcYxmmKBJyMSKu-9\&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;190\&quot; y=\&quot;513\&quot; as=\&quot;sourcePoint\&quot; /&gt;\n            &lt;mxPoint x=\&quot;336\&quot; y=\&quot;385\&quot; as=\&quot;targetPoint\&quot; /&gt;\n            &lt;Array as=\&quot;points\&quot;&gt;\n              &lt;mxPoint x=\&quot;240\&quot; y=\&quot;523\&quot; /&gt;\n            &lt;/Array&gt;\n          &lt;/mxGeometry&gt;\n        &lt;/mxCell&gt;\n        &lt;mxCell id=\&quot;6Vs2WzXcYxmmKBJyMSKu-22\&quot; value=\&quot;Scheduler\&quot; style=\&quot;text;strokeColor=none;fillColor=none;align=left;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;fontStyle=1\&quot; vertex=\&quot;1\&quot; parent=\&quot;1\&quot;&gt;\n          &lt;mxGeometry x=\&quot;338\&quot; y=\&quot;533\&quot; width=\&quot;80\&quot; height=\&quot;30\&quot; as=\&quot;geometry\&quot; /&gt;\n        &lt;/mxCell&gt;\n        &lt;mxCell id=\&quot;6Vs2WzXcYxmmKBJyMSKu-23\&quot; value=\&quot;\&quot; style=\&quot;rounded=0;whiteSpace=wrap;html=1;strokeColor=#999999;fillColor=none;fontFamily=Helvetica;strokeWidth=2;dashed=1;\&quot; vertex=\&quot;1\&quot; parent=\&quot;1\&quot;&gt;\n          &lt;mxGeometry x=\&quot;80\&quot; y=\&quot;280\&quot; width=\&quot;330\&quot; height=\&quot;111\&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>Task global states</em>
* </center>
*
* - @c WAITING : The task cannot run because the conditions for running are
* not in place.
* - @c READY : The task has completed preparations for running, but cannot run
* because a task with higher precedence is running.
* - @c RUNNING : The task is currently being executed.
* - @c SUSPENDED : The task doesn't take part in what is going on. Normally
* this state is taken after the @c RUNNING state or when the task does not
* reach the @c READY state.
*
* The presence of a task in a particular list indicates the task's state. There
* are many ready lists as defined in the #Q_PRIORITY_LEVELS macro. To select
* the target ready list, the OS uses the user-assigned priority between 0 (the
* lowest priority) and @c Q_PRIORITY_LEVELS-1 (the highest priority). For
* instance, if #Q_PRIORITY_LEVELS is set to 5, then QuarkTS++ will use 5
* priority levels or ready lists: 0 (lowest priority), 1, 2, 3, and 4 (highest
* priority).
*
* <center>
* @htmlonly
* <!DOCTYPE html>
* <html>
* <head>
* <title>oslist</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.4,&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-18T13:21:59.751Z\&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;qu1SGjoOBtXo91H1rG-O\&quot; version=\&quot;20.2.2\&quot; type=\&quot;google\&quot;&gt;&lt;diagram id=\&quot;a3gmjD7FvNUACDKGX7UC\&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>OS lists</em>
* </center>
*
* Except for the idle task, a task exists in one of these states. As the
* real-time embedded system runs, each task moves from one state to another
* (moving it from one list to another), according to the logic of a simple finite
* state machine (FSM). The figure above illustrates the typical flowchart used
* by QuarkTS++ to handle the task's states, with brief descriptions of the state
* transitions, additionally you may also notice the interaction between the
* scheduler and the dispatcher.
*
* The OS assumes that none of the tasks does a block anywhere during the
* @c RUNNING state. Based on the round-robin fashion, each ready task runs in
* turn from every ready list. The developer should take care to monitor their
* system execution times to make sure during the worst case, when all tasks have
* to execute, all of the deadlines are still met.
*
* @subsection q_osrules Rules
*
* Task precedence is used as the task scheduling rule and precedence among tasks
* is determined based on the priority of each task. If there are multiple tasks
* able to run, the one with the highest precedence goes to @c RUNNING state
* first.
*
* In determining precedence among tasks of those tasks having different
* priority levels, that with the highest priority has the highest precedence.
* Among tasks having the same priority, the one that entered the scheduling
* scheme first has the highest precedence if the #Q_PRESERVE_TASK_ENTRY_ORDER
* configuration is enabled, otherwise, the OS will reserves for himself the order
* according to the dynamics of the kernel lists.
*
* @subsubsection q_os_evenprecedence Event precedence
* The scheduler also has an order of precedence for incoming events, in this
* way, if events of different natures converge to a single task, these will be
* served according to the following flowchart:
*
* <center>
* @htmlonly
* <!DOCTYPE html>
* <html>
* <head>
* <title>evenprecedence</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-18T13:23:50.297Z\&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;-HzyQrBmOm1BBi3Kbblc\&quot; version=\&quot;20.2.2\&quot; type=\&quot;google\&quot;&gt;&lt;diagram id=\&quot;rtI5oX9UaKnuX4kORaYA\&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>Event precedence</em>
* </center>
*
* @subsubsection q_os_operational_states Additional operational states
* Each task has independent operating states from those globally controlled by
* the scheduler. These states can be handled by the application writer to modify
* the event flow to the task and consequently, affect the transition to the
* @c READY global state. These states are described as follows:
*
* - @c AWAKE : In this state, the task is conceptually in an alert mode, handling
* most of the available events. This operational state is available when the
* @c SHUTDOWN bit is set, allowing the next operational states to be available:
*    - @c ENABLED : The task can catch all the events. This operational
* state is available when the @c ENABLE bit is set.
*    - @c DISABLED : In this state, the time events will be discarded. This
* operational state is available when the @c ENABLE bit is cleared.
* - @c ASLEEP : Task operability is put into a deep doze mode, so the task
* can not be triggered by the lower precedence events. This operational state
* is available when the @c SHUTDOWN bit is cleared. The task can exit from this
* operational state when it receives a high precedence event (a queued
* notification) or using the qOS::task::setState() method.
*
* The figure below shows a better representation of how the event flow can be
* affected by these operational states.
*
* <center>
* @htmlonly
* <!DOCTYPE html>
* <html>
* <head>
* <title>operationalstates</title>
* <meta charset="utf-8"/>
* </head>
* <body><div class="mxgraph" style="max-width:150%;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-18T13:25:47.962Z\&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;9dMBppV9Mj4qN3SqXlf-\&quot; version=\&quot;20.2.2\&quot; type=\&quot;google\&quot;&gt;&lt;diagram id=\&quot;FMHORikkxHPTSQ5eLvpY\&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>Event flow according operational states</em>
* </center>
*
* @remark Queued notifications are the only event that can wake up sleeping tasks
* @note The @c ASLEEP operational state overrides the @c ENABLED and
* @c DISABLED states.
*
* @section q_critical Critical sections
*
* Since the kernel is non-preemptive, the only critical sections that must be
* handled are those involving shared resources accessed from ISR context.
* The most straightforward way to achieve mutual exclusion is to temporarily
* disable interrupts before entering a critical section and re-enable them
* afterward.
*
* By disabling interrupts, the CPU cannot switch context, ensuring that the
* currently running job accesses shared resources safely. However, this must
* be done carefully and only for short periods. In QuarkTS++, critical
* sections are minimized to keep interrupt latency as small as possible.
*
* Because the kernel is hardware-independent, the application developer must
* provide the specific code for enabling and disabling interrupts.
*
* For this purpose, the qOS::critical::setInterruptsED() method should be
* used. It allows the kernel to safely coordinate communication between ISRs
* and tasks using queued notifications or data queues.
*
* Some MCUs require not only disabling global interrupt flags but also
* saving and restoring the interrupt configuration. The @c uint32_t argument
* and return values in the provided @c Disabler and @c Restorer functions are used
* for this purpose.
*
* When a critical section is performed:
* - The @c Disabler function disables interrupts and returns the previous
*   interrupt configuration.
* - The kernel stores this configuration internally.
* - After the critical section ends, the @c Restorer function restores
*   the saved configuration.
*
*
* @subsection q_critical_examples Examples
*
* @subsubsection regintfcns Registering the interrupt control functions
*
* Before using any critical section, the application must register the
* hardware-specific enable/disable routines:
*
* @code{.cpp}
* using namespace qOS;
*
* static uint32_t disableInterrupts() {
*     uint32_t primask = __get_PRIMASK();  // Read current interrupt state
*     __disable_irq();                      // Disable all interrupts
*     return primask;                       // Return the saved state
* }
*
* static void restoreInterrupts(uint32_t primask) {
*     if (!primask) {
*         __enable_irq();                   // Restore interrupt state
*     }
* }
*
* void main( void ) {
*     critical::setInterruptsED(restoreInterrupts, disableInterrupts);
*     /* TODO : Setup OS and add tasks*/
* }
* @endcode
*
*
* @subsubsection usecritscope Using critical::scope for quick inline protection
*
* This construct provides minimal syntax overhead for protecting short
* critical sections. The section is automatically exited when the scope ends.
*
* @code{.cpp}
* void example() {
*     // Normal code (non-critical)
*     critical::scope {
*         // This block runs with interrupts disabled
*         sharedCounter++;
*     }
*     // Back to normal code (interrupts enabled)
* }
* @endcode
*
*
* @subsubsection usecritlock Using critical::lock (RAII-style)
*
* The qOS::critical::lock class automatically manages entry and exit of a
* critical section using RAII semantics. When the object is created, interrupts
* are disabled; when it goes out of scope, interrupts are restored.
*
* @code{.cpp}
* void example() {
*     critical::lock lockGuard;   // interrupts disabled here
*
*     sharedBuffer.push(value);   // safe shared access
*
* } // lockGuard destroyed → interrupts restored
* @endcode
*
* @section q_configmacros Configuration macros
* Some OS features can be customized using a set of macros located in the header
* file @c config.h. Here is the default configuration, followed by an
* explanation of each macro:
*
* - @c Q_PRIORITY_LEVELS : @a Default: @c 3. The number of priorities available for
* application tasks.
* - @c Q_PRIO_QUEUE_SIZE : @a Default: @c 10. Size of the priority queue for
* notifications. This argument should be an integer number greater than zero.
* A zero value can be used to disable this functionality.
* - @c Q_ALLOW_SCHEDULER_RELEASE : @a Default: @c 0(disabled). Used to enable or
* disable the scheduler release functionality.
* - @c Q_PRESERVE_TASK_ENTRY_ORDER : @a Default: @c 0(disabled). If enabled,
* the kernel will preserve the tasks entry order every OS scheduling cycle.
* - @c Q_BYTE_ALIGNMENT : @a Default: @c 8. Used by the @ref q_memmang extension
* to perform the byte alignment.
* - @c Q_DEFAULT_HEAP_SIZE : @a Default: @c 2048.  The total amount of heap size
* for the default memory pool. This will enable @c new and @c delete operators
* if not available
* - @c Q_FSM : @a Default: @c 1(enabled). Used to enable or disable the Finite
State Machine (FSM) extension.
* - @c Q_FSM_MAX_NEST_DEPTH : @a Default: @c 5. The max depth of nesting in
* Finite State Machines (FSM).
* - @c Q_FSM_MAX_TIMEOUTS : @a Default: @c 3. Max number of timeouts inside a
* timeout specification for the @ref q_fsm extension.
* - @c Q_FSM_PS_SIGNALS_MAX : @a Default: @c 8. Max number of signals to
* subscribe for a Finite State Machine (FSM).
* - @c Q_FSM_PS_SUB_PER_SIGNAL_MAX : @a Default: @c 4. Max number of FSM
* subscribers per signal.
* - @c Q_DEBUGTRACE_BUFSIZE : @a Default: @c 36. The buffer size for debug and
* trace macros
* - @c Q_CLI : @a Default: @c 1(enabled). Used to enable or disable the
* @ref q_atcli extension.
*
*/