QP/C  6.9.3
Real-Time Embedded Framework
Structure and Features

Directories and Files

The following annotated directory tree lists the top-level directories provided in the standard QP/C distribution.

  • qpc/
    • 3rd_party/ — Third-Party code used in the QP/C ports and examples
    • examples/QP/C Examples
    • ports/QP/C Ports
    • include/ — Platform-independent QP/C API (see include)
    • src/ — Platform-independent QP/C source code (see src)
The standard QP/C distribution contains many Example Projects, which are specifically designed to help you learn to use QP/C and to serve you as starting points for your own projects.

Components of QP/C

As shown in the diagram below, the QP/C framework has a layered structure. The Target hardware sits at the bottom. The Board Support Package (BSP) above it provides access to the board-specific features, such as the peripherals. The real-time kernel (QV, QK, QXK, or a conventional 3rd-party RTOS) provides the foundation for multitasking, such as task scheduling, context-switching, and inter-task communication. Based on these services, the active object framework (QF) supplies the event-driven infrastructure for executing active objects 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.

Components of the QP Framework

QEP Hierarchical Event Processor

QEP is a universal "event processor" that provides implementation of hierarchical state machines (UML statecharts) in highly readable ISO-C. The hallmark of the QEP state machine 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. (See QEP for detailed documentation).

QF Active-Object Framework

QF is a lightweight, event-driven, active object framework 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 active object. This includes direct event posting as well as publish-subscribe event delivery, event queuing, and time events (time-delayed requests for posing events). (See QF for detailed documentation).

QV Cooperative Kernel

QV is a simple cooperative kernel (previously called "Vanilla" kernel). This kernel always processes one event at a time to completion, and performs priority-based scheduling of active objects after processing of each event. The QV kernel is "implicitly-cooperative", because the active object do not need to yield the CPU explicitly. Instead, they simply return to the QV scheduler after completion of event processing. Due to naturally short duration of event processing in state machines, the simple QV kernel is often adequate for many real-time systems. (See QV for detailed documentation). This is the fastest, smallest, and easiest to understand way of executing active objects.

QK Preemptive Non-Blocking Kernel

QK is an ultra-fast preemptive, priority-based, single-stack, real-time kernel designed specifically for executing active objects. The QK kernel always executes the highest-priority active object that has event(s) queued up, but it processes events as one-shot function calls (instead of endless loops, as traditional RTOS kernels). Still, the QK kernel allows these one-shot event-processing functions to preempt each other, if the priority of the new event is higher than the currently-processed event (very much like prioritized interrupt controllers allow interrupts to preempt each other). This means that QK can use single stack for keeping the context all active objects (in the same way as prioritized interrupt controllers use a single stack to nest all interrupts). QK meets all the requirement of the Rate Monotonic Scheduling (a.k.a. Rate Monotonic Analysis — RMA) and can be used in hard real-time systems. (See QK for detailed documentation).

QXK Preemptive Blocking Kernel

QXK is a small, preemptive, priority-based, dual-mode blocking kernel that executes active objects like the QK kernel (basic threads), but can also execute traditional blocking threads (extended threads). In this respect, QXK behaves exactly as a conventional RTOS (Real-Time Operating System). QXK has been designed specifically for mixing event-driven active objects with traditional blocking code, such as commercial middleware (TCP/IP stacks, UDP stacks, embedded file systems, etc.) or legacy software. QXK meets all the requirement of the Rate Monotonic Scheduling (a.k.a. Rate Monotonic Analysis — RMA) and can be used in hard real-time systems. (See QXK for detailed documentation).

QXK has most features you might expect of a traditional blocking RTOS kernel and is recommended as the preferred RTOS kernel for QP/C applications that need to mix active objects with traditional blocking code. Due to the tight and optimal integration between QXK and the rest of QP/C, QXK offers better performance and smaller memory footprint than any QP port to a 3rd-party RTOS.

QS Software Tracing Component

QS is software tracing target-resident component that enables developers to monitor live event-driven QP applications with minimal target system resources and without stopping or significantly slowing down the code. QS is an ideal tool for testing, troubleshooting, and optimizing QP applications. QS can even be used to support acceptance testing in product manufacturing. (See QS for detailed documentation).

Classes in QP/C

