|
QP/C++
|
00001 00002 // Product: QF/C++ platform-independent public interface 00003 // Last Updated for Version: 4.3.00 00004 // Date of the Last Update: Nov 01, 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 #ifndef qf_h 00029 #define qf_h 00030 00037 00038 #ifdef Q_USE_NAMESPACE 00039 namespace QP { 00040 #endif 00041 00043 #if (QF_MAX_ACTIVE < 1) || (63 < QF_MAX_ACTIVE) 00044 #error "QF_MAX_ACTIVE not defined or out of range. Valid range is 1..63" 00045 #endif 00046 00048 #ifndef QF_EVENT_SIZ_SIZE 00049 00051 #define QF_EVENT_SIZ_SIZE 2 00052 #endif 00053 #if (QF_EVENT_SIZ_SIZE == 1) 00054 00060 typedef uint8_t QEventSize; 00061 #elif (QF_EVENT_SIZ_SIZE == 2) 00062 typedef uint16_t QEventSize; 00063 #elif (QF_EVENT_SIZ_SIZE == 4) 00064 typedef uint32_t QEventSize; 00065 #else 00066 #error "QF_EVENT_SIZ_SIZE defined incorrectly, expected 1, 2, or 4" 00067 #endif 00068 00070 #ifndef QF_MAX_EPOOL 00071 00072 #define QF_MAX_EPOOL 3 00073 #endif 00074 00076 #ifndef QF_ACTIVE_SUPER_ 00077 00093 #define QF_ACTIVE_SUPER_ QHsm 00094 00096 #define QF_ACTIVE_STATE_ QStateHandler 00097 00098 #endif 00099 00100 class QEQueue; // forward declaration 00101 00102 00122 class QActive : public QF_ACTIVE_SUPER_ { 00123 private: 00124 00134 QF_EQUEUE_TYPE m_eQueue; 00135 00136 public: 00137 #ifdef QF_OS_OBJECT_TYPE 00138 00139 00140 00141 00142 00143 00144 QF_OS_OBJECT_TYPE m_osObject; 00145 #endif 00146 00147 #ifdef QF_THREAD_TYPE 00148 00149 00150 00151 00152 00153 00154 QF_THREAD_TYPE m_thread; 00155 #endif 00156 00159 uint8_t m_prio; 00160 00169 uint8_t m_running; 00170 00171 public: 00172 00199 void start(uint8_t prio, 00200 QEvent const *qSto[], uint32_t qLen, 00201 void *stkSto, uint32_t stkSize, 00202 QEvent const *ie = (QEvent *)0); 00203 00222 #ifndef Q_SPY 00223 void postFIFO(QEvent const *e); 00224 #else 00225 void postFIFO(QEvent const *e, void const *sender); 00226 #endif 00227 00235 void postLIFO(QEvent const *e); 00236 00247 void run(void); 00248 00262 QEvent const *get_(void); 00263 00264 protected: 00265 00275 QActive(QF_ACTIVE_STATE_ initial) : QF_ACTIVE_SUPER_(initial) { 00276 } 00277 00291 void stop(void); 00292 00306 void subscribe(QSignal sig) const; 00307 00326 void unsubscribe(QSignal sig) const; 00327 00341 void defer(QEQueue *eq, QEvent const *e); 00342 00358 uint8_t recall(QEQueue *eq); 00359 00360 public: 00379 void unsubscribeAll(void) const; 00380 00381 private: 00382 00383 friend class QF; 00384 friend class QTimeEvt; 00385 #ifndef QF_INT_KEY_TYPE 00386 friend void QK_schedule_(void); 00387 friend void QK_scheduleExt_(void); 00388 #else 00389 friend void QK_schedule_(QF_INT_KEY_TYPE intLockKey); 00390 friend void QK_scheduleExt_(QF_INT_KEY_TYPE intLockKey); 00391 #endif 00392 }; 00393 00394 00396 #ifndef QF_TIMEEVT_CTR_SIZE 00397 00398 00399 #define QF_TIMEEVT_CTR_SIZE 2 00400 #endif 00401 #if (QF_TIMEEVT_CTR_SIZE == 1) 00402 00411 typedef uint8_t QTimeEvtCtr; 00412 #elif (QF_TIMEEVT_CTR_SIZE == 2) 00413 typedef uint16_t QTimeEvtCtr; 00414 #elif (QF_TIMEEVT_CTR_SIZE == 4) 00415 typedef uint32_t QTimeEvtCtr; 00416 #else 00417 #error "QF_TIMEEVT_CTR_SIZE defined incorrectly, expected 1, 2, or 4" 00418 #endif 00419 00451 class QTimeEvt : public QEvent { 00452 private: 00453 00455 QTimeEvt *m_prev; 00456 00458 QTimeEvt *m_next; 00459 00461 QActive *m_act; 00462 00466 QTimeEvtCtr m_ctr; 00467 00472 QTimeEvtCtr m_interval; 00473 00474 public: 00475 00488 QTimeEvt(QSignal s); 00489 00507 void postIn(QActive *act, QTimeEvtCtr nTicks) { 00508 m_interval = (uint16_t)0; 00509 arm_(act, nTicks); 00510 } 00511 00532 void postEvery(QActive *act, QTimeEvtCtr nTicks) { 00533 m_interval = nTicks; 00534 arm_(act, nTicks); 00535 } 00536 00547 uint8_t disarm(void); 00548 00565 uint8_t rearm(QTimeEvtCtr nTicks); 00566 00574 QTimeEvtCtr ctr(void); 00575 00576 private: 00577 00583 void arm_(QActive *act, QTimeEvtCtr nTicks); 00584 00585 friend class QF; 00586 }; 00587 00588 00589 #if (QF_MAX_ACTIVE > 63) 00590 #error "QF_MAX_ACTIVE exceeds 63" 00591 #endif 00592 00599 class QSubscrList { 00600 private: 00601 00610 uint8_t m_bits[((QF_MAX_ACTIVE - 1) / 8) + 1]; 00611 00612 friend class QF; 00613 friend class QActive; 00614 }; 00615 00621 class QF { 00622 public: 00623 00628 static void init(void); 00629 00655 static void psInit(QSubscrList *subscrSto, QSignal maxSignal); 00656 00689 static void poolInit(void *poolSto, uint32_t poolSize, 00690 QEventSize evtSize); 00691 00713 static void run(void); 00714 00720 static void onStartup(void); 00721 00734 static void onCleanup(void); 00735 00736 #ifndef QF_INT_KEY_TYPE 00737 static void onIdle(void); // interrupt lock key NOT defined 00738 00739 #else 00740 00764 static void onIdle(QF_INT_KEY_TYPE intLockKey); // int. lock key defined 00765 00766 #endif // QF_INT_KEY_TYPE 00767 00785 static void stop(void); 00786 00798 #ifndef Q_SPY 00799 static void publish(QEvent const *e); 00800 #else 00801 static void publish(QEvent const *e, void const *sender); 00802 #endif 00803 00818 #ifndef Q_SPY 00819 static void tick(void); 00820 #else 00821 static void tick(void const *sender); 00822 #endif 00823 00833 static char const Q_ROM * Q_ROM_VAR getVersion(void); 00834 00843 static char const Q_ROM * Q_ROM_VAR getPortVersion(void); 00844 00857 static uint32_t getPoolMargin(uint8_t poolId); 00858 00870 static uint32_t getQueueMargin(uint8_t prio); 00871 00876 static QEvent *new_(uint16_t evtSize, QSignal sig); 00877 00878 #ifdef Q_EVT_CTOR 00879 #define Q_NEW(evtT_, sig_, ...) \ 00880 (new(QF::new_(sizeof(evtT_), sig_)) evtT_((sig_), ##__VA_ARGS__)) 00881 #else 00882 00883 00884 00885 00886 00887 00888 00889 00890 00891 00892 00893 00894 00895 #define Q_NEW(evtT_, sig_) ((evtT_ *)QF::new_(sizeof(evtT_), (sig_))) 00896 #endif 00897 00919 static void gc(QEvent const *e); 00920 00924 static QActive *active_[]; 00925 00926 private: // functions to be used in QF ports only 00927 00938 static void add_(QActive *a); 00939 00940 public: 00952 static void remove_(QActive const *a); 00953 00954 friend class QActive; 00955 }; 00956 00958 // useful lookup tables 00959 00969 extern uint8_t const Q_ROM Q_ROM_VAR QF_log2Lkup[256]; 00970 00976 extern uint8_t const Q_ROM Q_ROM_VAR QF_pwr2Lkup[65]; 00977 00983 extern uint8_t const Q_ROM Q_ROM_VAR QF_invPwr2Lkup[65]; 00984 00989 extern uint8_t const Q_ROM Q_ROM_VAR QF_div8Lkup[65]; 00990 00992 // deprecated features defined for backwards compatibility... 00993 #if !defined(QF_CRIT_STAT_TYPE) && defined(QF_INT_KEY_TYPE) 00994 #define QF_CRIT_STAT_TYPE QF_INT_KEY_TYPE 00995 #endif 00996 #if !defined(QF_CRIT_ENTRY) && defined(QF_INT_LOCK) 00997 #define QF_CRIT_ENTRY(stat_) QF_INT_LOCK(stat_) 00998 #endif 00999 #if !defined(QF_CRIT_EXIT) && defined(QF_INT_UNLOCK) 01000 #define QF_CRIT_EXIT(stat_) QF_INT_UNLOCK(stat_) 01001 #endif 01002 01003 #ifdef Q_USE_NAMESPACE 01004 } // namespace QP 01005 #endif 01006 01008 #ifdef Q_EVT_CTOR 01009 #include <new> // for placement new 01010 #endif 01011 01013 // QS software tracing integration, only if enabled 01014 #ifdef Q_SPY // QS software tracing enabled? 01015 #ifndef qs_h 01016 #include "qs_port.h" // include QS port 01017 #endif // qs_h 01018 01037 #define TICK(sender_) tick(sender_) 01038 01058 #define PUBLISH(e_, sender_) publish((e_), (sender_)) 01059 01079 #define POST(e_, sender_) postFIFO((e_), (sender_)) 01080 01081 #if (QF_EQUEUE_CTR_SIZE == 1) 01082 01086 #define QS_EQC_(ctr_) QS::u8_(ctr_) 01087 #elif (QF_EQUEUE_CTR_SIZE == 2) 01088 #define QS_EQC_(ctr_) QS::u16_(ctr_) 01089 #elif (QF_EQUEUE_CTR_SIZE == 4) 01090 #define QS_EQC_(ctr_) QS::u32_(ctr_) 01091 #else 01092 #error "QF_EQUEUE_CTR_SIZE not defined" 01093 #endif 01094 01095 01096 #if (QF_EVENT_SIZ_SIZE == 1) 01097 01101 #define QS_EVS_(size_) QS::u8_(size_) 01102 #elif (QF_EVENT_SIZ_SIZE == 2) 01103 #define QS_EVS_(size_) QS::u16_(size_) 01104 #elif (QF_EVENT_SIZ_SIZE == 4) 01105 #define QS_EVS_(size_) QS::u32_(size_) 01106 #endif 01107 01108 01109 #if (QF_MPOOL_SIZ_SIZE == 1) 01110 01114 #define QS_MPS_(size_) QS::u8_(size_) 01115 #elif (QF_MPOOL_SIZ_SIZE == 2) 01116 #define QS_MPS_(size_) QS::u16_(size_) 01117 #elif (QF_MPOOL_SIZ_SIZE == 4) 01118 #define QS_MPS_(size_) QS::u32_(size_) 01119 #endif 01120 01121 #if (QF_MPOOL_CTR_SIZE == 1) 01122 01126 #define QS_MPC_(ctr_) QS::u8_(ctr_) 01127 #elif (QF_MPOOL_CTR_SIZE == 2) 01128 #define QS_MPC_(ctr_) QS::u16_(ctr_) 01129 #elif (QF_MPOOL_CTR_SIZE == 4) 01130 #define QS_MPC_(ctr_) QS::u32_(ctr_) 01131 #endif 01132 01133 01134 #if (QF_TIMEEVT_CTR_SIZE == 1) 01135 01139 #define QS_TEC_(ctr_) QS::u8_(ctr_) 01140 #elif (QF_TIMEEVT_CTR_SIZE == 2) 01141 #define QS_TEC_(ctr_) QS::u16_(ctr_) 01142 #elif (QF_TIMEEVT_CTR_SIZE == 4) 01143 #define QS_TEC_(ctr_) QS::u32_(ctr_) 01144 #endif 01145 01146 #else 01147 #ifndef qs_dummy_h 01148 #include "qs_dummy.h" // disable the QS software tracing 01149 #endif 01150 01151 #define TICK(dummy_) tick() 01152 #define PUBLISH(e_, dummy_) publish((e_)) 01153 #define POST(e_, dummy_) postFIFO((e_)) 01154 01155 #endif // Q_SPY 01156 01157 #endif // qf_h
1.7.5.1