QP/C++
qf.h
Go to the documentation of this file.
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