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