QP/C++  5.9.8
QXK

Preemptive Dual-Mode (Run-to-Completion/Blocking) RTOS Kernel. More...

Files

file  qpcpp.h
 QP/C++ public interface including backwards-compatibility layer.
 
file  qxk.h
 QXK/C++ preemptive extended (blocking) kernel, platform-independent public interface.
 
file  qxthread.h
 QXK/C++ extended (blocking) thread.
 
file  qxk.cpp
 QXK/C++ preemptive kernel core functions public interface.
 
file  qxk_mutex.cpp
 Priority-ceiling blocking mutex QP::QXMutex class definition.
 
file  qxk_sema.cpp
 QXK/C++ preemptive kernel counting semaphore implementation.
 
file  qxk_xthr.cpp
 QXK/C++ preemptive kernel extended (blocking) thread implementation.
 
file  qxk_pkg.h
 Internal (package scope) QXK/C++ interface.
 
file  qf_port.h
 QF/C++ port example, QXK kernel, Generic C++ compiler.
 
file  qxk_port.h
 QXK/C++ port example, Generic C++ compiler.
 

Namespaces

 QP
 namespace associated with the QP/C++ framework
 

Detailed Description

Preemptive Dual-Mode (Run-to-Completion/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 Overview

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.

Classes in QXK

The figure below shows the main classes introduced in the QXK kernel and their relation to the classes of the QP framework.

qxk_classes.gif
Classes of the QXK dual-mode kernel
Note
The main takeaway from the QXK class diagram is QXK's optimal, tight integration with the QP framework. The QXK kernel reuses all mechanisms already provided in QP, thus avoiding any code duplication, inefficient layers of indirection, and additional licensing costs, which are inevitable when using 3rd-party RTOS kernels to run QP applications.

QXK Features

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 applications that need to mix active objects with traditional blocking code.

Kernel Initialization and Control

See also

Thread Management

See also

Interrupt Management

See also

Mutexes

See also

Message Queues

See also

Semaphores

See also

Memory Pools

See also

Thread Local Storage

Thread-local storage (TLS) is a programming method that uses static or global memory local to a thread. TLS is specifically useful for writing library-type code, which is used in a multithreaded environment and needs to access per-thread data in an independent way.

TLS is used in some places where ordinary, single-threaded programs would use static or global variables, but where this would be inappropriate in multithreaded cases. An example of such situations is where library-type functions use a global variable to set an error condition (for example the global variable errno used by many functions of the C library). If errno were simply a global variable, a call of a system function on one thread may overwrite the value previously set by a call of a system function on a different thread, possibly before following code on that different thread could check for the error condition. The solution is to have errno be a variable that looks like it is global, but in fact exists once per thread—i.e., it lives in thread-local storage. A second use case would be multiple threads accumulating information into a global variable. To avoid a race condition, every access to this global variable would have to be protected by a mutual-exclusion mechanism. Alternatively, each thread might accumulate into a thread-local variable (that, by definition, cannot be read from or written to from other threads, implying that there can be no race conditions). Threads then only have to synchronize a final accumulation from their own thread-local variable into a single, truly global variable.

The TLS implementations vary, but many systems, including QXK, implement TLS by providing a pointer-sized variable thread-local. This pointer can be set to arbitrarily sized memory blocks in a thread-local manner, by allocating such a memory block (statically or dynamically) and storing the memory address of that block in the thread-local variable.

Typical usage of TLS in QXK is illustrated in the example qpcpp/examples/arm-cm/dpp_efm32-slstk3401a/qxk/, test.cpp, and consists:

See also