搜索
bottom↓
回复: 6

ucos-ii高手请进

[复制链接]

出0入0汤圆

发表于 2009-9-17 17:04:55 | 显示全部楼层 |阅读模式
最近在学习ucosii,有一个问题希望哪位高手指点一下  就是消息邮箱的挂起函数,有一段不知道为什么要这样。源程序如下:
void *OSMboxPend (OS_EVENT *pevent, INT16U timeout, INT8U *err)
{
    void  *msg;

    OS_ENTER_CRITICAL();
    if (pevent->OSEventType != OS_EVENT_TYPE_MBOX) {                      (1)
        OS_EXIT_CRITICAL();
        *err = OS_ERR_EVENT_TYPE;
        return ((void *)0);
    }
    msg = pevent->OSEventPtr;
    if (msg != (void *)0) {                                               (2)
        pevent->OSEventPtr = (void *)0;                                   (3)
        OS_EXIT_CRITICAL();
        *err = OS_NO_ERR;
    } else if (OSIntNesting > 0) {                                        (4)
        OS_EXIT_CRITICAL();
        *err = OS_ERR_PEND_ISR;
    } else {
        OSTCBCur->OSTCBStat |= OS_STAT_MBOX;                              (5)
        OSTCBCur->OSTCBDly   = timeout;
        OSEventTaskWait(pevent);
        OS_EXIT_CRITICAL();
        OSSched();
        OS_ENTER_CRITICAL();
        if ((msg = OSTCBCur->OSTCBMsg) != (void *)0) {                    (6)
            OSTCBCur->OSTCBMsg      = (void *)0;
            OSTCBCur->OSTCBStat     = OS_STAT_RDY;
            OSTCBCur->OSTCBEventPtr = (OS_EVENT *)0;
            OS_EXIT_CRITICAL();
            *err                    = OS_NO_ERR;
        } else if (OSTCBCur->OSTCBStat & OS_STAT_MBOX) {                  (7)
            OSEventTO(pevent);                                            (8)
            OS_EXIT_CRITICAL();
            msg                     = (void *)0;                          (9)
            *err                    = OS_TIMEOUT;
        } else {                                                        (?????)
            msg                     = pevent->OSEventPtr;                (10)
            pevent->OSEventPtr      = (void *)0;                            (11)
            OSTCBCur->OSTCBEventPtr = (OS_EVENT *)0;                     (12)
            OS_EXIT_CRITICAL();
            *err                    = OS_NO_ERR;
        }
    }
    return (msg);
}



问题是:(10)标号上方这个else(即标有问号的那一行),程序在什么情况下会出现这种可能性呢???即任务控制块中没有消息指针,而任务等待消息的状态标志又被清掉了,这是一种什么情况呢???恳请哪位高手指点一下,呵呵,不胜感激。

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

一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。

出0入0汤圆

发表于 2009-9-22 16:02:39 | 显示全部楼层
这个问题很简单,(6)之前任务重新调度,
6之后任务重新就绪,
1是队列就绪,2是超时,第三种情况我给出一种答案
#if OS_Q_PEND_ABORT_EN > 0
INT8U  OSQPendAbort (OS_EVENT *pevent, INT8U opt, INT8U *perr)
{
    INT8U      nbr_tasks;
#if OS_CRITICAL_METHOD == 3                                /* Allocate storage for CPU status register */
    OS_CPU_SR  cpu_sr = 0;
#endif



#if OS_ARG_CHK_EN > 0
    if (perr == (INT8U *)0) {                              /* Validate 'perr'                          */
        return (0);
    }
    if (pevent == (OS_EVENT *)0) {                         /* Validate 'pevent'                        */
        *perr = OS_ERR_PEVENT_NULL;
        return (0);
    }
#endif
    if (pevent->OSEventType != OS_EVENT_TYPE_Q) {          /* Validate event block type                */
        *perr = OS_ERR_EVENT_TYPE;
        return (0);
    }
    OS_ENTER_CRITICAL();
    if (pevent->OSEventGrp != 0) {                         /* See if any task waiting on queue?        */
        nbr_tasks = 0;
        switch (opt) {
            case OS_PEND_OPT_BROADCAST:                    /* Do we need to abort ALL waiting tasks?   */
                 while (pevent->OSEventGrp != 0) {         /* Yes, ready ALL tasks waiting on queue    */
                     (void)OS_EventTaskRdy(pevent, (void *)0, OS_STAT_Q, OS_STAT_PEND_ABORT);
                     nbr_tasks++;
                 }
                 break;
               
            case OS_PEND_OPT_NONE:
            default:                                       /* No,  ready HPT       waiting on queue    */
                 (void)OS_EventTaskRdy(pevent, (void *)0, OS_STAT_Q, OS_STAT_PEND_ABORT);
                 nbr_tasks++;
                 break;
        }
        OS_EXIT_CRITICAL();
        OS_Sched();                                        /* Find HPT ready to run                    */
        *perr = OS_ERR_PEND_ABORT;
        return (nbr_tasks);
    }
    OS_EXIT_CRITICAL();
    *perr = OS_ERR_NONE;
    return (0);                                            /* No tasks waiting on queue                */
}

出0入0汤圆

发表于 2009-9-22 16:03:47 | 显示全部楼层
具体情况需要具体分析,每个版本的代码不一样,你这种问内核的事情需要内核版本

出0入0汤圆

 楼主| 发表于 2009-9-22 17:17:47 | 显示全部楼层
谢谢 回复
我是初学者  看得是卲贝贝的书
你给的答案我不是很懂,这个函数我没有见过
我只看了书里面介绍的函数  呵呵  
是不是有这样的可能性  就是其他任务发送消息的时候  发送过程还没有全部完成即退出临界状态,而后又被中断,而这个挂起的任务重新取得了CPU的控制权。所以如此。
谢谢您的回复。

出0入0汤圆

发表于 2009-9-26 14:58:16 | 显示全部楼层
任务发送消息的时候是有临界保护的,这是系统内核保证的,如果你不放心,可以仔细的阅读代码
我给出的答案是在别的任务中将执行请求取消函数
这样当前的请求任务就可以就绪,结果就是既没有超时也没有请求到消息。
我的这个版本应该是2.83以上的

出0入0汤圆

发表于 2009-10-11 12:46:22 | 显示全部楼层
mark,后面看到这部分的时候注意一下,呵呵

出0入0汤圆

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

本版积分规则

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

GMT+8, 2024-5-20 17:43

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

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