|
楼主 |
发表于 2015-5-4 09:03:19
|
显示全部楼层
前几天不好意思啊,在家里用手机,所以不好弄
以下是 调度器
int_t QF_run(void) {
uint8_t p;
QActive *a;
/* set priorities all registered active objects... */
for (p = (uint8_t)1; p <= (uint8_t)QF_MAX_ACTIVE; ++p) {
a = QF_ROM_ACTIVE_GET_(p);
Q_ASSERT(a != (QActive *)0); /* QF_active[p] must be initialized */
a->prio = p; /* set the priority of the active object */
}
/* trigger initial transitions in all registered active objects... */
for (p = (uint8_t)1; p <= (uint8_t)QF_MAX_ACTIVE; ++p) {
a = QF_ROM_ACTIVE_GET_(p);
QMSM_INIT(&a->super); /* take the initial transition in the SM */
}
QF_onStartup(); /* invoke startup callback */
for (;;) { /* the event loop of the vanilla kernel */
QF_INT_DISABLE();
if (QF_readySet_ != (uint8_t)0) {
QActiveCB const Q_ROM *acb;
#ifdef QF_LOG2
p = QF_LOG2(QF_readySet_);
#else
#if (QF_MAX_ACTIVE > 4)
if ((QF_readySet_ & (uint8_t)0xF0) != (uint8_t)0) {/*hi nibble? */
p = (uint8_t)(Q_ROM_BYTE(QF_log2Lkup[QF_readySet_ >> 4])
+ (uint8_t)4);
}
else /* hi nibble of QF_readySet_ is zero */
#endif
{
p = Q_ROM_BYTE(QF_log2Lkup[QF_readySet_]);
}
#endif
acb = &QF_active[p];
a = QF_ROM_ACTIVE_GET_(p);
Q_ASSERT(a->nUsed > (uint8_t)0);/*some events must be available */
--a->nUsed;
if (a->nUsed == (uint8_t)0) { /* queue becoming empty? */
QF_readySet_ &= Q_ROM_BYTE(l_invPow2Lkup[p]); /* clear bit */
}
Q_SIG(a) = QF_ROM_QUEUE_AT_(acb, a->tail).sig;
#if (Q_PARAM_SIZE != 0)
Q_PAR(a) = QF_ROM_QUEUE_AT_(acb, a->tail).par;
#endif
if (a->tail == (uint8_t)0) { /* wrap around? */
a->tail = Q_ROM_BYTE(acb->end);
}
--a->tail;
QF_INT_ENABLE();
QMSM_DISPATCH(&a->super); /* dispatch to the SM */
}
else {
QF_onIdle(); /* see NOTE01 */
}
}
#ifdef __GNUC__ /* GNU compiler? */
return (int_t)0;
#endif
}
事件派发事件的时候,关中断,处理事件的时候中断是打开的
以下是 TICK 对象的一次性定时器派发程序 ,中断中派发的
void QF_tickXISR(uint8_t const tickRate) {
uint8_t p = (uint8_t)QF_MAX_ACTIVE;
do {
QActive *a = QF_ROM_ACTIVE_GET_(p);
if (a->tickCtr[tickRate] != (QTimeEvtCtr)0) {
--a->tickCtr[tickRate];
if (a->tickCtr[tickRate] == (QTimeEvtCtr)0) {
#ifdef Q_TIMERSET
QF_timerSetX_[tickRate] &= Q_ROM_BYTE(l_invPow2Lkup[p]);
#endif
#if (Q_PARAM_SIZE != 0)
QACTIVE_POST_ISR(a, (enum_t)Q_TIMEOUT_SIG + (enum_t)tickRate,
(QParam)0);
#else
QACTIVE_POST_ISR(a, (enum_t)Q_TIMEOUT_SIG + (enum_t)tickRate);
#endif
}
}
--p;
} while (p != (uint8_t)0);
}
那我的问题是,led ON 时候等待KEY_PRESS_SINGLE 和 TIMEOUT_SINGLE (QP NANO 自带动,tick 里面中断发送到事件),
当KEY_PRESS_SINGLE 正在处理的时候,中断的TIMEOUT_SINGLE也触发了,而且进入到事件队列里,还有处理掉,而这个时候KEY_PRESS_SINGLE 的处理,已经把当前的状态转移到下个状态了,那么在下一个状态就多 了一个TIMEOUT_SINGLE 要处理, 百思不解啊,是我理解错了吗?
QState Led_on(Led *me)
{
switch(Q_SIG(me))
{
case Q_ENTRY_SIG:
{
BSP_ledOn( );
return Q_HANDLED( );
}
case Q_KEY_PRESS_SIG:
{
return Q_TRAN(&Led_off);
}
case Q_TIMEOUT_SIG:
{
QActive_arm((QActive*)me, 125);
return Q_TRAN(&Led_off);
}
}
return Q_SUPER(&QHsm_top);
} |
|