The Interface Viewpoint focuses on defining and describing the interfaces between QP/C++ Framework and the outside layers, such as the underlying operating system (OS Abstraction Layer) and the QP/C++ Application.
The OS Abstraction Layer (OSAL) shown in Figure SDS-OSAL, insulates 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 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 main focus of this section is to describe the design of the OSAL API, with the specific examples are 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 preemptions. 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/C++ OSAL must provide an efficient critical section abstraction to insulate QP/C++ Framework from the specifics of teh underlying OS.
For example, in single-core embedded systems, critical sections are typically implemented by disabling interrupts upon the entry to the section and re-enabling them upon the exit. This is effective because in such systems interrupts are the only way preemption can be initiated (both interrupt preemption but also 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/C++ OSAL must accomodate all such critical section implementations.
SDS_QP_CRIT : Critical Section API |
---|
Description #define QF_CRIT_STAT ...
#define QF_CRIT_ENTRY() ...
#define QF_CRIT_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: . . . // outside critical section
[1] QF_CRIT_STAT
. . . // outside critical section
[2] QF_CRIT_ENTRY();
[3] . . . // inside critical section
[4] QF_CRIT_EXIT();
. . . // outside critical section
|
Examples #define QF_CRIT_STAT // empty
#define QF_CRIT_ENTRY() (asm volatile ("cpsid i"))
#define QF_CRIT_EXIT() (asm volatile ("cpsie i"))
Example save-and-restore critical section status macros (MSP430 CPU): #define QF_CRIT_STAT unsigned short int_state_;
#define QF_CRIT_ENTRY() do { \
int_state_ = __get_interrupt_state(); \
__disable_interrupt(); \
} while (false)
#define QF_CRIT_EXIT() __set_interrupt_state(int_state_)
|
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 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 |
TBD...