qk.h 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272
  1. /*$file${include::qk.h} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
  2. /*
  3. * Model: qpc.qm
  4. * File: ${include::qk.h}
  5. *
  6. * This code has been generated by QM 5.2.5 <www.state-machine.com/qm>.
  7. * DO NOT EDIT THIS FILE MANUALLY. All your changes will be lost.
  8. *
  9. * This code is covered by the following QP license:
  10. * License # : LicenseRef-QL-dual
  11. * Issued to : Any user of the QP/C real-time embedded framework
  12. * Framework(s) : qpc
  13. * Support ends : 2023-12-31
  14. * License scope:
  15. *
  16. * Copyright (C) 2005 Quantum Leaps, LLC <state-machine.com>.
  17. *
  18. * SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial
  19. *
  20. * This software is dual-licensed under the terms of the open source GNU
  21. * General Public License version 3 (or any later version), or alternatively,
  22. * under the terms of one of the closed source Quantum Leaps commercial
  23. * licenses.
  24. *
  25. * The terms of the open source GNU General Public License version 3
  26. * can be found at: <www.gnu.org/licenses/gpl-3.0>
  27. *
  28. * The terms of the closed source Quantum Leaps commercial licenses
  29. * can be found at: <www.state-machine.com/licensing>
  30. *
  31. * Redistributions in source code must retain this top-level comment block.
  32. * Plagiarizing this software to sidestep the license obligations is illegal.
  33. *
  34. * Contact information:
  35. * <www.state-machine.com/licensing>
  36. * <info@state-machine.com>
  37. */
  38. /*$endhead${include::qk.h} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
  39. /*! @file
  40. * @brief QK/C (preemptive non-blocking kernel) platform-independent
  41. * public interface.
  42. */
  43. #ifndef QK_H_
  44. #define QK_H_
  45. /*==========================================================================*/
  46. /* QF configuration for QK -- data members of the QActive class... */
  47. /* QK event-queue used for AOs */
  48. #define QF_EQUEUE_TYPE QEQueue
  49. /* QK thread type used for AOs
  50. * QK uses this member to store the private Thread-Local Storage pointer.
  51. */
  52. #define QF_THREAD_TYPE void*
  53. #include "qequeue.h" /* QK kernel uses the native QP event queue */
  54. #include "qmpool.h" /* QK kernel uses the native QP memory pool */
  55. #include "qf.h" /* QF framework integrates directly with QK */
  56. /*==========================================================================*/
  57. /*$declare${QK::QK-extern-C} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
  58. /*${QK::QK-extern-C::Attr} .................................................*/
  59. /*! @brief QK preemptive non-blocking kernel
  60. * @class QK
  61. */
  62. typedef struct QK_Attr {
  63. uint8_t volatile actPrio; /*!< QF prio of the active AO */
  64. uint8_t volatile nextPrio; /*!< QF prio of the next AO to execute */
  65. uint8_t volatile actThre; /*!< active preemption-threshold */
  66. uint8_t volatile lockCeil; /*!< lock preemption-ceiling (0==no-lock) */
  67. uint8_t volatile lockHolder; /*!< QF prio of the AO holding the lock */
  68. } QK;
  69. /*${QK::QK-extern-C::attr_} ................................................*/
  70. /*! attributes of the QK kernel
  71. * @static @private @memberof QK
  72. */
  73. extern QK QK_attr_;
  74. /*${QK::QK-extern-C::sched_} ...............................................*/
  75. /*! QK scheduler finds the highest-priority AO ready to run
  76. * @static @private @memberof QK
  77. *
  78. * @details
  79. * The QK scheduler finds out the priority of the highest-priority AO
  80. * that (1) has events to process and (2) has priority that is above the
  81. * current priority.
  82. *
  83. * @returns
  84. * The QF-priority of the next active object to activate, or zero
  85. * if no activation of AO is needed.
  86. *
  87. * @attention
  88. * QK_sched_() must be always called with interrupts **disabled** and
  89. * returns with interrupts **disabled**.
  90. */
  91. uint_fast8_t QK_sched_(void);
  92. /*${QK::QK-extern-C::activate_} ............................................*/
  93. /*! QK activator activates the next active object. The activated AO preempts
  94. * the currently executing AOs.
  95. * @static @private @memberof QK
  96. *
  97. * @details
  98. * QK_activate_() activates ready-to run AOs that are above the initial
  99. * preemption-threshold.
  100. *
  101. * @precondition{qk,500}
  102. * - QK_attr_.actPrio and QK_attr_.nextPrio must be in range
  103. *
  104. * @attention
  105. * QK_activate_() must be always called with interrupts **disabled** and
  106. * returns with interrupts **disabled**.
  107. */
  108. void QK_activate_(void);
  109. /*$enddecl${QK::QK-extern-C} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
  110. /*--------------------------------------------------------------------------*/
  111. /*$declare${QK::QK-base} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
  112. /*${QK::QK-base::schedLock} ................................................*/
  113. /*! QK selective scheduler lock
  114. * @static @public @memberof QK
  115. *
  116. * @details
  117. * This function locks the QK scheduler to the specified ceiling.
  118. *
  119. * @param[in] ceiling preemption ceiling to which the QK scheduler
  120. * needs to be locked
  121. *
  122. * @returns
  123. * The previous QK Scheduler lock status, which is to be used to unlock
  124. * the scheduler by restoring its previous lock status in
  125. * QK_schedUnlock().
  126. *
  127. * @precondition{qk,600}
  128. * - The QK scheduler lock cannot be called from an ISR
  129. *
  130. * @note
  131. * QK_schedLock() must be always followed by the corresponding
  132. * QK_schedUnlock().
  133. *
  134. * @sa QK_schedUnlock()
  135. *
  136. * @usage
  137. * The following example shows how to lock and unlock the QK scheduler:
  138. * @include qk_lock.c
  139. */
  140. QSchedStatus QK_schedLock(uint_fast8_t const ceiling);
  141. /*${QK::QK-base::schedUnlock} ..............................................*/
  142. /*! QK selective scheduler unlock
  143. * @static @public @memberof QK
  144. *
  145. * @details
  146. * This function unlocks the QK scheduler to the previous status.
  147. *
  148. * @param[in] stat previous QK Scheduler lock status returned from
  149. * QK_schedLock()
  150. *
  151. * @precondition{qk,700}
  152. * - the QK scheduler cannot be unlocked: from the ISR context
  153. * - the current lock ceiling must be greater than the previous
  154. *
  155. * @note
  156. * QK_schedUnlock() must always follow the corresponding
  157. * QK_schedLock().
  158. *
  159. * @sa QK_schedLock()
  160. *
  161. * @usage
  162. * The following example shows how to lock and unlock the QK scheduler:
  163. * @include qk_lock.c
  164. */
  165. void QK_schedUnlock(QSchedStatus const stat);
  166. /*${QK::QK-base::onIdle} ...................................................*/
  167. /*! QK idle callback (customized in BSPs for QK)
  168. * @static @public @memberof QK
  169. *
  170. * @details
  171. * QK_onIdle() is called continuously by the QK idle loop. This callback
  172. * gives the application an opportunity to enter a power-saving CPU mode,
  173. * or perform some other idle processing.
  174. *
  175. * @note
  176. * QK_onIdle() is invoked with interrupts enabled and must also return with
  177. * interrupts enabled.
  178. */
  179. void QK_onIdle(void);
  180. /*$enddecl${QK::QK-base} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
  181. /*==========================================================================*/
  182. /* interface used only inside QF, but not in applications */
  183. #ifdef QP_IMPL
  184. /* QK-specific scheduler locking and event queue... */
  185. /*$declare${QK-impl} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
  186. /*${QK-impl::QK_ISR_CONTEXT_} ..............................................*/
  187. #ifndef QK_ISR_CONTEXT_
  188. /*! Internal macro that reports the execution context (ISR vs. thread)
  189. *
  190. * @returns true if the code executes in the ISR context and false
  191. * otherwise
  192. */
  193. #define QK_ISR_CONTEXT_() (QF_intNest_ != 0U)
  194. #endif /* ndef QK_ISR_CONTEXT_ */
  195. /*${QK-impl::QF_SCHED_STAT_} ...............................................*/
  196. /*! QK scheduler lock status */
  197. #define QF_SCHED_STAT_ QSchedStatus lockStat_;
  198. /*${QK-impl::QF_SCHED_LOCK_} ...............................................*/
  199. /*! QK selective scheduler locking */
  200. #define QF_SCHED_LOCK_(ceil_) do { \
  201. if (QK_ISR_CONTEXT_()) { \
  202. lockStat_ = 0xFFU; \
  203. } else { \
  204. lockStat_ = QK_schedLock((ceil_)); \
  205. } \
  206. } while (false)
  207. /*${QK-impl::QF_SCHED_UNLOCK_} .............................................*/
  208. /*! QK selective scheduler unlocking */
  209. #define QF_SCHED_UNLOCK_() do { \
  210. if (lockStat_ != 0xFFU) { \
  211. QK_schedUnlock(lockStat_); \
  212. } \
  213. } while (false)
  214. /*${QK-impl::QACTIVE_EQUEUE_WAIT_} .........................................*/
  215. /*! QK native event queue waiting */
  216. #define QACTIVE_EQUEUE_WAIT_(me_) \
  217. (Q_ASSERT_ID(110, (me_)->eQueue.frontEvt != (QEvt *)0))
  218. /*${QK-impl::QACTIVE_EQUEUE_SIGNAL_} .......................................*/
  219. /*! QK native event queue signaling */
  220. #define QACTIVE_EQUEUE_SIGNAL_(me_) do { \
  221. QPSet_insert(&QF_readySet_, (uint_fast8_t)(me_)->prio); \
  222. if (!QK_ISR_CONTEXT_()) { \
  223. if (QK_sched_() != 0U) { \
  224. QK_activate_(); \
  225. } \
  226. } \
  227. } while (false)
  228. /*$enddecl${QK-impl} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
  229. /* Native QF event pool operations... */
  230. /*$declare${QF-QMPool-impl} vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/
  231. /*${QF-QMPool-impl::QF_EPOOL_TYPE_} ........................................*/
  232. #define QF_EPOOL_TYPE_ QMPool
  233. /*${QF-QMPool-impl::QF_EPOOL_INIT_} ........................................*/
  234. #define QF_EPOOL_INIT_(p_, poolSto_, poolSize_, evtSize_) \
  235. (QMPool_init(&(p_), (poolSto_), (poolSize_), (evtSize_)))
  236. /*${QF-QMPool-impl::QF_EPOOL_EVENT_SIZE_} ..................................*/
  237. #define QF_EPOOL_EVENT_SIZE_(p_) ((uint_fast16_t)(p_).blockSize)
  238. /*${QF-QMPool-impl::QF_EPOOL_GET_} .........................................*/
  239. #define QF_EPOOL_GET_(p_, e_, m_, qs_id_) \
  240. ((e_) = (QEvt *)QMPool_get(&(p_), (m_), (qs_id_)))
  241. /*${QF-QMPool-impl::QF_EPOOL_PUT_} .........................................*/
  242. #define QF_EPOOL_PUT_(p_, e_, qs_id_) \
  243. (QMPool_put(&(p_), (e_), (qs_id_)))
  244. /*$enddecl${QF-QMPool-impl} ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/
  245. #endif /* QP_IMPL */
  246. #endif /* QK_H_ */