QP/C
qf.h
Go to the documentation of this file.
00001 /*****************************************************************************
00002 * Product: QP/C
00003 * Last Updated for Version: 4.5.04
00004 * Date of the Last Update:  Feb 05, 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
00034 *****************************************************************************/
00035 #ifndef qf_h
00036 #define qf_h
00037 
00047 /****************************************************************************/
00048 #if (QF_MAX_ACTIVE < 1) || (63 < QF_MAX_ACTIVE)
00049     #error "QF_MAX_ACTIVE not defined or out of range. Valid range is 1..63"
00050 #endif
00051 
00052 /****************************************************************************/
00053 #ifndef QF_EVENT_SIZ_SIZE
00054 
00056     #define QF_EVENT_SIZ_SIZE 2
00057 #endif
00058 #if (QF_EVENT_SIZ_SIZE == 1)
00059 
00065     typedef uint8_t QEvtSize;
00066 #elif (QF_EVENT_SIZ_SIZE == 2)
00067     typedef uint16_t QEvtSize;
00068 #elif (QF_EVENT_SIZ_SIZE == 4)
00069     typedef uint32_t QEvtSize;
00070 #else
00071     #error "QF_EVENT_SIZ_SIZE defined incorrectly, expected 1, 2, or 4"
00072 #endif
00073 
00074 /****************************************************************************/
00075 #ifndef QF_MAX_EPOOL
00076 
00078     #define QF_MAX_EPOOL 3
00079 #endif
00080 
00081 /****************************************************************************/
00082 #ifndef QF_ACTIVE_SUPER_
00083 
00101     #define QF_ACTIVE_SUPER_               QHsm
00102 
00106     #define QF_ACTIVE_CTOR_(me_, initial_) QHsm_ctor((me_), (initial_))
00107 
00111     #define QF_ACTIVE_INIT_(me_, e_)       (QHsm_init((me_), (e_)))
00112 
00116     #define QF_ACTIVE_DISPATCH_(me_, e_)   (QHsm_dispatch((me_), (e_)))
00117 
00120     #define QF_ACTIVE_STATE_               QStateHandler
00121 
00122 #endif
00123 
00124 struct QEQueueTag;                                   /* forward declaration */
00125 
00126 /****************************************************************************/
00147 typedef struct QActiveTag {
00151     QF_ACTIVE_SUPER_ super;
00152 
00153 #ifdef QF_EQUEUE_TYPE
00154 
00164     QF_EQUEUE_TYPE eQueue;
00165 #endif
00166 
00167 #ifdef QF_OS_OBJECT_TYPE
00168 
00175     QF_OS_OBJECT_TYPE osObject;
00176 #endif
00177 
00178 #ifdef QF_THREAD_TYPE
00179 
00185     QF_THREAD_TYPE thread;
00186 #endif
00187 
00191     uint8_t prio;
00192 
00193 } QActive;
00194 
00195 /* public functions */
00223 void QActive_start(QActive * const me, uint8_t prio,
00224                    QEvt const *qSto[], uint32_t qLen,
00225                    void *stkSto, uint32_t stkSize,
00226                    QEvt const *ie);
00227 
00228 #ifdef Q_SPY
00229 
00250     void QActive_postFIFO(QActive * const me, QEvt const * const e,
00251                           void const * const sender);
00252 
00272     #define QACTIVE_POST(me_, e_, sender_) \
00273         (QActive_postFIFO((me_), (e_), (void const *)(sender_)))
00274 
00275 #else
00276 
00277     void QActive_postFIFO(QActive * const me, QEvt const * const e);
00278     #define QACTIVE_POST(me_, e_, dummy_) (QActive_postFIFO((me_), (e_)))
00279 
00280 #endif
00281 
00290 void QActive_postLIFO(QActive * const me, QEvt const * const e);
00291 
00292 /* protected functions ...*/
00293 
00310 #define QActive_ctor(me_, initial_) QF_ACTIVE_CTOR_(&(me_)->super, (initial_))
00311 
00325 void QActive_stop(QActive * const me);
00326 
00341 void QActive_subscribe(QActive const * const me, enum_t const sig);
00342 
00362 void QActive_unsubscribe(QActive const * const me, enum_t const sig);
00363 
00383 void QActive_unsubscribeAll(QActive const * const me);
00384 
00385 
00400 void QActive_defer(QActive * const me,
00401                    QEQueue * const eq, QEvt const * const e);
00402 
00419 uint8_t QActive_recall(QActive * const me, QEQueue * const eq);
00420 
00431 QEvt const *QActive_get_(QActive *const me);
00432 /* friend class QF; */
00433 /* friend class QTimeEvt; */
00434 
00435 /****************************************************************************/
00436 #ifndef QF_TIMEEVT_CTR_SIZE
00437 
00440     #define QF_TIMEEVT_CTR_SIZE 2
00441 #endif
00442 #if (QF_TIMEEVT_CTR_SIZE == 1)
00443 
00453     typedef uint8_t QTimeEvtCtr;
00454 #elif (QF_TIMEEVT_CTR_SIZE == 2)
00455     typedef uint16_t QTimeEvtCtr;
00456 #elif (QF_TIMEEVT_CTR_SIZE == 4)
00457     typedef uint32_t QTimeEvtCtr;
00458 #else
00459     #error "QF_TIMEEVT_CTR_SIZE defined incorrectly, expected 1, 2, or 4"
00460 #endif
00461 
00495 typedef struct QTimeEvtTag {
00499     QEvt super;
00500 
00503     struct QTimeEvtTag *next;
00504 
00507     QActive *act;
00508 
00513     QTimeEvtCtr ctr;
00514 
00520     QTimeEvtCtr interval;
00521 } QTimeEvt;
00522 
00523 /* public functions */
00524 
00538 void QTimeEvt_ctor(QTimeEvt * const me, enum_t const sig);
00539 
00558 #define QTimeEvt_postIn(me_, act_, nTicks_) do { \
00559     (me_)->interval = (QTimeEvtCtr)0; \
00560     QTimeEvt_arm_((me_), (act_), (nTicks_)); \
00561 } while (0)
00562 
00584 #define QTimeEvt_postEvery(me_, act_, nTicks_) do { \
00585     (me_)->interval = (nTicks_); \
00586     QTimeEvt_arm_((me_), (act_), (nTicks_)); \
00587 } while (0)
00588 
00600 uint8_t QTimeEvt_disarm(QTimeEvt * const me);
00601 
00619 uint8_t QTimeEvt_rearm(QTimeEvt * const me, QTimeEvtCtr const nTicks);
00620 
00629 QTimeEvtCtr QTimeEvt_ctr(QTimeEvt const * const me);
00630 
00631 /* private functions */
00632 
00638 void QTimeEvt_arm_(QTimeEvt * const me,
00639                    QActive * const act, QTimeEvtCtr const nTicks);
00640 
00641 /* friend class QF; */
00642 
00643 /*****************************************************************************
00644 * QF facilities
00645 */
00646 
00655 typedef struct QSubscrListTag {
00656 
00666     uint8_t bits[((QF_MAX_ACTIVE - 1) / 8) + 1];
00667 } QSubscrList;
00668 
00669 /* public functions */
00670 
00676 void QF_init(void);
00677 
00702 void QF_psInit(QSubscrList * const subscrSto, uint32_t const maxSignal);
00703 
00735 void QF_poolInit(void * const poolSto, uint32_t const poolSize,
00736                  uint32_t const evtSize);
00737 
00759 int16_t QF_run(void);
00760 
00779 void QF_stop(void);
00780 
00787 void QF_onStartup(void);
00788 
00802 void QF_onCleanup(void);
00803 
00827 void QF_onIdle(void);
00828 
00829 #ifdef Q_SPY
00830 
00845     void QF_publish(QEvt const * const e, void const * const sender);
00846 
00866     #define QF_PUBLISH(e_, sender_) \
00867         (QF_publish((e_), (void const *)(sender_)))
00868 #else
00869 
00870     void QF_publish(QEvt const * const e);
00871     #define QF_PUBLISH(e_, dummy_)   (QF_publish(e_))
00872 
00873 #endif
00874 
00875 #ifdef Q_SPY
00876 
00891     void QF_tick(void const * const sender);
00892 
00912     #define QF_TICK(sender_)              (QF_tick(sender_))
00913 
00914 #else
00915 
00916     void QF_tick(void);
00917     #define QF_TICK(dummy_)               (QF_tick())
00918 
00919 #endif
00920 
00926 uint8_t QF_noTimeEvtsActive(void);
00927 
00928 
00929 /* functions used in the QF ports only -------------------------------------*/
00930 
00942 void QF_add_(QActive * const a);
00943 
00956 void QF_remove_(QActive const * const a);
00957 
00968 char_t const Q_ROM * Q_ROM_VAR QF_getVersion(void);
00969 
00979 char_t const Q_ROM * Q_ROM_VAR QF_getPortVersion(void);
00980 
00993 uint32_t QF_getPoolMargin(uint8_t const poolId);
00994 
01007 uint32_t QF_getQueueMargin(uint8_t const prio);
01008 
01009 
01010 #ifdef Q_EVT_CTOR            /* Provide the constructor for the QEvt class? */
01011 
01017     QEvt *QF_new_(QEvtSize const evtSize);
01018 
01033     #define Q_NEW(evtT_, sig_, ...) \
01034         (evtT_##_ctor((evtT_ *)QF_new_((QEvtSize)sizeof(evtT_)), \
01035                       (sig_), ##__VA_ARGS__))
01036 #else
01037 
01038     QEvt *QF_new_(QEvtSize const evtSize, enum_t const sig);
01039 
01040     #define Q_NEW(evtT_, sig_) \
01041         ((evtT_ *)QF_new_((QEvtSize)sizeof(evtT_), (sig_)))
01042 
01043 #endif                                                        /* Q_EVT_CTOR */
01044 
01045 
01067 void QF_gc(QEvt const * const e);
01068 
01069 
01070 /****************************************************************************/
01071 /* Useful lookup tables ...*/
01077 extern uint8_t const Q_ROM Q_ROM_VAR QF_pwr2Lkup[65];
01078 
01084 extern uint8_t const Q_ROM Q_ROM_VAR QF_invPwr2Lkup[65];
01085 
01090 extern uint8_t const Q_ROM Q_ROM_VAR QF_div8Lkup[65];
01091 
01092 /* Log-base-2 calculations ...*/
01093 #ifndef QF_LOG2
01094 
01104     #define QF_LOG2(n_) (Q_ROM_BYTE(QF_log2Lkup[(n_)]))
01105 
01112     extern uint8_t const Q_ROM Q_ROM_VAR QF_log2Lkup[256];
01113 
01114 #endif                                                           /* QF_LOG2 */
01115 
01116 
01121 extern QActive *QF_active_[QF_MAX_ACTIVE + 1];
01122 
01123 #endif                                                              /* qf_h */