00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include "qpn_port.h"
00029
00030 Q_DEFINE_THIS_MODULE(qkn)
00031
00032
00038 #ifndef QK_PREEMPTIVE
00039 #error "The required header file qkn.h is not included in qpn_port.h"
00040 #endif
00041
00042
00043
00044 uint8_t volatile QK_currPrio_ = (uint8_t)(QF_MAX_ACTIVE + 1);
00045
00046 #ifdef QF_ISR_NEST
00047 uint8_t volatile QK_intNest_;
00048 #endif
00049
00050
00051 static QActive *l_act;
00052
00053
00054 void QF_run(void) {
00055 static uint8_t p;
00056
00057
00058 for (p = (uint8_t)1; p <= (uint8_t)QF_MAX_ACTIVE; ++p) {
00059 l_act = (QActive *)Q_ROM_PTR(QF_active[p].act);
00060 Q_ASSERT(l_act != (QActive *)0);
00061 l_act->prio = p;
00062 }
00063
00064 for (p = (uint8_t)1; p <= (uint8_t)QF_MAX_ACTIVE; ++p) {
00065 l_act = (QActive *)Q_ROM_PTR(QF_active[p].act);
00066 #ifndef QF_FSM_ACTIVE
00067 QHsm_init((QHsm *)l_act);
00068 #else
00069 QFsm_init((QFsm *)l_act);
00070 #endif
00071 }
00072
00073 QF_INT_LOCK();
00074 QK_currPrio_ = (uint8_t)0;
00075 QK_SCHEDULE_();
00076 QF_INT_UNLOCK();
00077
00078 QF_onStartup();
00079
00080 for (;;) {
00081 QK_onIdle();
00082 }
00083 }
00084
00085
00086 void QK_schedule_(void) Q_REENTRANT {
00087 static uint8_t const Q_ROM Q_ROM_VAR log2Lkup[] = {
00088 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4
00089 };
00090 static uint8_t const Q_ROM Q_ROM_VAR invPow2Lkup[] = {
00091 0xFF, 0xFE, 0xFD, 0xFB, 0xF7, 0xEF, 0xDF, 0xBF, 0x7F
00092 };
00093
00094 uint8_t pin;
00095 uint8_t p;
00096
00097
00098 #if (QF_MAX_ACTIVE > 4)
00099 if ((QF_readySet_ & 0xF0) != 0) {
00100 p = (uint8_t)(Q_ROM_BYTE(log2Lkup[QF_readySet_ >> 4]) + 4);
00101 }
00102 else
00103 #endif
00104 {
00105 p = Q_ROM_BYTE(log2Lkup[QF_readySet_]);
00106 }
00107
00108 if (p > QK_currPrio_) {
00109 pin = QK_currPrio_;
00110 do {
00111 QK_currPrio_ = p;
00112 QF_INT_UNLOCK();
00113
00114
00115 #ifndef QF_FSM_ACTIVE
00116 QHsm_dispatch((QHsm *)Q_ROM_PTR(QF_active[p].act));
00117 #else
00118 QFsm_dispatch((QFsm *)Q_ROM_PTR(QF_active[p].act));
00119 #endif
00120
00121 QF_INT_LOCK();
00122
00123 l_act = (QActive *)Q_ROM_PTR(QF_active[p].act);
00124
00125 if ((--l_act->nUsed) == (uint8_t)0) {
00126
00127 QF_readySet_ &= Q_ROM_BYTE(invPow2Lkup[p]);
00128 }
00129 else {
00130 Q_SIG(l_act) = ((QEvent *)Q_ROM_PTR(QF_active[p].queue))
00131 [l_act->tail].sig;
00132 #if (Q_PARAM_SIZE != 0)
00133 Q_PAR(l_act) = ((QEvent *)Q_ROM_PTR(QF_active[p].queue))
00134 [l_act->tail].par;
00135 #endif
00136 if (l_act->tail == (uint8_t)0) {
00137 l_act->tail = Q_ROM_BYTE(QF_active[p].end);
00138 }
00139 --l_act->tail;
00140 }
00141
00142 if (QF_readySet_ != (uint8_t)0) {
00143 #if (QF_MAX_ACTIVE > 4)
00144 if ((QF_readySet_ & 0xF0) != 0) {
00145 p = (uint8_t)(Q_ROM_BYTE(log2Lkup[QF_readySet_ >> 4])+ 4);
00146 }
00147 else
00148 #endif
00149 {
00150 p = Q_ROM_BYTE(log2Lkup[QF_readySet_]);
00151 }
00152 }
00153 else {
00154 p = (uint8_t)0;
00155 }
00156
00157 } while (p > pin);
00158 QK_currPrio_ = pin;
00159 }
00160 }
00161
00162 #ifdef QK_MUTEX
00163
00164 QMutex QK_mutexLock(uint8_t prioCeiling) {
00165 uint8_t mutex;
00166 QF_INT_LOCK();
00167 mutex = QK_currPrio_;
00168 if (QK_currPrio_ < prioCeiling) {
00169 QK_currPrio_ = prioCeiling;
00170 }
00171 QF_INT_UNLOCK();
00172 return mutex;
00173 }
00174
00175 void QK_mutexUnlock(QMutex mutex) {
00176 QF_INT_LOCK();
00177 if (QK_currPrio_ > mutex) {
00178 QK_currPrio_ = mutex;
00179 QK_SCHEDULE_();
00180 }
00181 QF_INT_UNLOCK();
00182 }
00183 #endif