|
QP/C
|
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 */
1.7.6.1