Interface Viewpoint
Purpose
The Interface Viewpoint focuses on defining and describing the interfaces between the QP/C++ Framework and the outside layers, such as the underlying operating system (OS Abstraction Layer) and the QP/C++ Application.
Model Kind
The package diagram shown in Figure SDS-OSAL illustrates the main layers with interfaces under consideration in this viewpoint.
The OS Abstraction Layer (OSAL) insulates the QP/C++ Framework from the underlying Operating System (OS), such as one of the built-in real-time kernels, 3rd-party RTOS, or a General-Purpose OS. The OSAL provides both the abstract Operating System API (OSAL API), see Figure SDS-OSAL [2A], and the implementation of this API for the specific OS (Figure SDS-OSAL [2B]). The main idea of an OSAL is that the OSAL API is fixed and is used inside the QP/C++ Framework source code, while the OSAL implementation (called the "QP port") depends on the specific underlying OS. In other words, there is a separate "QP port" for every supported real-time kernel, 3rd-party RTOS, or GPOS. The primary focus of this section is to describe the design of the OSAL API, with specific examples taken from various "QP ports" implementing the OSAL API.
Critical section is a non-blocking mutual exclusion mechanism that protects a sequence of instructions from preemption. QP/C++ Framework, just like any other system-level software, must internally use critical sections to guarantee concurrency-safe operation. The critical section implementation depends on the underlying OS, so the QP OSAL must provide an efficient critical section abstraction to insulate QP/C++ Framework from the specifics of the underlying OS.
For example, in single-core embedded systems, critical sections are typically implemented by disabling interrupts upon entry to the section and re-enabling them upon exit. This is effective because in such systems, interrupts are the only way preemption can be initiated (both interrupt preemption and thread preemption in a real-time kernel). However, other systems (e.g., multicore) might use a different critical section mechanism (e.g., spin-lock). Some other systems (e.g., general-purpose OS) might implement user-space critical sections with the traditional mutual-exclusion mechanism, such as a mutex. The critical section abstraction in QP OSAL must accommodate all such critical section implementations.
Critical Section API
Description
The critical section abstraction in QP OSAL consists of three parameter-less macros: critical-section status, critical-section-entry, and critical-section-exit.
These macros support two main types of critical section implementations:
Internally, QP/C++ Framework uses the critical section macros in the following generic way:
[1] If the macro QF_CRIT_STAT is not-empty, it allocates a local critical-section-status variable. Otherwise, if the macro is empty, the line does nothing.
[2] The macro QF_CRIT_ENTRY() enters the critical section, which saves the critical section status into the status variable (if it was defined at step [1])
[3] This code executes inside the critical section protection
[4] the macro QF_CRIT_EXIT() exits the critical section, which restores the critical section status from the status variable (if it was defined at step [1])
Examples
Example simple critical section macros without critical section status (ARM Cortex-M CPU):
Example save-and-restore critical section status macros (MSP430 CPU):
Nesting Critical Sections
Some CPUs or operating systems require nesting of one critical section in another critical section. The "save-and-restore critical section status" method enables such critical section nesting in an explicit manner. But even the "simple critical section" method can be implemented in a way that allows critical section nesting. For example, the critical section can use an internal up-down nesting counter, which will guarantee that only the last nesting level truly exits the critical section.
Forward Traceability (truncated to 2 level(s))
TBD...