Preemptive Dual-Mode Blocking RTOS Kernel. More...
|QP/C public interface including backwards-compatibility layer. |
|QXK/C (preemptive dual-mode kernel) platform-independent public interface. |
|QXK/C eXtended (blocking) thread. |
|QXK preemptive dual-mode kernel core functions. |
|QXMutex_init(), QXMutex_lock and QXMutex_unlock() definitions. |
|Internal (package scope) QXK/C interface. |
|QXK preemptive kernel semaphore functions. |
|QXK preemptive kernel extended (blocking) thread functions. |
|QF/C port example for QXK, generic C compiler. |
|QXK/C port example for a generic C compiler. |
Preemptive Dual-Mode Blocking RTOS Kernel.
QXK is a small, preemptive, priority-based, dual-mode blocking kernel that executes active objects like the QK kernel, 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.
Currently, the QXK kernel has been ported to the following CPUs:
Currently, the QXK kernel is illustrated by the following examples:
QXK distinguishes two kinds of threads: basic-threads (non-blocking, run-to-completion activations) and extended-threads (blocking, typically structrued as endless loops). The basic-threads all nest on the same stack (Main Stack Pointer in ARM Cortex-M). The extended-threads use private per-thread stacks, as in conventional RTOS kernels. Any switching from basic- to extended-thread or extended- to extended-thread requires full context switch. On the other hand, switching from basic-thread to another basic-thread requires only activation of the basic-thread, which is much simpler and faster.
The figure below shows the main classes introduced in the QXK kernel and their relation to the classes of the QP framework.
0 The abstract QActive class represents active objects in QP. This class contains the
thread object of the underlying kernel (QXK thread-control-block in this case) as well as the event queue and the unique priority of the active object.
1 The QXThread class represents the "naked" blocking threads of the QXK kernel. It inherits QActive, so that extended-threads can be treated as active objects internally in the framework. However, the extended-threads do not implement state machines. Instead, the data fields used for storing the current state in active objects are re-used to store the private stack of the extended-thread. The QXThread class also contains the
timeEvt object (see QTimeEvt) for generating timeouts when the extended-thread is blocked.
2 The QXMutex class represents the priority-ceiling mutex of the QXK kernel. The mutex can be used by both the extended-threads and active object threads (in case they share resources that need to be protected). However, using any blocking mechanism inside active objects is not recommended, because it delays run-to-completion event processing.
As you can see in the list below, QXK provides 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.
>Preemptive, priority-based scheduling of up to 64 threads. Each thread must be provided with its own private stack space and must be assigned its own unique priority (1..QF_MAX_ACTIVE);
NOTE: QXK always executes the highest-priority thread that is ready to run (is not blocked). The scheduling algorithm used in 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.
>All threads in QXK are capable of blocking. However, QXK distinguishes between two types of threads:
>Tightly integrated mechanisms for communication between event-driven active objects and "naked" blocking threads:
>Priority-Ceiling Mutexes with optional timeout;
NOTE: Priority-ceiling protocol implemented in QXK is immune to priority-inversions.
>Counting Semaphores with optional timeout that can block multiple extended-threads;
>Blocking "zero-copy" message queue with optional timeout bound to each extended-thread;
>Deterministic fixed-size memory pools for dynamic memory management available both to extended-threads and active objects;
>Interrupt management, including "zero-latency", kernel-unaware interrupts that are never disabled;
NOTE: This feature is only supported on CPUs that allow selective interrupt disabling, such as ARM Cortex-M3/M4 (but not ARM Cortex-M0).