QP/C
qvanilla.c
Go to the documentation of this file.
00001 /*****************************************************************************
00002 * Product: QF/C
00003 * Last Updated for Version: 4.4.00
00004 * Date of the Last Update:  Jan 21, 2012
00005 *
00006 *                    Q u a n t u m     L e a P s
00007 *                    ---------------------------
00008 *                    innovating embedded systems
00009 *
00010 * Copyright (C) 2002-2012 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
00027 *****************************************************************************/
00028 #include "qf_pkg.h"
00029 #include "qassert.h"
00030 
00031 Q_DEFINE_THIS_MODULE("qvanilla")
00032 
00033 
00040 /* Package-scope objects ---------------------------------------------------*/
00041 #if (QF_MAX_ACTIVE <= 8)
00042     QPSet8  QF_readySet_;                 /* QF-ready set of active objects */
00043 #else
00044     QPSet64 QF_readySet_;                 /* QF-ready set of active objects */
00045 #endif
00046 
00047 /*..........................................................................*/
00048 void QF_init(void) {
00049     /* nothing to do for the "vanilla" kernel */
00050 }
00051 /*..........................................................................*/
00052 void QF_stop(void) {
00053     QF_onCleanup();                                     /* cleanup callback */
00054     /* nothing else to do for the "vanilla" kernel */
00055 }
00056 /*..........................................................................*/
00057 void QF_run(void) {
00058 
00059     QF_onStartup();                                     /* startup callback */
00060 
00061     for (;;) {                                       /* the background loop */
00062         QEvent const *e;
00063         QActive *a;
00064         uint8_t p;
00065 
00066         QF_INT_DISABLE();
00067 
00068 #if (QF_MAX_ACTIVE <= 8)
00069         if (QPSet8_notEmpty(&QF_readySet_)) {
00070             QPSet8_findMax(&QF_readySet_, p);
00071 #else
00072         if (QPSet64_notEmpty(&QF_readySet_)) {
00073             QPSet64_findMax(&QF_readySet_, p);
00074 #endif
00075             a = QF_active_[p];
00076             QF_INT_ENABLE();
00077 
00078             e = QActive_get_(a);          /* get the next event for this AO */
00079             QF_ACTIVE_DISPATCH_(&a->super, e);        /* dispatch to the AO */
00080             QF_gc(e); /* determine if event is garbage and collect it if so */
00081         }
00082         else {
00083             QF_onIdle();                                      /* see NOTE01 */
00084         }
00085     }
00086 }
00087 /*..........................................................................*/
00088 void QActive_start(QActive *me, uint8_t prio,
00089                    QEvent const *qSto[], uint32_t qLen,
00090                    void *stkSto, uint32_t stkSize,
00091                    QEvent const *ie)
00092 {
00093     Q_REQUIRE(((uint8_t)0 < prio) && (prio <= (uint8_t)QF_MAX_ACTIVE)
00094               && (stkSto == (void *)0));   /* does not need per-actor stack */
00095 
00096     (void)stkSize;         /* avoid the "unused parameter" compiler warning */
00097     QEQueue_init(&me->eQueue, qSto, (QEQueueCtr)qLen);/* initialize QEQueue */
00098     me->prio = prio;           /* set the QF priority of this active object */
00099     QF_add_(me);                     /* make QF aware of this active object */
00100     QF_ACTIVE_INIT_(&me->super, ie);          /* execute initial transition */
00101 
00102     QS_FLUSH();                       /* flush the trace buffer to the host */
00103 }
00104 /*..........................................................................*/
00105 void QActive_stop(QActive *me) {
00106     QF_remove_(me);
00107 }
00108 
00109 /*****************************************************************************
00110 * NOTE01:
00111 * QF_onIdle() must be called with interrupts DISABLED because the
00112 * determination of the idle condition (no events in the queues) can change
00113 * at any time by an interrupt posting events to a queue. The QF_onIdle()
00114 * MUST enable interrups internally, perhaps at the same time as putting the
00115 * CPU into a power-saving mode.
00116 */