|
QP/C++
|
00001 00002 // Product: QK/C++ 00003 // Last Updated for Version: 4.5.00 00004 // Date of the Last Update: May 19, 2012 00005 // 00006 // Q u a n t u m L e a P s 00007 // --------------------------- 00008 // innovating embedded systems 00009 // 00010 // Copyright (C) 2002-2012 Quantum Leaps, LLC. All rights reserved. 00011 // 00012 // This program is open source software: you can redistribute it and/or 00013 // modify it under the terms of the GNU General Public License as published 00014 // by the Free Software Foundation, either version 2 of the License, or 00015 // (at your option) any later version. 00016 // 00017 // Alternatively, this program may be distributed and modified under the 00018 // terms of Quantum Leaps commercial licenses, which expressly supersede 00019 // the GNU General Public License and are specifically designed for 00020 // licensees interested in retaining the proprietary status of their code. 00021 // 00022 // This program is distributed in the hope that it will be useful, 00023 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00024 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00025 // GNU General Public License for more details. 00026 // 00027 // You should have received a copy of the GNU General Public License 00028 // along with this program. If not, see <http://www.gnu.org/licenses/>. 00029 // 00030 // Contact information: 00031 // Quantum Leaps Web sites: http://www.quantum-leaps.com 00032 // http://www.state-machine.com 00033 // e-mail: info@quantum-leaps.com 00035 #include "qk_pkg.h" 00036 #include "qassert.h" 00037 00043 00044 // Public-scope objects ------------------------------------------------------ 00045 extern "C" { 00046 #if (QF_MAX_ACTIVE <= 8) 00047 QP_ QPSet8 QK_readySet_; // ready set of QK 00048 #else 00049 QP_ QPSet64 QK_readySet_; // ready set of QK 00050 #endif 00051 // start with the QK scheduler locked 00052 uint8_t QK_currPrio_ = static_cast<uint8_t>(QF_MAX_ACTIVE + 1); 00053 uint8_t QK_intNest_; // start with nesting level of 0 00054 00055 } // extern "C" 00056 00057 QP_BEGIN_ 00058 00059 Q_DEFINE_THIS_MODULE("qk") 00060 00061 //............................................................................ 00062 char_t const Q_ROM * Q_ROM_VAR QK::getVersion(void) { 00063 uint8_t const u8_zero = static_cast<uint8_t>('0'); 00064 static char_t const Q_ROM Q_ROM_VAR version[] = { 00065 static_cast<char_t>(((QP_VERSION >> 12) & 0xFU) + u8_zero), 00066 static_cast<char_t>('.'), 00067 static_cast<char_t>(((QP_VERSION >> 8) & 0xFU) + u8_zero), 00068 static_cast<char_t>('.'), 00069 static_cast<char_t>(((QP_VERSION >> 4) & 0xFU) + u8_zero), 00070 static_cast<char_t>((QP_VERSION & 0xFU) + u8_zero), 00071 static_cast<char_t>('\0') 00072 }; 00073 return version; 00074 } 00075 //............................................................................ 00076 void QF::init(void) { 00077 QK_init(); // QK initialization ("C" linkage, might be assembly) 00078 } 00079 //............................................................................ 00080 void QF::stop(void) { 00081 QF::onCleanup(); // cleanup callback 00082 // nothing else to do for the QK preemptive kernel 00083 } 00084 //............................................................................ 00085 static void initialize(void) { 00086 QK_currPrio_ = static_cast<uint8_t>(0); // priority for the QK idle loop 00087 uint8_t p = QK_schedPrio_(); 00088 if (p != static_cast<uint8_t>(0)) { 00089 QK_sched_(p); // process all events produced so far 00090 } 00091 } 00092 //............................................................................ 00093 int16_t QF::run(void) { 00094 QF_INT_DISABLE(); 00095 initialize(); 00096 onStartup(); // startup callback 00097 QF_INT_ENABLE(); 00098 00099 for (;;) { // the QK idle loop 00100 QK::onIdle(); // invoke the QK on-idle callback 00101 } 00102 // this unreachable return is to make the compiler happy 00103 return static_cast<int16_t>(0); 00104 } 00105 //............................................................................ 00106 void QActive::start(uint8_t const prio, 00107 QEvt const *qSto[], uint32_t const qLen, 00108 void * const stkSto, uint32_t const stkSize, 00109 QEvt const * const ie) 00110 { 00111 Q_REQUIRE((static_cast<uint8_t>(0) < prio) 00112 && (prio <= static_cast<uint8_t>(QF_MAX_ACTIVE))); 00113 00114 m_eQueue.init(qSto, static_cast<QEQueueCtr>(qLen)); // initialize 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 // in the QK port the parameter stkSize is used as the thread flags 00120 m_osObject = static_cast<uint8_t>(stkSize); // m_osObject contains flags 00121 00122 // in the QK port the parameter stkSto is used as the thread-local-storage 00123 m_thread = stkSto; // contains the pointer to the thread-local-storage 00124 #else 00125 Q_ASSERT((stkSto == static_cast<void *>(0)) 00126 && (stkSize == static_cast<uint32_t>(0))); 00127 #endif 00128 00129 init(ie); // execute initial transition 00130 00131 QS_FLUSH(); // flush the trace buffer to the host 00132 } 00133 //............................................................................ 00134 void QActive::stop(void) { 00135 QF::remove_(this); // remove this active object from the QF 00136 } 00137 00138 QP_END_
1.7.6.1