2022-08-11 15:36:19 -04:00
|
|
|
//$file${include::qk.hpp} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
|
|
|
|
//
|
|
|
|
// Model: qpcpp.qm
|
|
|
|
// File: ${include::qk.hpp}
|
|
|
|
//
|
|
|
|
// This code has been generated by QM 5.2.1 <www.state-machine.com/qm>.
|
|
|
|
// 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 <state-machine.com>.
|
2022-04-19 19:23:30 -04:00
|
|
|
//
|
|
|
|
// 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: <www.gnu.org/licenses/gpl-3.0>
|
|
|
|
//
|
|
|
|
// The terms of the closed source Quantum Leaps commercial licenses
|
|
|
|
// can be found at: <www.state-machine.com/licensing>
|
|
|
|
//
|
|
|
|
// Redistributions in source code must retain this top-level comment block.
|
|
|
|
// Plagiarizing this software to sidestep the license obligations is illegal.
|
|
|
|
//
|
|
|
|
// Contact information:
|
2022-08-11 15:36:19 -04:00
|
|
|
// <www.state-machine.com/licensing>
|
2022-04-19 19:23:30 -04:00
|
|
|
// <info@state-machine.com>
|
2022-08-11 15:36:19 -04:00
|
|
|
//
|
|
|
|
//$endhead${include::qk.hpp} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
|
|
//! @date Last updated on: 2022-06-30
|
|
|
|
//! @version Last updated for: @ref qpcpp_7_0_1
|
2022-04-19 19:23:30 -04:00
|
|
|
//!
|
|
|
|
//! @file
|
|
|
|
//! @brief QK/C++ platform-independent public interface.
|
2014-04-13 21:35:34 -04:00
|
|
|
|
2019-10-27 12:26:31 -04:00
|
|
|
#ifndef QK_HPP
|
|
|
|
#define QK_HPP
|
2012-08-14 18:00:48 -04:00
|
|
|
|
2022-04-19 19:23:30 -04:00
|
|
|
//============================================================================
|
2022-08-11 15:36:19 -04:00
|
|
|
// QF customization for QK -- data members of the QActive class...
|
2012-08-14 18:00:48 -04:00
|
|
|
|
2020-08-24 16:42:48 -04:00
|
|
|
// QK event-queue used for AOs
|
2022-08-11 15:36:19 -04:00
|
|
|
#define QF_EQUEUE_TYPE QEQueue
|
2018-02-18 12:08:21 -05:00
|
|
|
|
2020-08-24 16:42:48 -04:00
|
|
|
// QK thread type used for AOs
|
|
|
|
// QK uses this member to store the private Thread-Local Storage pointer.
|
2022-08-11 15:36:19 -04:00
|
|
|
#define QF_THREAD_TYPE void*
|
2018-02-18 12:08:21 -05:00
|
|
|
|
2022-08-11 15:36:19 -04:00
|
|
|
//============================================================================
|
|
|
|
#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
|
2015-12-31 14:56:37 -05:00
|
|
|
|
2022-04-19 19:23:30 -04:00
|
|
|
//============================================================================
|
2022-08-11 15:36:19 -04:00
|
|
|
//$declare${QK::QK-base} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
|
2018-02-18 12:08:21 -05:00
|
|
|
namespace QP {
|
2022-08-11 15:36:19 -04:00
|
|
|
namespace QK {
|
|
|
|
|
|
|
|
//${QK::QK-base::onIdle} .....................................................
|
|
|
|
//! QK idle callback (customized in BSPs for QK)
|
|
|
|
//!
|
|
|
|
//! @details
|
|
|
|
//! QK::onIdle() is called continously 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;
|
2018-02-18 12:08:21 -05:00
|
|
|
|
2022-08-11 15:36:19 -04:00
|
|
|
} // namespace QK
|
|
|
|
} // namespace QP
|
|
|
|
//$enddecl${QK::QK-base} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
|
|
//============================================================================
|
2016-09-01 11:58:57 -04:00
|
|
|
extern "C" {
|
2022-08-11 15:36:19 -04:00
|
|
|
//$declare${QK-extern-C} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
|
2016-09-01 11:58:57 -04:00
|
|
|
|
2022-08-11 15:36:19 -04:00
|
|
|
//${QK-extern-C::QK_Attr} ....................................................
|
|
|
|
//! attributes of the QK kernel (extern "C" for easy access in assembly)
|
2016-09-01 11:58:57 -04:00
|
|
|
struct QK_Attr {
|
2020-03-17 21:33:58 -04:00
|
|
|
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 lockPrio; //!< lock prio (0 == no-lock)
|
|
|
|
std::uint8_t volatile lockHolder; //!< prio of the lock holder
|
2016-09-01 11:58:57 -04:00
|
|
|
};
|
|
|
|
|
2022-08-11 15:36:19 -04:00
|
|
|
//${QK-extern-C::QK_attr_} ...................................................
|
|
|
|
//! attributes of the QK kernel (extern "C" to be accessible from C)
|
2016-09-01 11:58:57 -04:00
|
|
|
extern QK_Attr QK_attr_;
|
|
|
|
|
2022-08-11 15:36:19 -04:00
|
|
|
//${QK-extern-C::QK_sched_} ..................................................
|
2016-09-29 19:54:50 -04:00
|
|
|
//! QK scheduler finds the highest-priority thread ready to run
|
2022-08-11 15:36:19 -04:00
|
|
|
//!
|
|
|
|
//! @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 1-based priority of the the active object, or zero if
|
|
|
|
//! no eligible active object is ready to run.
|
|
|
|
//!
|
|
|
|
//! @attention
|
|
|
|
//! QK_sched_() must be always called with interrupts **disabled** and
|
|
|
|
//! returns with interrupts **disabled**.
|
|
|
|
std::uint_fast8_t QK_sched_() noexcept;
|
2016-09-01 11:58:57 -04:00
|
|
|
|
2022-08-11 15:36:19 -04:00
|
|
|
//${QK-extern-C::QK_activate_} ...............................................
|
2016-09-29 19:54:50 -04:00
|
|
|
//! QK activator activates the next active object. The activated AO preempts
|
2022-08-11 15:36:19 -04:00
|
|
|
//! the currently executing AOs
|
|
|
|
//!
|
|
|
|
//! @details
|
|
|
|
//! QK_activate_() activates ready-to run AOs that are above the initial
|
|
|
|
//! active priority (QK_attr_.actPrio).
|
|
|
|
//!
|
|
|
|
//! @note
|
|
|
|
//! The activator might enable interrupts internally, but always returns with
|
|
|
|
//! interrupts **disabled**.
|
|
|
|
void QK_activate_() noexcept;
|
2016-09-01 11:58:57 -04:00
|
|
|
|
2022-08-11 15:36:19 -04:00
|
|
|
//${QK-extern-C::QK_onContextSw} .............................................
|
2018-02-18 12:08:21 -05:00
|
|
|
#ifdef QK_ON_CONTEXT_SW
|
2022-08-11 15:36:19 -04:00
|
|
|
//! 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**.
|
2022-04-19 19:23:30 -04:00
|
|
|
//!
|
|
|
|
//! @note
|
2022-08-11 15:36:19 -04:00
|
|
|
//! 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"
|
2022-04-19 19:23:30 -04:00
|
|
|
//============================================================================
|
2013-10-10 20:01:51 -04:00
|
|
|
// interface used only inside QF, but not in applications
|
2014-04-13 21:35:34 -04:00
|
|
|
#ifdef QP_IMPL
|
2022-08-11 15:36:19 -04:00
|
|
|
// QK-specific scheduler locking and event queue...
|
|
|
|
//$declare${QK-impl} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
|
2016-10-08 12:46:03 -04:00
|
|
|
|
2022-08-11 15:36:19 -04:00
|
|
|
//${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_(prio_) do { \
|
|
|
|
if (QK_ISR_CONTEXT_()) { \
|
|
|
|
lockStat_ = 0xFFU; \
|
|
|
|
} else { \
|
|
|
|
lockStat_ = QK::schedLock((prio_)); \
|
|
|
|
} \
|
|
|
|
} 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<std::uint_fast8_t>((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<QEvt *>((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} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
2015-05-14 16:05:04 -04:00
|
|
|
#endif // QP_IMPL
|
2019-10-27 12:26:31 -04:00
|
|
|
#endif // QK_HPP
|