The figure below shows the main classes comprising the QP/C framework and their relation to the application-level code, such as the "Fly 'n' Shoot" Game example application (shown at the bottom 1/3 of the diagram).

Main Classes in the QP Framework

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]).


The abstract QHsm class represents a Hierarchical State Machine (HSM) with full support for hierarchical nesting of states, entry/exit actions, initial transitions, and transitions to history in any composite state. This class is designed for ease of manual coding of HSMs in C, but it is also supported by the QM modeling tool. QHsm is also the base class for the QMsm state machine, which provides a superior efficiency, but requires the use of the QM modeling tool to generate code.


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. The "Fly 'n' Shoot" Game application provides an example of application-level classes deriving from QActive and QHsm (see [6] and [7]).


The abstract QMsm class (QM State Machine) derives from QHsm and 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 QM modeling tool. The class is abstract, meaning that it is not designed to be instantiated directly, but rather only for inheritance.


The abstract QMActive class represents an active object that uses the QMsm 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).


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.


Active Objects in the application derive either from the QActive or QMActive base class.


Applications can also use classes derived directly from the QHsm or QMsm 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 "Orthogonal Components".

Application-level events with parameters derive from the QEvt class.

State Machines

The behavior of each active object in QP/C is specified by means of a hierarchical state machine (UML statechart), which is the most effective and elegant technique of describing 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-transition explosion" 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.

The Quantum Leaps Application Note A Crash Course in UML State Machines introduces the main state machine concepts backed up by examples.
Application Note: A Crash Course in UML State Machines
The hallmark of the QP/C implementation of UML state machines is traceability, which is direct, precise, and unambiguous mapping of every state machine element to human-readable, portable, MISRA-compliant C code. Preserving the traceability from requirements through design to code is essential for mission-critical systems, such as medical devices or avionic systems.

Software Tracing and Testing System

The QP/C RTEF supports the comprehensive QP/Spy software tracing system, which can be invaluable in debugging and optimizing QP/C applications by observing live interactions within the system. Apart from these benefits, the QP/Spy software tracing provides the foundation for the following facilities:

  • unit testing with QUTest
  • visualization & monitoring with QView
The QS software tracing instrumentation is only active in the Spy build configuration and is completely inactive in Release and Debug build configurations. Specifically, the QS instrumentation does not need to be removed or changed in any way in the production code. It is specifically designed to be safely left in the code, without causing any side effects.

Design by Contract

Design by Contract (DbC) is a philosophy that views a software system as a set of components whose collaboration is based on precisely defined specifications of mutual obligations — the contracts. The central idea of this method is to inherently embed the contracts in the code and validate them automatically at runtime. In C and C++, the most important aspects of DbC (the contracts) can be implemented with assertions. Assertions are increasingly popular among the developers of mission-critical software. For example, NASA requires certain density of assertions in such software.

In the context of the QP/C framework, DbC provides an excellent methodology for implementing a very robust error-handling policy. Due to inversion of control so typical in all event-driven systems, the QP/C framework controls many more aspects of the application than a traditional RTOS. A framework is in a much better position to make sure that the application is performing correctly, rather than the application to check error codes or catch exceptions originating from the framework.

Coding Standard

The QP/C framework has been developed in strict adherence to the documented Quantum Leaps Coding Standard.

Application Note: Quantum Leaps C/C++ Coding Standard

MISRA Compliance

The QP/C framework complies with most of the Motor Industry Software Reliability Association (MISRA) MISRA-C:2004 rules.

Application Note: QP/C MISRA-C:2004 Compliance Matrix

All deviations are carefully limited into very specific contexts and are documented with the Application Note: QP/C MISRA-C:2004 Compliance Matrix.

MISRA and MISRA C are registered trademarks of MIRA Ltd, held on behalf of the MISRA Consortium.

The MISRA guidelines place great emphasis on the use of static code analysts tools to check compliance with the MISRA-C language subset. To this end, QP/C comes with an extensive support for automatic rule checking with PC-Lint. The QP frameworks go even beyond MISRA, by complying with the strict type checking of PC-Lint.

PC-Lint-Plus Support

The QP/C framework comes with extensive support for automatic rule checking by means of PC-Lint-Plus, 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.

See also
Lint Port

Next: Examples