搜索
bottom↓
回复: 8

关于 QP nano 事件误触发

[复制链接]

出0入0汤圆

发表于 2015-5-1 23:21:53 来自手机 | 显示全部楼层 |阅读模式
State-a-fun(){
}
状态A开自带定时函数,当状态A退出当前状态的时候,定时器触发Timeout事件,存放在事件队列里,如果这时候状态转到了状态B,那么Timeout事件就是否直接被带动状态B处理了,


困惑我好几天了,忘高人解答

阿莫论坛20周年了!感谢大家的支持与爱护!!

月入3000的是反美的。收入3万是亲美的。收入30万是移民美国的。收入300万是取得绿卡后回国,教唆那些3000来反美的!

出0入0汤圆

发表于 2015-5-1 23:59:50 | 显示全部楼层
  正在看qp的书,但是看不懂楼主想表达的意思。

出0入0汤圆

发表于 2015-5-2 00:28:01 来自手机 | 显示全部楼层
楼主描述有点乱。
会。状态b不处理不就行了。

出0入0汤圆

 楼主| 发表于 2015-5-2 15:29:07 来自手机 | 显示全部楼层
qpnano一个对象只有一个内置的定时器,状态B也会用到这个定时器,和Timeout事件

出0入0汤圆

发表于 2015-5-2 15:57:21 来自手机 | 显示全部楼层
实在看不懂你在说什么

出0入0汤圆

发表于 2015-5-2 16:00:50 来自手机 | 显示全部楼层
没看懂,楼主看的什么书

出0入0汤圆

发表于 2015-5-2 19:31:56 | 显示全部楼层
这可要看你的runtime是不是抢占式的了 QF要等到QF_tick()执行后才切换活动对象的状态机

出0入0汤圆

 楼主| 发表于 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);
}

出0入0汤圆

 楼主| 发表于 2015-5-4 10:35:17 | 显示全部楼层
lansen0815 发表于 2015-5-2 19:31
这可要看你的runtime是不是抢占式的了 QF要等到QF_tick()执行后才切换活动对象的状态机 ...

不是抢占式的,事件TIMEOUT在中断中发射到事件队列的,而且事件派发后,事件的处理是没有关中断的
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-25 08:59

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表