The**QP/Cframework**bringstogethertwomosteffectivetechniquesofstructuringevent-drivenembeddedsystems:<ahref="http://www.state-machine.com/doc/concepts.html#Active"target="_blank"class="extern">active objects</a> and <a href="http://www.state-machine.com/doc/concepts.html#HSM" target="_blank" class="extern">hierarchical state machines</a> (UML statecharts). The following sections describe the main components and structure of the framework.
<p>Asshowninthediagrambelow,theQP/Cframeworkhasalayeredstructure.TheTargethardwaresitsatthebottom.TheBoardSupportPackage(BSP)aboveitprovidesaccesstotheboard-specificfeatures,suchastheperipherals.Thereal-timekernel(QV,QK,QXK,oraconventional3rd-partyRTOS)providesthefoundationformultitasking,suchastaskscheduling,context-switching,andinter-taskcommunication.Basedontheseservices,theevent-drivenframework(QF)suppliestheevent-driveninfrastructureforexecuting<ahref="http://www.state-machine.com/doc/concepts.html#Active"target="_blank"class="extern">active objects</a> and ensuring thread-safe event-driven exchanges among them. Finally, the event-processor (QEP) implements the hierarchical state machine semantics (based on UML statecharts). The top layer is the application-level code consisting of loosely-coupled active objects.
@imagehtmlqp_components.jpg"Components of the QP Framework"
@n
<divclass="separate"></div>
@subsectioncomp_qepQEPHierarchicalEventProcessor
QEPisauniversal,UML-complianteventprocessorthatprovidesimplementationof<ahref="http://www.state-machine.com/doc/concepts.html#HSM"target="_blank"class="extern">hierarchical state machines</a> (UML statecharts) in highly readable ANSI-C. The hallmark of QEP implementation strategy is **traceability**, which means that every state machine element is mapped to code precisely, unambiguously, and exactly once. QEP fully supports hierarchical state nesting, which is the fundamental mechanism for reusing behavior across many states instead of repeating the same actions and transitions over and over again. (<span class="highlight">See @ref qep for detailed documentation</span>).
<divclass="separate"></div>
@subsectioncomp_qfQFActive-ObjectFramework
QFisalightweight,event-driven,<ahref="http://www.state-machine.com/doc/concepts.html#Framework"target="_blank"class="extern">active object framework</a> specifically designed for real-time embedded (RTE) systems. The main job of the framework is to guarantee **thread-safe**, run-to-completion event processing within each <a href="http://www.state-machine.com/doc/concepts.html#Active" target="_blank" class="extern">active object</a>. This includes direct event posting as well as publish-subscribe event delivery, event queuing, and time events (time-delayed requests for posing events). (<span class="highlight">See @ref qf for detailed documentation</span>).
<divclass="separate"></div>
@subsectioncomp_qvQVCooperativeKernel
QVisasimplecooperativekernel(previouslycalled"Vanilla"kernel).Thiskernelalwaysprocessesoneeventatatimetocompletion,andperformspriority-basedschedulingofactiveobjectsafterprocessingofeachevent.TheQVkernelis"implicitly-cooperative",becausetheactiveobjectdonotneedtoyieldtheCPUexplicitly.Instead,theysimplyreturntotheQVscheduleraftercompletionofeventprocessing.Duetonaturallyshortdurationofeventprocessinginstatemachines,thesimpleQVkernelisoftenadequateformanyreal-timesystems.(<spanclass="highlight">See @ref qv for detailed documentation</span>). This is the fastest, smallest, and easiest-to-understand way of executing active objects.
<divclass="separate"></div>
@subsectioncomp_qkQKPreemptiveNon-BlockingKernel
QKisanultra-fast**preemptive**,priority-based,single-stack,real-timekerneldesignedspecificallyforexecutingactiveobjects.TheQKkernelalwaysexecutesthehighest-priorityactiveobjectthathasevent(s)queuedup,butitprocesseseventsasone-shotfunctioncalls(insteadofendlessloops,astraditionalRTOSkernels).Still,theQKkernelallowstheseone-shotevent-processingfunctionstopreempteachother,ifthepriorityoftheneweventishigherthanthecurrently-processedevent(verymuchlikeprioritizedinterruptcontrollersallowinterruptstopreempteachother).ThismeansthatQKcanuse_singlestack_forkeepingthecontextallactiveobjects(inthesamewayasprioritizedinterruptcontrollersuseasinglestacktonestallinterrupts).QKmeetsalltherequirementofthe<aclass="extern" target="_blank" href="http://en.wikipedia.org/wiki/Rate-monotonic_scheduling"><strong>Rate Monotonic Scheduling</strong></a> (a.k.a. Rate Monotonic Analysis — RMA) and can be used in hard real-time systems. (<span class="highlight">See @ref qk for detailed documentation</span>).
<divclass="separate"></div>
@subsectioncomp_qxkQXKPreemptiveBlockingKernel
QXKisasimplepreemptive,priority-based,**blocking**,real-timekerneldesignedspecificallyformixingactiveobjectswithtraditionalblockingcode,suchascommercialmiddleware(TCP/IPstacks,UDPstacks,embeddedfilesystems,etc.)orlegacycode.QXKworkslikemostconventional**RTOS**kernels,andlikemostofsuchkernelsrequireseverythread(activeobjectandevery"naked"thread)toprovideaseparateprivatestack.Thekernelprovidesausualassortmentofblockingfacilities,suchastimed-delays,semaphores,mutexes,andblockingmessagequeues.QXKmeetsalltherequirementofthe<aclass="extern" target="_blank" href="http://en.wikipedia.org/wiki/Rate-monotonic_scheduling"><strong>Rate Monotonic Scheduling</strong></a> (a.k.a. Rate Monotonic Analysis — RMA) and can be used in hard real-time systems. (<span class="highlight">See @ref qxk for detailed documentation</span>).
TheQuantumLeapsApplicationNote<aclass="extern" target="_blank" href="http://www.state-machine.com/doc/AN_OOP_in_C.pdf"><strong>Object-Oriented Programming in C</strong></a> describes how the OOP design patterns are implemented in QP/C and how you should code them in your own applications.
@imagehtmlqp_classes.gif"Main Classes in the QP Framework"
<ulclass="tag">
<li><spanclass="tag">0</span> The ::QEvt class represents events without parameters and serves as the base class for derivation of time events and any events with parameters. For example, application-level events `ObjectPosEvt` and `ObjectImageEvt` inherit ::QEvt and add to it some parameters (see [8]).
</li>
<li><spanclass="tag">1</span> The abstract ::QMsm class represents the most fundamental State Machine in QP/C. This class implements the fastest and the most efficient strategy for coding hierarchical state machines, but this strategy is not human-maintainable and requires the use of the <a class="extern" target="_blank" href="http://www.state-machine.com/qm">QM modeling tool</a>. The class is abstract, meaning that it is not designed to be instantiated directly, but rather only for inheritance. The @ref game application provides an example of application-level classes deriving directly from ::QMsm (see [7]).
</li>
<li><spanclass="tag">2</span> The abstract ::QHsm class derives from ::QMsm and implements the state machine coding strategy suitable for manual coding and maintaining the code. The ::QHsm strategy is also supported by the <a class="extern" target="_blank" href="http://www.state-machine.com/qm">QM modeling tool</a>, but is not as fast or efficient as the ::QMsm strategy.
</li>
<li><spanclass="tag">3</span> The abstract ::QMActive class represents an active object that uses the ::QMsm style state machine implementation strategy. This strategy requires the use of the QM modeling tool to generate state machine code automatically, but the code is faster than in the ::QHsm style implementation strategy and needs less run-time support (smaller event-processor).
</li>
<li><spanclass="tag">4</span> The abstract ::QActive class represents an active object that uses the ::QHsm style implementation strategy for state machines. This strategy is tailored to manual coding, but it is also supported by the QM modeling tool. The resulting code is slower than in the ::QMsm-style implementation strategy.
</li>
<li><spanclass="tag">5</span> The ::QTimeEvt class represents time events in QP. **Time events** are special QP events equipped with the notion of time passage. The basic usage model of the time events is as follows. An active object allocates one or more ::QTimeEvt objects (provides the storage for them). When the active object needs to arrange for a timeout, it arms one of its time events to fire either just once (one-shot) or periodically. Each time event times out independently from the others, so a QP application can make multiple parallel timeout requests (from the same or different active objects). When QP detects that the appropriate moment has arrived, it inserts the time event directly into the recipient's event queue. The recipient then processes the time event just like any other event.
</li>
<li><spanclass="tag">6</span> Active Objects in the application derive either from the ::QMActive or ::QActive base class.
</li>
<li><spanclass="tag">7</span> Applications can also use classes derived directly from the ::QMsm or ::QHsm base classes to represent "raw" state machines that are not active objects, because they don't have event queue and execution thread. Such "raw" state machines are typically used as "OrthogonalComponents".
</li>
<li><spanclass="tag">8</span> Application-level events with parameters derive from the ::QEvt class.
ThebehaviorofeachactiveobjectinQP/Cisspecifiedbymeansofa<ahref="http://www.state-machine.com/doc/concepts.html#HSM"target="_blank"class="extern">hierarchical state machine</a> (UML statechart), which is the most effective and elegant technique of decomposing event-driven behavior. The most important innovation of UML state machines over classical finite state machines (FSMs) is the hierarchical state nesting. The value of state nesting lies in avoiding repetitions, which are inevitable in the traditional "flat" FSM formalism and are the main reason for the "state-transitionexplosion" in FSMs. The semantics of state nesting allow substates to define only the differences of behavior from the superstates, thus promoting sharing and reusing behavior.
TheQuantumLeapsApplicationNote<aclass="extern" target="_blank" href="http://www.state-machine.com/doc/AN_Crash_Course_in_UML_State_Machines.pdf"><strong>A Crash Course in UML State Machines</strong></a> introduces the main state machine concepts backed up by examples.
TheQP/Cframeworkcomeswithextensivesupportforautomaticrulecheckingbymeansof<aclass="extern" target="_blank" href="http://www.gimpel.com/">PC-Lint</a>, which is designed not just for proving compliance of the QP/C framework code, but more importantly, to aid in checking compliance of the application-level code. Any organization engaged in designing safety-related embedded software could benefit from the unprecedented quality infrastructure built around the QP/C framework.