/*##########################################################################*/ /*! @page ports_rtos Ports to Third-Party RTOS

The most important reason why you might consider using a traditional RTOS kernel for executing event-driven QP/C applications is compatibility with the existing software. For example, most communication stacks (TCP/IP, USB, CAN, etc.) are designed for a traditional **blocking** kernel. In addition, a lot of legacy code requires blocking mechanisms, such as semaphores or time-delays. A conventional RTOS allows you to run the existing software components as regular "blocking" tasks in parallel to the event-driven QP/C application.

Another reason you might be interested in running QP/C on top of a conventional RTOS is **safety certification**, which your RTOS kernel might have but the built-in QP kernels currently don't provide. @note You do **not** need to use a traditional RTOS just to achieve preemptive multitasking with QP. The @ref comp_qk "preemptive QK kernel", available as part of the QP package, supports preemptive priority-based multitasking and is fully compatible with Rate Monotonic Scheduling to achieve guaranteed, hard real-time performance. The preemptive, run-to-completion QK kernel perfectly matches the run-to-completion execution semantics of active objects, yet it is simpler, faster, and more efficient than any traditional blocking kernel. The QP/C framework can work with virtually any traditional real-time operating system (RTOS). The currently supported 3rd-party RTOS kernels are: - @subpage embos - @subpage threadx - @subpage ti-rtos - @subpage ucos-ii - OSEK/VDX RTOS ERIKA Enterprise Combined with a conventional RTOS, QP/C takes full advantage of the multitasking capabilities of the RTOS by executing each active object in a separate RTOS task. The QP/C Platform Abstraction Layer (PAL) includes an abstract RTOS interface to enable integration between QP/C and the underlying RTOS. Specifically, the PAL allows adapting most message queue variants as event queues of active objects as well as most memory partitions as QP/C event pools. @attention Starting from version 5.6.0, QP/C includes the conventional, preemptive @ref qxk " blocking QXK kernel", which is recommended as the preferred RTOS kernel for applications that need to mix active objects with traditional blocking code. Due to the tight and optimal integration between QXK and the rest of QP, QXK offers better performance and smaller memory footprint than any @ref ports_rtos "QP port to a 3rd-party RTOS". Additionally, QXK is already included in QP, so you avoid additional licensing costs of 3rd-party kernels. */ /*##########################################################################*/ /*! @page embos embOS @image html under_construction.jpg */ /*##########################################################################*/ /*! @page threadx ThreadX @image html under_construction.jpg */ /*##########################################################################*/ /*! @page ti-rtos TI-RTOS Kernel (SYS/BIOS) @tableofcontents @section ti-rtos_about About the QP Port to TI-RTOS The ports/ti-rtos/ directory contains a generic platform-independent QP/C port to TI-RTOS kernel (SYS/BIOS). The provided QP port to TI-RTOS has been designed *generically* to rely exclusively on the existing TI-RTOS API. This means that the port should run without changes on any CPU/compiler platform supported by TI-RTOS. @attention The TI-RTOS requires its own tooling (XDCTOOLS) and is too big to fit into the 3rd_party/ directory in the QP/C distribution. Therefore, you need to **download and install** TI-RTOS on your machine before you can build any examples. Please refer to the TI Application Note "TI-RTOS for TivaC Getting Started Guide" (Literature Number: SPRUHU5D) for more information. The QP-TI-RTOS port works as follows: - Each QP active object executes in a separate TI-RTOS Software Interrupt (Swi). - Each QP active object thread has a unique priority (the Swi priority). - The critical section used in QF and QS is based on the TI-RTOS APIs `Hwi_disable()`/`Hwi_enable()`, which selectively disable interrupts and allow for nesting of critical sections. - The QP port uses the native event queue (::QEQueue) for active object event queues. - The QP port uses the native QF memory pool (::QMPool) to implement event pools. - The QP port does not mandate any specific method to manage the QP time events, but the provided examples use the TI-RTOS clock package to periodically invoke the QP clock tick QF_TICK_X() (see @ref exa_ti-rtos ). @note This QP port uses the TI-RTOS Swis ("Software Interrupts") to provide the thread context to run QP active objects. The TI-RTOS Swis are a perfect match to execute the run-to-completion (RTC) event processing in active objects and require far less resources (no private stacks) than regular blocking threads. ------------------------------------------------------------------------------ @section ti-rtos_qf_h The qf_port.h Header File The ports/ti-rtos/qf_port.h header file contains the customization of the QP framework for the TI-RTOS kernel. The file is shown below with the explanation sections following the source code: @code{c} #ifndef qf_port_h #define qf_port_h /* TI-RTOS-specific event queue and thread types, see NOTE1 */ [1] #define QF_EQUEUE_TYPE QEQueue [2] #define QF_OS_OBJECT_TYPE Swi_Struct [3] #define QF_THREAD_TYPE Swi_Handle /* The maximum number of active objects in the application, see NOTE2 */ [4] #define QF_MAX_ACTIVE 32 /* TI-RTOS-specific critical section operations, NOTE3 */ [5] #define QF_CRIT_STAT_TYPE UInt [6] #define QF_CRIT_ENTRY(key_) ((key_) = Hwi_disable()) [7] #define QF_CRIT_EXIT(key_) (Hwi_restore((key_))) [8] #include /* TI-RTOS Hwi package */ [9] #include /* TI-RTOS Swi package */ #include "qep_port.h" /* QEP port */ #include "qequeue.h" /* this QF port uses the native QF event queue */ #include "qmpool.h" /* this QF port uses the native QF memory pool */ #include "qf.h" /* QF platform-independent public interface */ /***************************************************************************** * interface used only inside QF, but not in applications */ #ifdef QP_IMPL /* TI-RTOS-specific scheduler locking, see NOTE4 */ [10] #define QF_SCHED_STAT_ UInt key_; [11] #define QF_SCHED_LOCK_(dummy) (key_ = Swi_disable()) [12] #define QF_SCHED_UNLOCK_() (Swi_restore(key_)) /* TI-RTOS-specific native event queue operations... */ [13] #define QACTIVE_EQUEUE_WAIT_(me_) \ (Q_ASSERT_ID(0, (me_)->eQueue.frontEvt != (QEvt *)0)) [14] #define QACTIVE_EQUEUE_SIGNAL_(me_) Swi_post((me_)->thread) [15] #define QACTIVE_EQUEUE_ONEMPTY_(dummy) ((void)0) /* native QF event pool operations... */ [16] #define QF_EPOOL_TYPE_ QMPool [17] #define QF_EPOOL_INIT_(p_, poolSto_, poolSize_, evtSize_) \ (QMPool_init(&(p_), (poolSto_), (poolSize_), (evtSize_))) [18] #define QF_EPOOL_EVENT_SIZE_(p_) ((uint_fast16_t)(p_).blockSize) [19] #define QF_EPOOL_GET_(p_, e_, m_) ((e_) = (QEvt *)QMPool_get(&(p_), (m_))) [20] #define QF_EPOOL_PUT_(p_, e_) (QMPool_put(&(p_), (e_))) #endif /* ifdef QP_IMPL */ #endif /* qf_port_h */ @endcode ------------------------------------------------------------------------------ @section ti-rtos_qf_c The qf_port.c Implementation File The ports/ti-rtos/qf_port.c file contains the implementation of the QP port to the TI-RTOS kernel. The file is shown below with the explanation sections following the source code: @code{c} ~ ~ ~ /*..........................................................................*/ [1] void QF_init(void) { } /*..........................................................................*/ [2] int_t QF_run(void) { [3] QF_onStartup(); /* configure & start interrupts */ [4] BIOS_start(); /* start TI-RTOT (SYS/BIOS) */ Q_ERROR_ID(100); /* BIOS_start() should never return */ return (int_t)0; /* this unreachable return keeps the compiler happy */ } ~ ~ ~ /*..........................................................................*/ [5] void QActive_start_(QActive * const me, uint_fast8_t prio, QEvt const *qSto[], uint_fast16_t qLen, void *stkSto, uint_fast16_t stkSize, QEvt const *ie) { Swi_Params swiParams; /** @pre the priority must be in range and the stack storage must not * be provided, because the TI-RTOS Swis do not need per-Swi stacks. */ Q_REQUIRE_ID(400, ((uint_fast8_t)0 < prio) && (prio <= (uint_fast8_t)QF_MAX_ACTIVE) [6] && (stkSto == (void *)0)); (void)stkSize; /* avoid the "unused parameter" compiler warning */ [7] QEQueue_init(&me->eQueue, qSto, qLen); [8] me->prio = prio; /* set QF priority of this AO before adding it to QF */ [9] QF_add_(me); /* make QF aware of this active object */ [10] QMSM_INIT(&me->super, ie); /* take the top-most initial tran. */ [11] QS_FLUSH(); /* flush the QS trace buffer to the host */ /* create TI-RTOS Swi to run this active object... */ [12] Swi_Params_init(&swiParams); [13] swiParams.arg0 = (xdc_UArg)me; /* the "me" pointer */ [14] swiParams.arg1 = 0; /* not used */ [15] swiParams.priority = prio; /* TI-RTOS Swis can use the QP priority */ swiParams.trigger = 0; /* not used */ [16] Swi_construct(&me->osObject, &swi_function, &swiParams, NULL); [17] me->thread = Swi_handle(&me->osObject); /* TI-RTOS Swi must be created correctly */ [18] Q_ENSURE_ID(490, me->thread != 0); } /*..........................................................................*/ [19] static void swi_function(UArg arg0, UArg arg1) { /* TI-RTOS Swi signature */ [20] QMActive *act = (QMActive *)arg0; [21] QEvt const *e = QActive_get_(act); [22] QMSM_DISPATCH(&act->super, e); /* dispatch to the AO's SM */ [23] QF_gc(e); /* check if the event is garbage, and collect it if so */ (void)arg1; /* unused parameter */ /* are events still available for this AO? */ [24] if (act->eQueue.frontEvt != (QEvt *)0) { [25] Swi_post(act->thread); } } @endcode */ /*##########################################################################*/ /*! @page ucos-ii uC/OS-II @section ucos-ii_about About the QP Port to uC/OS-II This directory contains a generic platform-independent QP/C port to uC/OS-II V2.92. Typically, you should not need to change the files in this directory to adapt the QP-uC/OS port on any CPU/Compiler to which uC/OS-II has been ported, because all the CPU and compiler specifics are handled by the uC/OS-II RTOS. @note Currently, the port has been tested only on ARM Cortex-M3 and M4F. @section ucos-ii_source uC/OS-II Source and ARM Cortex-M3/M4 Ports The uC/OS-II V2.92 source code and ports are located in 3rd_party@uCOS-II. Please make sure to read about uC/OS-II licensing in the README file found in this directory. @note The official Micrium ARM-Cortex-M ports have been modified by Quantum Leaps to remove the dependencies on the Micrium's uC-CPU and uC-LIB components, and instead to inter-operate with the Cortex Microcontroller Software Interface Standard (CMSIS). ------------------------------------------------------------------------------ @section ucos-ii_using Using this QP Port to uC/OS-II The example projects for this port are located in @ref exa_ucos-ii "examples/ucos-ii/arm-cm/dpp_ek-tm4c123gxl". Currently, ARM-KEIL and IAR-ARM toolsets are supported (in the arm and iar sub-directories within this example project). The example projects use this port by directly including the QP source code (and this port) in the application projects. There is no QP library to build. However, this port can also be used as a library, in which case you need to build the QP library yourself and include in your project.
@subsection ucos-ii_build QP Source Files Needed in this QP Port Whether you use this QP port as source files or as a library, it is important to note that not all QP soruce files should be included. Here is the list of QP source files needed: @verbatim qpc +-source | +-qep_hsm.c | +-qep_msm.c | +-qf_act.c | +-qf_defer.c | +-qf_dyn.c | +-qf_ps.c | +-qf_qeq.c | +-qf_qmact.c | +-qf_time.c | | | +-qs.c - included only in the Spy build configuration | +-qs_fp.c - included only in the Spy build configuration | +-ports | +-ucos-ii | | +-qf_port.c @endverbatim @note Specifically, the QP source files qf_actq.c and qf_mem.c must **NOT** be included in the build, because this functionality is taken from uC/OS-II. @image html under_construction.jpg */