|
QP/C
|
00001 /***************************************************************************** 00002 * Product: QK/C 00003 * Last Updated for Version: 4.4.00 00004 * Date of the Last Update: Jan 05, 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 "qk_pkg.h" 00029 #include "qassert.h" 00030 00031 Q_DEFINE_THIS_MODULE("qk") 00032 00033 00041 /* Public-scope objects ----------------------------------------------------*/ 00042 #if (QF_MAX_ACTIVE <= 8) 00043 QPSet8 QK_readySet_; /* QK ready-set */ 00044 #else 00045 QPSet64 QK_readySet_; /* QK ready-set */ 00046 #endif 00047 /* start with the QK scheduler locked */ 00048 uint8_t QK_currPrio_ = (uint8_t)(QF_MAX_ACTIVE + 1); 00049 uint8_t QK_intNest_; /* start with nesting level of 0 */ 00050 00051 /*..........................................................................*/ 00052 char_t const Q_ROM * Q_ROM_VAR QK_getVersion(void) { 00053 return QF_getVersion(); 00054 } 00055 /*..........................................................................*/ 00056 void QF_init(void) { 00057 QK_init(); /* might be defined in assembly */ 00058 } 00059 /*..........................................................................*/ 00060 void QF_stop(void) { 00061 QF_onCleanup(); /* cleanup callback */ 00062 /* nothing else to do for the QK preemptive kernel */ 00063 } 00064 /*..........................................................................*/ 00065 static void initialize(void) { 00066 uint8_t p; 00067 00068 QK_currPrio_ = (uint8_t)0; /* set the priority for the QK idle loop */ 00069 p = QK_schedPrio_(); 00070 if (p != (uint8_t)0) { 00071 QK_sched_(p); /* process all events produced so far */ 00072 } 00073 } 00074 /*..........................................................................*/ 00075 void QF_run(void) { 00076 QF_INT_DISABLE(); 00077 initialize(); 00078 QF_onStartup(); /* startup callback */ 00079 QF_INT_ENABLE(); 00080 00081 for (;;) { /* the QK idle loop */ 00082 QK_onIdle(); /* invoke the QK on-idle callback */ 00083 } 00084 } 00085 /*..........................................................................*/ 00086 void QActive_start(QActive *me, uint8_t prio, 00087 QEvent const *qSto[], uint32_t qLen, 00088 void *stkSto, uint32_t stkSize, 00089 QEvent const *ie) 00090 { 00091 Q_REQUIRE(((uint8_t)0 < prio) && (prio <= (uint8_t)QF_MAX_ACTIVE)); 00092 00093 QEQueue_init(&me->eQueue, qSto, (QEQueueCtr)qLen); 00094 me->prio = prio; 00095 QF_add_(me); /* make QF aware of this active object */ 00096 00097 #if defined(QK_TLS) || defined(QK_EXT_SAVE) 00098 me->osObject = (uint8_t)stkSize; /* osObject contains the thread flags */ 00099 me->thread = stkSto;/* contains the pointer to the thread-local storage */ 00100 #else 00101 Q_ASSERT((stkSto == (void *)0) && (stkSize == (uint32_t)0)); 00102 #endif 00103 00104 QF_ACTIVE_INIT_(&me->super, ie); /* execute initial transition */ 00105 00106 QS_FLUSH(); /* flush the trace buffer to the host */ 00107 } 00108 /*..........................................................................*/ 00109 void QActive_stop(QActive *me) { 00110 QF_remove_(me); /* remove this active object from the QF */ 00111 } 00112 /*..........................................................................*/ 00113 /* NOTE: QK schedPrio_() is entered and exited with interrupts DISABLED */ 00114 uint8_t QK_schedPrio_(void) { 00115 uint8_t p; /* highest-priority active object ready to run */ 00116 00117 #if (QF_MAX_ACTIVE <= 8) 00118 /* determine the priority of the highest-priority task ready to run */ 00119 QPSet8_findMax(&QK_readySet_, p); 00120 #else 00121 /* determine the priority of the highest-priority task ready to run */ 00122 QPSet64_findMax(&QK_readySet_, p); 00123 #endif 00124 00125 #ifdef QK_NO_MUTEX 00126 if (p <= QK_currPrio_) { /* do we have a preemption? */ 00127 #else /* QK priority-ceiling mutexes allowed */ 00128 if ((p <= QK_currPrio_) || (p <= QK_ceilingPrio_)) { 00129 #endif 00130 p = (uint8_t)0; 00131 } 00132 return p; 00133 }
1.7.6.1