|
QP/C++
|
00001 00002 // Product: QK/C++ 00003 // Last Updated for Version: 4.3.00 00004 // Date of the Last Update: Nov 02, 2011 00005 // 00006 // Q u a n t u m L e a P s 00007 // --------------------------- 00008 // innovating embedded systems 00009 // 00010 // Copyright (C) 2002-2011 Quantum Leaps, LLC. All rights reserved. 00011 // 00012 // This software may be distributed and modified under the terms of the GNU 00013 // General Public License version 2 (GPL) as published by the Free Software 00014 // Foundation and appearing in the file GPL.TXT included in the packaging of 00015 // this file. Please note that GPL Section 2[b] requires that all works based 00016 // on this software must also be made publicly available under the terms of 00017 // the GPL ("Copyleft"). 00018 // 00019 // Alternatively, this software may be distributed and modified under the 00020 // terms of Quantum Leaps commercial licenses, which expressly supersede 00021 // the GPL and are specifically designed for licensees interested in 00022 // retaining the proprietary status of their code. 00023 // 00024 // Contact information: 00025 // Quantum Leaps Web site: http://www.quantum-leaps.com 00026 // e-mail: info@quantum-leaps.com 00028 #include "qk_pkg.h" 00029 #include "qassert.h" 00030 00036 00037 // Public-scope objects ------------------------------------------------------ 00038 extern "C" { 00039 #if (QF_MAX_ACTIVE <= 8U) 00040 #ifdef Q_USE_NAMESPACE 00041 QP::QPSet8 volatile QK_readySet_; // ready set of QK 00042 #else 00043 QPSet8 volatile QK_readySet_; // ready set of QK 00044 #endif 00045 #else 00046 #ifdef Q_USE_NAMESPACE 00047 QP::QPSet64 volatile QK_readySet_; // ready set of QK 00048 #else 00049 QPSet64 volatile QK_readySet_; // ready set of QK 00050 #endif 00051 #endif 00052 // start with the QK scheduler locked 00053 uint8_t volatile QK_currPrio_ = (uint8_t)(QF_MAX_ACTIVE + 1); 00054 uint8_t volatile QK_intNest_; // start with nesting level of 0 00055 00056 } // extern "C" 00057 00058 #ifdef Q_USE_NAMESPACE 00059 namespace QP { 00060 #endif 00061 00062 Q_DEFINE_THIS_MODULE(qk) 00063 00064 //............................................................................ 00065 //lint -e970 -e971 ignore MISRA rules 13 and 14 in this function 00066 char const Q_ROM * Q_ROM_VAR QK::getVersion(void) { 00067 static char const Q_ROM Q_ROM_VAR version[] = { 00068 (char)(((QP_VERSION >> 12U) & 0xFU) + (uint8_t)'0'), 00069 '.', 00070 (char)(((QP_VERSION >> 8U) & 0xFU) + (uint8_t)'0'), 00071 '.', 00072 (char)(((QP_VERSION >> 4U) & 0xFU) + (uint8_t)'0'), 00073 (char)((QP_VERSION & 0xFU) + (uint8_t)'0'), 00074 '\0' 00075 }; 00076 return version; 00077 } 00078 //............................................................................ 00079 void QF::init(void) { 00080 QK_init(); // QK initialization ("C" linkage, might be assembly) 00081 } 00082 //............................................................................ 00083 void QF::stop(void) { 00084 QF::onCleanup(); // cleanup callback 00085 // nothing else to do for the QK preemptive kernel 00086 } 00087 //............................................................................ 00088 static void initialize(void) { 00089 QK_currPrio_ = (uint8_t)0; // set the priority for the QK idle loop 00090 uint8_t p = QK_schedPrio_(); 00091 if (p != (uint8_t)0) { 00092 QK_sched_(p); // process all events produced so far 00093 } 00094 } 00095 //............................................................................ 00096 void QF::run(void) { 00097 QF_INT_DISABLE(); 00098 initialize(); 00099 onStartup(); // startup callback 00100 QF_INT_ENABLE(); 00101 00102 for (;;) { // the QK idle loop 00103 QK::onIdle(); // invoke the QK on-idle callback 00104 } 00105 } 00106 //............................................................................ 00107 void QActive::start(uint8_t prio, 00108 QEvent const *qSto[], uint32_t qLen, 00109 void *tls, uint32_t flags, 00110 QEvent const *ie) 00111 { 00112 Q_REQUIRE(((uint8_t)0 < prio) && (prio <= (uint8_t)QF_MAX_ACTIVE)); 00113 00114 m_eQueue.init(qSto, (QEQueueCtr)qLen); // initialize the event queue 00115 m_prio = prio; 00116 QF::add_(this); // make QF aware of this active object 00117 00118 #if defined(QK_TLS) || defined(QK_EXT_SAVE) 00119 m_osObject = (uint8_t)flags; // m_osObject contains the thread flags 00120 m_thread = tls; // contains the pointer to the thread-local-storage 00121 #else 00122 Q_ASSERT((tls == (void *)0) && (flags == (uint32_t)0)); 00123 #endif 00124 00125 init(ie); // execute initial transition 00126 00127 QS_FLUSH(); // flush the trace buffer to the host 00128 } 00129 //............................................................................ 00130 void QActive::stop(void) { 00131 QF::remove_(this); // remove this active object from the QF 00132 } 00133 00134 #ifdef Q_USE_NAMESPACE 00135 } // namespace QP 00136 #endif 00137 00138 //............................................................................ 00139 extern "C" { 00140 00141 // NOTE: QK schedPrio_() is entered and exited with interrupts DISABLED 00142 uint8_t QK_schedPrio_(void) { 00143 00144 #ifdef Q_USE_NAMESPACE 00145 using namespace QP; 00146 #endif 00147 00148 uint8_t p = QK_readySet_.findMax(); 00149 00150 #ifdef QK_NO_MUTEX 00151 if (p > QK_currPrio_) { // do we have a preemption? 00152 #else // QK priority-ceiling mutexes allowed 00153 if ((p > QK_currPrio_) && (p > QK_ceilingPrio_)) { 00154 #endif 00155 return p; 00156 } 00157 else { 00158 return (uint8_t)0; 00159 } 00160 } 00161 00162 } // extern "C"
1.7.5.1