The following diagram (Figure SRS-BLK) illustrates the context in which the QP/C Framework and QP/C Application operate within an embedded system.
[01] The integration QP/C Application:
[02] The QP/C Framework component:
[03] The Board Support Package (BSP) provides:
[04A] The Real-Time Kernel provides scheduling and execution context for the Active Objects. This could be one of the kernels built into the QP/C Framework (QV, QK, or QXK); or
[04B] Alternatively, QP/C Framework can operate with a 3rd-party RTOS kernel, or a General-Purpose OS (e.g., Linux/POSIX or Windows);
[05] The Target Hardware (MCU + external components). The underlying microcontroller or processor on which QP/C executes.
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/C. 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. That inversion of control gives the event-driven infrastructure (QP/C) all the defining characteristics of an application framework rather than a toolkit.
The main difference between a framework and a toolkit (a software library) is that when you use a toolkit, such as a conventional RTOS, you write the main body of each thread, and you call the toolkit 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).
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.)
The use case diagram depicted in Figure SRS-USE shows the main users and typical use cases they engage in.
[1] QP/C Application use cases (use QP/C Framework [2] use cases):
[2] QP/C Framework use cases:
A reusable architecture, like the QP/C Framework (see also Safety Element out of Context), 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 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:
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: