qpcpp/include/qk.hpp

281 lines
10 KiB
C++
Raw Normal View History

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>.
//
// 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>
// <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
//!
//! @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-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-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**.
//!
//! @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"
//============================================================================
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