//$file${include::qk.hpp} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv // // Model: qpcpp.qm // File: ${include::qk.hpp} // // This code has been generated by QM 5.2.2 . // DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost. // // This code is covered by the following QP license: // License # : LicenseRef-QL-dual // Issued to : Any user of the QP/C++ real-time embedded framework // Framework(s) : qpcpp // Support ends : 2023-12-31 // License scope: // // Copyright (C) 2005 Quantum Leaps, LLC . // // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial // // This software is dual-licensed under the terms of the open source GNU // General Public License version 3 (or any later version), or alternatively, // under the terms of one of the closed source Quantum Leaps commercial // licenses. // // The terms of the open source GNU General Public License version 3 // can be found at: // // The terms of the closed source Quantum Leaps commercial licenses // can be found at: // // Redistributions in source code must retain this top-level comment block. // Plagiarizing this software to sidestep the license obligations is illegal. // // Contact information: // // // //$endhead${include::qk.hpp} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ //! @file //! @brief QK/C++ platform-independent public interface. #ifndef QP_INC_QK_HPP_ #define QP_INC_QK_HPP_ //============================================================================ // QF customization for QK -- data members of the QActive class... // QK event-queue used for AOs #define QF_EQUEUE_TYPE QEQueue // QK thread type used for AOs // QK uses this member to store the private Thread-Local Storage pointer. #define QF_THREAD_TYPE void* //============================================================================ #include "qequeue.hpp" // QK kernel uses the native QF event queue #include "qmpool.hpp" // QK kernel uses the native QF memory pool #include "qf.hpp" // QF framework integrates directly with QK //============================================================================ //$declare${QK::QK-base} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv namespace QP { namespace QK { //${QK::QK-base::onIdle} ..................................................... //! QK idle callback (customized in BSPs for QK) //! //! @details //! QK::onIdle() is called continuously by the QK idle loop. This callback //! gives the application an opportunity to enter a power-saving CPU mode, //! or perform some other idle processing. //! //! @note //! QK::onIdle() is invoked with interrupts enabled and must also return //! with interrupts enabled. //! //! @sa QV::onIdle(), QXK::onIdle() void onIdle(); //${QK::QK-base::schedLock} .................................................. //! QK selective scheduler lock //! //! @details //! This function locks the QK scheduler to the specified ceiling. //! //! @param[in] ceiling priority ceiling to which the QK scheduler //! needs to be locked //! //! @returns //! The previous QK Scheduler lock status, which is to be used to unlock //! the scheduler by restoring its previous lock status in //! QP::QK::schedUnlock(). //! //! @note //! QP::QK::schedLock() must be always followed by the corresponding //! QP::QK::schedUnlock(). //! //! @sa QK_schedUnlock() //! //! @usage //! The following example shows how to lock and unlock the QK scheduler: //! @include qk_lock.cpp QSchedStatus schedLock(std::uint_fast8_t const ceiling) noexcept; //${QK::QK-base::schedUnlock} ................................................ //! QK selective scheduler unlock //! //! @details //! This function unlocks the QK scheduler to the previous status. //! //! @param[in] stat previous QK Scheduler lock status returned from //! QP::QK::schedLock() //! @note //! QP::QK::schedUnlock() must always follow the corresponding //! QP::QK::schedLock(). //! //! @sa QP::QK::schedLock() //! //! @usage //! The following example shows how to lock and unlock the QK scheduler: //! @include qk_lock.cpp void schedUnlock(QSchedStatus const stat) noexcept; } // namespace QK } // namespace QP //$enddecl${QK::QK-base} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ //============================================================================ extern "C" { //$declare${QK-extern-C} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv //${QK-extern-C::QK_Attr} .................................................... //! attributes of the QK kernel (extern "C" for easy access in assembly) struct QK_Attr { std::uint8_t volatile actPrio; //!< prio of the active AO std::uint8_t volatile nextPrio; //!< prio of the next AO to execute std::uint8_t volatile actThre; //!< active preemption-threshold std::uint8_t volatile lockCeil; //!< lock preemption-ceiling (0==no-lock) std::uint8_t volatile lockHolder; //!< prio of the lock holder }; //${QK-extern-C::QK_attr_} ................................................... //! attributes of the QK kernel (extern "C" to be accessible from C) extern QK_Attr QK_attr_; //${QK-extern-C::QK_sched_} .................................................. //! QK scheduler finds the highest-priority thread ready to run //! //! @details //! The QK scheduler finds out the priority of the highest-priority AO //! that (1) has events to process and (2) has priority that is above the //! current priority. //! //! @returns //! The QF-priority of the next active object to activate, or zero //! if no activation of AO is needed. //! //! @attention //! QK_sched_() must be always called with interrupts **disabled** and //! returns with interrupts **disabled**. std::uint_fast8_t QK_sched_() noexcept; //${QK-extern-C::QK_activate_} ............................................... //! QK activator activates the next active object. The activated AO preempts //! the currently executing AOs //! //! @details //! QK_activate_() activates ready-to run AOs that are above the initial //! preemption-threshold. //! //! @note //! The activator might enable interrupts internally, but always returns with //! interrupts **disabled**. void QK_activate_() noexcept; //${QK-extern-C::QK_onContextSw} ............................................. #ifdef QK_ON_CONTEXT_SW //! QK context switch callback (customized in BSPs for QK) //! //! @details //! This callback function provides a mechanism to perform additional //! custom operations when QK switches context from one thread to //! another. //! //! @param[in] prev pointer to the previous thread (active object) //! (prev==0 means that `prev` was the QK idle loop) //! @param[in] next pointer to the next thread (active object) //! (next==0) means that `next` is the QK idle loop) //! @attention //! QK_onContextSw() is invoked with interrupts **disabled** and must also //! return with interrupts **disabled**. //! //! @note //! This callback is enabled by defining the macro #QK_ON_CONTEXT_SW. //! //! @include qk_oncontextsw.cpp void QK_onContextSw( QP::QActive * prev, QP::QActive * next); #endif // def QK_ON_CONTEXT_SW //$enddecl${QK-extern-C} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ } // extern "C" //============================================================================ // interface used only inside QF, but not in applications #ifdef QP_IMPL // QK-specific scheduler locking and event queue... //$declare${QK-impl} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv //${QK-impl::QK_ISR_CONTEXT_} ................................................ #ifndef QK_ISR_CONTEXT_ //! Internal port-specific macro that checks the execution context //! (ISR vs. thread). Might be overridden in qk_port.hpp. //! //! @returns //! 'true' if the code executes in the ISR context and 'false' otherwise. #define QK_ISR_CONTEXT_() (QF::intNest_ != 0U) #endif // ndef QK_ISR_CONTEXT_ //${QK-impl::QF_SCHED_STAT_} ................................................. //! QK scheduler lock status #define QF_SCHED_STAT_ QSchedStatus lockStat_; //${QK-impl::QF_SCHED_LOCK_} ................................................. //! QK selective scheduler locking #define QF_SCHED_LOCK_(ceil_) do { \ if (QK_ISR_CONTEXT_()) { \ lockStat_ = 0xFFU; \ } else { \ lockStat_ = QK::schedLock((ceil_)); \ } \ } while (false) //${QK-impl::QF_SCHED_UNLOCK_} ............................................... //! QK selective scheduler unlocking #define QF_SCHED_UNLOCK_() do { \ if (lockStat_ != 0xFFU) { \ QK::schedUnlock(lockStat_); \ } \ } while (false) //${QK-impl::QACTIVE_EQUEUE_WAIT_} ........................................... // QK native event queue waiting #define QACTIVE_EQUEUE_WAIT_(me_) \ Q_ASSERT_ID(110, (me_)->m_eQueue.m_frontEvt != nullptr) //${QK-impl::QACTIVE_EQUEUE_SIGNAL_} ......................................... // QK native event queue signaling #define QACTIVE_EQUEUE_SIGNAL_(me_) do { \ QF::readySet_.insert( \ static_cast((me_)->m_prio)); \ if (!QK_ISR_CONTEXT_()) { \ if (QK_sched_() != 0U) { \ QK_activate_(); \ } \ } \ } while (false) //$enddecl${QK-impl} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ // Native QF event pool operations... //$declare${QF-QMPool-impl} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv //${QF-QMPool-impl::QF_EPOOL_TYPE_} .......................................... #define QF_EPOOL_TYPE_ QMPool //${QF-QMPool-impl::QF_EPOOL_INIT_} .......................................... #define QF_EPOOL_INIT_(p_, poolSto_, poolSize_, evtSize_) \ (p_).init((poolSto_), (poolSize_), (evtSize_)) //${QF-QMPool-impl::QF_EPOOL_EVENT_SIZE_} .................................... #define QF_EPOOL_EVENT_SIZE_(p_) ((p_).getBlockSize()) //${QF-QMPool-impl::QF_EPOOL_GET_} ........................................... #define QF_EPOOL_GET_(p_, e_, m_, qs_id_) \ ((e_) = static_cast((p_).get((m_), (qs_id_)))) //${QF-QMPool-impl::QF_EPOOL_PUT_} ........................................... #define QF_EPOOL_PUT_(p_, e_, qs_id_) ((p_).put((e_), (qs_id_))) //$enddecl${QF-QMPool-impl} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ #endif // QP_IMPL #endif // QP_INC_QK_HPP_