QP/C 8.1.3
Real-Time Event Framework
Loading...
Searching...
No Matches
Overview

About this DocumentActive Objects

QP/C is a lightweight, real-time event framework (RTEF) designed for embedded systems, such as microcontrollers but also embedded Linux/POSIX. The QP/C software framework provides the core runtime services needed to build event-driven applications based on Active Objects, Hierarchical State Machines, and asynchronous event delivery.

As a software component, QP/C supplies a well-defined set of abstractions and execution semantics that can be integrated into a larger system architecture. It provides both:

  • a runtime environment for executing Active Objects, and
  • a behavioral model based on hierarchical state machines for specifying the logic of those Active Objects.
Remarks
Even though this Software Requirement Specification focuses on the QP/C Framework component, the described features and requirements can be ultimately implemented in various programming languages, so the applicability of this SRS extends to the whole family of QP RTEFs, currently consisting of QP/C, QP/C++, SafeQP/C, and SafeQP/C++ frameworks implemented in C and C++, respectively. Other possible implementations (e.g., QP/Rust) of these requirements and features might be added in the future.

Goals

The primary goals of the QP/C component are:

  • to provide a modern, event-driven concurrency model based on the Active Object (Actor) model, incorporating best practices from concurrent programming
  • to offer a safer alternative to traditional shared-state, blocking, and mutex-based concurrency typically found in RTOS-based designs
  • to raise the level of abstraction for embedded developers by providing structured concepts such as Events, Active Objects, and Hierarchical State Machines
  • to support model-based development and code generation workflows
  • to bridge the semantic gap between high-level behavioral models (e.g., UML state machines) and low-level implementation in C

Functional Safety

QP/C incorporates architectural patterns and design principles that align with functional-safety best practices (e.g., structured methods, hierarchical state machines, modularity, traceability). These characteristics support its use within systems developed under standards such as IEC 61508, IEC 62304, and ISO 26262.

Context of Use

The following diagram (Figure SRS-BLK) illustrates the context in which the QP/C component operates within an embedded system.

Figure SRS-BLK: Block diagram showing the context and functional decomposition of a system based on QP/C Framework.

[1] The integratin QP/C Application:

  • defines event-driven Active Objects that implement system functionality
  • defines application-specific error handling and safe-state logic;
  • defines interrupt service routines (ISRs) that generate events for Active Objects

[2] The QP/C Framework component:

[3a] The Real-Time Kernel provides scheduling and execution context for the Active Objects. This could be one of the kernels built-into QP/C Frameworks (QV, QK, or QXK); or

[3b] Alternatively, QP/C Framework can operate with a 3-rd party RTOS kernel; or

[3c] Alternatively, QP/C Framework can operate with a General-Purpose OS (e.g., Linux/POSIX or Windows);

[4] The Board Support Package (BSP) provides:

  • hardware abstraction
  • interrupt configuration
  • time-base configuration
  • low-level initialization

[5] The Target Hardware (MCU + external components). The underlying microcontroller or processor on which QP/C executes.

Inversion of Control

Like most event-driven systems, the QP/C Framework is based on inversion of control, which means that the control of code execution resides in the QP/C Framework rather than the QP/C Application based on QP. Specifically, to handle events, QP/C Framework component calls the QP/C Application, and not the other way around. Of course, QP/C Applications can also call services provided in QP/C Framework, but the main flow of control always begins with the QP/C Framework.

Framework, NOT a Library

That inversion of control gives the event-driven infrastructure (QP/C) all the defining characteristics of a framework rather than a library.

The main difference between a framework and a library is that when you use a library, such as a conventional RTOS, you write the main body of each thread, and you call the library code that you want to reuse (e.g., a semaphore). When you use a framework, such as QP/C, you reuse the main body and write the code it calls (inversion of control).

Deriving Application from a Framework

The mechanism for deriving an application from a software framework, such as QP/C, is by inheriting the base classes provided by the framework and specializing them for the application at hand. (See also the extensibility characteristics of a framework enumerated above.)

Main Use Cases

The use case diagram depicted in Figure SRS-USE shows the main users and typical use cases they engage in.

Figure SRS-USE: Users and main use cases of QP/C Application and QP/C Framework.

[1] QP/C Application use cases (use QP/C Framework [2] use cases):

  • Application Developer (actor) develops QP/C Application consisting of Active Objects
  • Application Developer (actor) optimizes QP/C Application
  • Application Developer (actor) maintains QP/C Application by modifying Active Objects
  • Application Developer (actor) traces QP/C Application to debug, profile, optimize
  • Application Developer (actor) or Application Tester (actor) tests QP/C Application (e.g., unit-testing individual Active Objects and integration-testing groups of Active Objects)

[2] QP/C Framework use cases:

  • Framework Maintainer (actor) adapts/ports QP/C Framework to new CPU or 3rd-party RTOS/OS
  • Framework Maintainer (actor) traces QP/C Framework to fine-tune, optimize, debug the modifications
  • Framework Maintainer (actor) tests QP/C Framework to verify the modifications
  • Application Developer (actor) applies QP/C Framework by using its services

Portability & Configurability

A reusable architecture, like the QP/C software framework, needs to be adaptable to a wide range of application areas and target hardware selections. For that, QP/C needs to be highly configurable. Whenever this SRS mentions "configurability", it explicitly specifies which of the following types of configurability is required:

Compile-Time Configurability

Compile-time configurability means that the specific configuration option (out of a given range of possibilities) is chosen at compile-time and cannot be changed later (e.g., at run-time). Compile-time configurability is typically used for:

  • Turning features on or off
  • Determining the size (and dynamic range) of various data types
  • Determining the maximum number of various objects residing inside the QP/C component
  • Determining the presence (or absence) of class members
Remarks
In C or C++, compile-time configurability is typically implemented with the preprocessor macros, but can also be achieved by the composition of the selected modules.

Run-Time Configurability

Run-time configurability means that the specific configuration option is chosen at run-time. Unlike compile-time configurability, run-time configurability has a finer granularity, usually on an object-by-object basis. It is typically used for:

  • Choosing a specific implementation of a class operation based on the object type (polymorphism)
  • Selecting features by calling or not calling the specific QP/C API
  • Selecting features by passing parameters to the specific QP/C API

About this DocumentActive Objects