|
QP/C++
|
00001 00002 // Product: QP/C++ 00003 // Last Updated for Version: 4.5.04 00004 // Date of the Last Update: Feb 04, 2013 00005 // 00006 // Q u a n t u m L e a P s 00007 // --------------------------- 00008 // innovating embedded systems 00009 // 00010 // Copyright (C) 2002-2013 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 #ifndef qf_h 00036 #define qf_h 00037 00044 00046 #ifdef Q_EVT_CTOR 00047 #include <new> // for placement new 00048 #endif 00049 00051 // apply defaults for all undefined configuration parameters 00052 // 00053 #ifndef QF_EVENT_SIZ_SIZE 00054 00055 #define QF_EVENT_SIZ_SIZE 2 00056 #endif 00057 00058 #ifndef QF_MAX_EPOOL 00059 00060 #define QF_MAX_EPOOL 3 00061 #endif 00062 00063 #ifndef QF_TIMEEVT_CTR_SIZE 00064 00065 00066 #define QF_TIMEEVT_CTR_SIZE 2 00067 #endif 00068 00069 #if (QF_MAX_ACTIVE < 1) || (63 < QF_MAX_ACTIVE) 00070 #error "QF_MAX_ACTIVE not defined or out of range. Valid range is 1..63" 00071 #endif 00072 00073 #ifndef QF_ACTIVE_SUPER_ 00074 00090 #define QF_ACTIVE_SUPER_ QHsm 00091 00093 #define QF_ACTIVE_STATE_ QStateHandler 00094 00095 #endif 00096 00098 QP_BEGIN_ 00099 00101 #if (QF_EVENT_SIZ_SIZE == 1) 00102 00108 typedef uint8_t QEvtSize; 00109 #elif (QF_EVENT_SIZ_SIZE == 2) 00110 typedef uint16_t QEvtSize; 00111 #elif (QF_EVENT_SIZ_SIZE == 4) 00112 typedef uint32_t QEvtSize; 00113 #else 00114 #error "QF_EVENT_SIZ_SIZE defined incorrectly, expected 1, 2, or 4" 00115 #endif 00116 00118 #if (QF_TIMEEVT_CTR_SIZE == 1) 00119 00120 00121 00122 00123 00124 00125 00126 00127 typedef uint8_t QTimeEvtCtr; 00128 #elif (QF_TIMEEVT_CTR_SIZE == 2) 00129 typedef uint16_t QTimeEvtCtr; 00130 #elif (QF_TIMEEVT_CTR_SIZE == 4) 00131 typedef uint32_t QTimeEvtCtr; 00132 #else 00133 #error "QF_TIMEEVT_CTR_SIZE defined incorrectly, expected 1, 2, or 4" 00134 #endif 00135 00136 class QEQueue; // forward declaration 00137 00158 class QActive : public QF_ACTIVE_SUPER_ { 00159 00160 #ifdef QF_EQUEUE_TYPE 00161 00162 00163 00164 00165 00166 00167 00168 00169 00170 QF_EQUEUE_TYPE m_eQueue; 00171 #endif 00172 00173 #ifdef QF_OS_OBJECT_TYPE 00174 00175 00176 00177 00178 00179 00180 QF_OS_OBJECT_TYPE m_osObject; 00181 #endif 00182 00183 #ifdef QF_THREAD_TYPE 00184 00185 00186 00187 00188 00189 00190 QF_THREAD_TYPE m_thread; 00191 #endif 00192 00195 uint8_t m_prio; 00196 00197 public: 00224 void start(uint8_t const prio, 00225 QEvt const *qSto[], uint32_t const qLen, 00226 void * const stkSto, uint32_t const stkSize, 00227 QEvt const * const ie = static_cast<QEvt *>(0)); 00228 00247 #ifndef Q_SPY 00248 void postFIFO(QEvt const * const e); 00249 #else 00250 void postFIFO(QEvt const * const e, void const * const sender); 00251 #endif 00252 00271 void unsubscribeAll(void) const; 00272 00273 protected: 00283 QActive(QF_ACTIVE_STATE_ const initial) : QF_ACTIVE_SUPER_(initial) { 00284 } 00285 00293 void postLIFO(QEvt const * const e); 00294 00308 void stop(void); 00309 00323 void subscribe(enum_t const sig) const; 00324 00343 void unsubscribe(enum_t const sig) const; 00344 00358 void defer(QEQueue * const eq, QEvt const * const e) const; 00359 00375 bool recall(QEQueue * const eq); 00376 00377 private: 00378 00392 QEvt const *get_(void); 00393 00394 friend class QF; 00395 friend class QTimeEvt; 00396 00397 #ifdef qk_h // is this QK port? 00398 friend void ::QK_schedExt_(uint8_t p); 00399 friend void ::QK_sched_(uint8_t p); 00400 #endif 00401 00402 }; 00403 00435 class QTimeEvt : public QEvt { 00436 private: 00437 00439 QTimeEvt *m_next; 00440 00442 QActive *m_act; 00443 00447 QTimeEvtCtr m_ctr; 00448 00453 QTimeEvtCtr m_interval; 00454 00455 public: 00456 00469 QTimeEvt(enum_t const s); 00470 00488 void postIn(QActive * const act, QTimeEvtCtr const nTicks) { 00489 m_interval = static_cast<QTimeEvtCtr>(0); 00490 arm_(act, nTicks); 00491 } 00492 00513 void postEvery(QActive * const act, QTimeEvtCtr const nTicks) { 00514 m_interval = nTicks; 00515 arm_(act, nTicks); 00516 } 00517 00528 bool disarm(void); 00529 00546 bool rearm(QTimeEvtCtr const nTicks); 00547 00555 QTimeEvtCtr ctr(void) const; 00556 00557 private: 00558 00564 void arm_(QActive * const act, QTimeEvtCtr const nTicks); 00565 00566 friend class QF; 00567 }; 00568 00569 00575 uint8_t const QF_SUBSCR_LIST_SIZE = 00576 static_cast<uint8_t>(((QF_MAX_ACTIVE - 1) / 8) + 1); 00577 00583 class QSubscrList { 00584 private: 00585 00594 uint8_t m_bits[QF_SUBSCR_LIST_SIZE]; 00595 00596 friend class QF; 00597 friend class QActive; 00598 }; 00599 00605 class QF { 00606 public: 00607 00612 static void init(void); 00613 00639 static void psInit(QSubscrList * const subscrSto, 00640 uint32_t const maxSignal); 00641 00674 static void poolInit(void * const poolSto, uint32_t const poolSize, 00675 uint32_t const evtSize); 00676 00699 static int16_t run(void); 00700 00706 static void onStartup(void); 00707 00720 static void onCleanup(void); 00721 00746 static void onIdle(void); 00747 00765 static void stop(void); 00766 00778 #ifndef Q_SPY 00779 static void publish(QEvt const *e); 00780 #else 00781 static void publish(QEvt const *e, void const *sender); 00782 #endif 00783 00798 #ifndef Q_SPY 00799 static void tick(void); 00800 #else 00801 static void tick(void const * const sender); 00802 #endif 00803 00808 static bool noTimeEvtsActive(void); 00809 00819 static char_t const Q_ROM * Q_ROM_VAR getVersion(void); 00820 00833 static uint32_t getPoolMargin(uint8_t const poolId); 00834 00846 static uint32_t getQueueMargin(uint8_t const prio); 00847 00852 static QEvt *new_(QEvtSize const evtSize, enum_t const sig); 00853 00875 static void gc(QEvt const *e); 00876 00877 private: // functions to be used in QF ports only 00878 00889 static void add_(QActive * const a); 00890 00891 public: 00903 static void remove_(QActive const * const a); 00904 00908 static QActive *active_[]; 00909 00914 static void thread_(QActive *act); 00915 00916 friend class QActive; 00917 }; 00918 00919 QP_END_ 00920 00922 #ifdef Q_EVT_CTOR // Provide the constructor for the QEvt class? 00923 00938 #define Q_NEW(evtT_, sig_, ...) \ 00939 (new(QP_ QF::new_( \ 00940 static_cast<QP_ QEvtSize>(sizeof(evtT_)), (sig_))) \ 00941 evtT_((sig_), ##__VA_ARGS__)) 00942 #else // QEvt is a POD (Plain Old Datatype) 00943 00944 #define Q_NEW(evtT_, sig_) \ 00945 (static_cast<evtT_ *>( \ 00946 QP_ QF::new_(static_cast<QP_ QEvtSize>(sizeof(evtT_)), (sig_)))) 00947 #endif 00948 00950 // QS software tracing integration, only if enabled 00951 #ifdef Q_SPY // QS software tracing enabled? 00952 00972 #define TICK(sender_) tick(sender_) 00973 00992 #define PUBLISH(e_, sender_) publish((e_), (sender_)) 00993 01012 #define POST(e_, sender_) postFIFO((e_), (sender_)) 01013 01014 #else 01015 01016 #define TICK(dummy_) tick() 01017 #define PUBLISH(e_, dummy_) publish(e_) 01018 #define POST(e_, dummy_) postFIFO(e_) 01019 01020 #endif // Q_SPY 01021 01022 #endif // qf_h
1.7.6.1