//事件等待表的初始化函数;pevent表示事件控制块的指针
#if (OS_EVENT_EN)
void  OS_EventWaitListInit (OS_EVENT *pevent)
{
    INT8U  i;
    pevent->OSEventGrp = 0u;                     /* No task waiting on event                           */
    for (i = 0u; i < OS_EVENT_TBL_SIZE; i++) {
        pevent->OSEventTbl[i] = 0u;
    }
}

    //事件等待表的初始化函数;pevent表示事件控制块的指针
    #if (OS_EVENT_EN)
    void  OS_EventWaitListInit (OS_EVENT *pevent)
    {
        INT8U  i;
        pevent->OSEventGrp = 0u;                     /* No task waiting on event                           */
        for (i = 0u; i < OS_EVENT_TBL_SIZE; i++) {
        pevent->OSEventTbl[i] = 0u;
        }
    }
    #endif

    //事件控制块的初始化
    static  void  OS_InitEventList (void)
    {
        //OS_EVENT_EN判断是否使用事件管理--事件是否大于0
    #if (OS_EVENT_EN) && (OS_MAX_EVENTS > 0u)
    #if (OS_MAX_EVENTS > 1u)//OS_MAX_EVENTS=10
        INT16U     ix;
        INT16U     ix_next;
        //指向事假控制块的指针变量
        OS_EVENT  *pevent1;
        OS_EVENT  *pevent2;
        
        //清空事件表---但是可能其他事件给清0了
        OS_MemClr((INT8U *)&OSEventTbl[0], sizeof(OSEventTbl)); /* Clear the event table                   */
        //初始事件控制块OS_MAX_EVENTS=10--
        for (ix = 0u; ix < (OS_MAX_EVENTS - 1u); ix++) {        /* Init. list of free EVENT control blocks */
        ix_next = ix + 1u;
        pevent1 = &OSEventTbl[ix];
        pevent2 = &OSEventTbl[ix_next];
        pevent1->OSEventType    = OS_EVENT_TYPE_UNUSED;
        pevent1->OSEventPtr     = pevent2;
    #if OS_EVENT_NAME_EN > 0u
                //给事件区名称
        pevent1->OSEventName    = (INT8U *)(void *)"?";     /* Unknown name                            */
    #endif
        }
        //OS_EVENT_TYPE_UNUSED=0--ix=9-表尾部
        pevent1                         = &OSEventTbl[ix];
        pevent1->OSEventType            = OS_EVENT_TYPE_UNUSED;
        pevent1->OSEventPtr             = (OS_EVENT *)0;
    #if OS_EVENT_NAME_EN > 0u
        pevent1->OSEventName            = (INT8U *)(void *)"?"; /* Unknown name                            */
    #endif
        //OSEventFreeList指向控制块的头部--基本就是初始化成功
        OSEventFreeList                 = &OSEventTbl[0];
    #else
        OSEventFreeList                 = &OSEventTbl[0];       /* Only have ONE event control block       */
        OSEventFreeList->OSEventType    = OS_EVENT_TYPE_UNUSED;
        OSEventFreeList->OSEventPtr     = (OS_EVENT *)0;
    #if OS_EVENT_NAME_EN > 0u
        OSEventFreeList->OSEventName    = (INT8U *)"?";         /* Unknown name                            */
    #endif
    #endif
    #endif
    }

    //移除任务控制块
    #if ((OS_EVENT_EN) && (OS_EVENT_MULTI_EN > 0u))
    void  OS_EventTaskRemoveMulti (OS_TCB    *ptcb,
                       OS_EVENT **pevents_multi)
    {
        OS_EVENT **pevents;
        OS_EVENT  *pevent;
        INT8U      y;
        OS_PRIO    bity;
        OS_PRIO    bitx;

        y       =  ptcb->OSTCBY;
        bity    =  ptcb->OSTCBBitY;
        bitx    =  ptcb->OSTCBBitX;
        pevents =  pevents_multi;
        pevent  = *pevents;
        while (pevent != (OS_EVENT *)0) {                   /* Remove task from all events' wait lists     */
        pevent->OSEventTbl[y]  &= (OS_PRIO)~bitx;
        if (pevent->OSEventTbl[y] == 0u) {
            pevent->OSEventGrp &= (OS_PRIO)~bity;
        }
        pevents++;
        pevent = *pevents;
        }
    }

    //取消事件的等待;
    #if (OS_EVENT_EN)
    void  OS_EventTaskRemove (OS_TCB   *ptcb,
                  OS_EVENT *pevent)
    {
        INT8U  y;
        
        //在事件等待表删除事件等待标志
        y                       =  ptcb->OSTCBY;
        pevent->OSEventTbl[y]  &= (OS_PRIO)~ptcb->OSTCBBitX;    /* Remove task from wait list              */
        //若该行已没有任务等待
        if (pevent->OSEventTbl[y] == 0u) {
            //删除事件等待组的事件等待标志;
        pevent->OSEventGrp &= (OS_PRIO)~ptcb->OSTCBBitY;
        }
    }
    #endif

    #if (OS_EVENT_EN)
    //事件等待函数
    void  OS_EventTaskWait (OS_EVENT *pevent)
    {
        INT8U  y;
        //在tcb的OSTCBEventPtr域存储ecb指针-以后通过该任务的tcb可直接找到正事件的ecb
        OSTCBCur->OSTCBEventPtr               = pevent;                 /* Store ptr to ECB in TCB         */
        //在事件等待组和事件等待表中进行标识
        pevent->OSEventTbl[OSTCBCur->OSTCBY] |= OSTCBCur->OSTCBBitX;    /* Put task in waiting list        */
        pevent->OSEventGrp                   |= OSTCBCur->OSTCBBitY;
        //OSTCBY指把任务优先级右移三位;任务优先级低三位OSTCBBitX具体在哪个位置
        //以上将该任务在ecb中登记完毕,下面将阻塞这个任务-等待任务事件的发生
        y             =  OSTCBCur->OSTCBY;            /* Task no longer ready                              */
        //把就绪表中给删除掉 取反 在与操作-给对应位给清掉;
        OSRdyTbl[y]  &= (OS_PRIO)~OSTCBCur->OSTCBBitX;
        if (OSRdyTbl[y] == 0u) {                      /* Clear event grp bit if this was only task pending */
        //得给就绪表里是否没有事件发生了;
            OSRdyGrp &= (OS_PRIO)~OSTCBCur->OSTCBBitY;
        }
    }
    #endif

    //等待事件的任务就绪函数
    #if (OS_EVENT_EN)
    INT8U  OS_EventTaskRdy (OS_EVENT  *pevent,//对应ecb指针
                void      *pmsg,//信息指针
                INT8U      msk,//信息状态位的掩码--清除tcb状态位
                INT8U      pend_stat)//等待事件的原因/OS_STAT_PEND_OK/OS_STAT_PEND_ABORT
    {
        OS_TCB   *ptcb;
        INT8U     y;
        INT8U     x;
        INT8U     prio;
        //判断优先级
    #if OS_LOWEST_PRIO > 63u
        OS_PRIO  *ptbl;
    #endif

    #if OS_LOWEST_PRIO <= 63u
        //在事件等待等待表和事件组找到优先级最高的任务;
        y    = OSUnMapTbl[pevent->OSEventGrp];              /* Find HPT waiting for message                */
        x    = OSUnMapTbl[pevent->OSEventTbl[y]];
        prio = (INT8U)((y << 3u) + x);                      /* Find priority of task getting the msg       */
    #else
        if ((pevent->OSEventGrp & 0xFFu) != 0u) {           /* Find HPT waiting for message                */
        y = OSUnMapTbl[ pevent->OSEventGrp & 0xFFu];
        } else {
        y = OSUnMapTbl[(OS_PRIO)(pevent->OSEventGrp >> 8u) & 0xFFu] + 8u;
        }
        //查找优先级指标表找到对应的TCB指针;
        ptbl = &pevent->OSEventTbl[y];
        if ((*ptbl & 0xFFu) != 0u) {  //若不为0 调度器每个时钟滴答对该值-1 减到0后 将任务就绪;
        x = OSUnMapTbl[*ptbl & 0xFFu];
        } else {
            //本函数发生冲突--强制为0
        x = OSUnMapTbl[(OS_PRIO)(*ptbl >> 8u) & 0xFFu] + 8u;
        }
        prio = (INT8U)((y << 4u) + x);                      /* Find priority of task getting the msg       */
    #endif
        //任务控制块ptcb
        ptcb                  =  OSTCBPrioTbl[prio];        /* Point to this task's OS_TCB                 */
        ptcb->OSTCBDly        =  0u;                        /* Prevent OSTimeTick() from readying task     */
    #if ((OS_Q_EN > 0u) && (OS_MAX_QS > 0u)) || (OS_MBOX_EN > 0u)
       //给TCB中信息指针赋值
        ptcb->OSTCBMsg        =  pmsg;                      /* Send message directly to waiting task       */
    #else
        //防止编译器发送警告
        pmsg                  =  pmsg;                      /* Prevent compiler warning if not used        */
    #endif
        //清除任务状态中对应等待标志,--任务已经不再等待给事件了
        ptcb->OSTCBStat      &= (INT8U)~msk;                /* Clear bit associated with event type        */
        //s设置等待状态
        ptcb->OSTCBStatPend   =  pend_stat;                 /* Set pend status of post or abort            */
         //判断任务数是否被挂起 为0 不是挂起 -就让他就绪;挂起的任务不能因为事件的发生而就绪;                                                   /* See if task is ready (could be susp'd)      */
        if ((ptcb->OSTCBStat &   OS_STAT_SUSPEND) == OS_STAT_RDY) {
        OSRdyGrp         |=  ptcb->OSTCBBitY;           /* Put task in the ready to run list           */
        OSRdyTbl[y]      |=  ptcb->OSTCBBitX;
        }
        //在事件等待表删除该任务;
        OS_EventTaskRemove(ptcb, pevent);                   /* Remove this task from event   wait list     */
    #if (OS_EVENT_MULTI_EN > 0u)
        if (ptcb->OSTCBEventMultiPtr != (OS_EVENT **)0) {   /* Remove this task from events' wait lists    */
        OS_EventTaskRemoveMulti(ptcb, ptcb->OSTCBEventMultiPtr);
        ptcb->OSTCBEventPtr       = (OS_EVENT  *)pevent;/* Return event as first multi-pend event ready*/
        }
    #endif

        return (prio);
    }
    #endif

    //时钟中断
    void  OSTimeTick (void)
    {
        OS_TCB    *ptcb;
        BOOLEAN    step;
        OSTimeTickHook();                                      /*调用用户钩子函数,默认是空函数                     */

    #if OS_TIME_GET_SET_EN > 0u
        OS_ENTER_CRITICAL();                                   /* Update the 32-bit tick counter               */
        OSTime++; //调度计数+1
        OS_EXIT_CRITICAL();
    #endif
        //成立表示已经启动多任务
        if (OSRunning == OS_TRUE) {
    #if OS_TICK_STEP_EN > 0u
        switch (OSTickStepState) {                         /* Determine whether we need to process a tick  */
            case OS_TICK_STEP_DIS:                         /* Yes, stepping is disabled                    */
             step = OS_TRUE;
             break;

            case OS_TICK_STEP_WAIT:                        /* No,  waiting for uC/OS-View to set ...       */
             step = OS_FALSE;                          /*      .. OSTickStepState to OS_TICK_STEP_ONCE */
             break;

            case OS_TICK_STEP_ONCE:                        /* Yes, process tick once and wait for next ... */
             step            = OS_TRUE;                /*      ... step command from uC/OS-View        */
             OSTickStepState = OS_TICK_STEP_WAIT;
             break;

            default:                                       /* Invalid case, correct situation              */
             step            = OS_TRUE;
             OSTickStepState = OS_TICK_STEP_DIS;
             break;
        }
        if (step == OS_FALSE) {                            /* Return if waiting for step command           */
            return;
        }
    #endif
             /* Point at first TCB in TCB list */
        ptcb = OSTCBList;                                  /* Point at first TCB in TCB list               */
        while (ptcb->OSTCBPrio != OS_TASK_IDLE_PRIO) {     /* Go through all TCBs in TCB list              */
            OS_ENTER_CRITICAL();
            if (ptcb->OSTCBDly != 0u) {                    /* No, Delayed or waiting for event with TO     */
            ptcb->OSTCBDly--;                          /* Decrement nbr of ticks to end of delay       */
                    //Check for timeout
                    if (ptcb->OSTCBDly == 0u) {                /* Check for timeout                            */
                        //若有任务等待一事件的发生
                if ((ptcb->OSTCBStat & OS_STAT_PEND_ANY) != OS_STAT_RDY) {
                            // Clear status flag  
                            ptcb->OSTCBStat  &= (INT8U)~(INT8U)OS_STAT_PEND_ANY;          /* Yes, Clear status flag   */
                ptcb->OSTCBStatPend = OS_STAT_PEND_TO;                 /* Indicate PEND timeout    */
                } else {
                ptcb->OSTCBStatPend = OS_STAT_PEND_OK;
                }
                        //如果任务不是被挂起的
                if ((ptcb->OSTCBStat & OS_STAT_SUSPEND) == OS_STAT_RDY) {  /* Is task suspended?       */
                OSRdyGrp               |= ptcb->OSTCBBitY;             /* No,  Make ready          */
                OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX;
                }
            }
            }
                // Point at next TCB in TCB list
            ptcb = ptcb->OSTCBNext;                        /* Point at next TCB in TCB list                */
            OS_EXIT_CRITICAL();
        }
        }
    }

嵌入式实时操作系统μCOS原理与实践+事件部分代码的更多相关文章

  1. 嵌入式实时操作系统μCOS原理与实践任务控制与时间的解析

    /*************************************************************************************************** ...

  2. 嵌入式实时操作系统VxWorks入门――开发环境构建[转]

    VxWorks 操作系统是美国WindRiver公司于1983年设计开发的一种嵌入式实时操作系统(RTOS),它以其良好的可靠性和卓越的实时性被广泛地应用在通 信.军事.航空.航天等高精尖技术及实时性 ...

  3. 嵌入式实时操作系统Nucleus PLUS综述

    近些年来,随着嵌入式系统飞速的发展.嵌入式实时操作系统广泛地应用在制造工业.过程控制.通讯.仪器仪表.汽车.船舶.航空航天.军事.装备.消费类产 品等方面. Nucleus PLUS 是为实时嵌入式应 ...

  4. VxWorks Fuzzing 之道:VxWorks 工控实时操作系统漏洞挖掘调试与利用揭秘

    转载:freebuf 0×00 前言 关于VxWorks,这里引用44CON议题<攻击 VxWorks:从石器时代到星际>探究 一文章中的介绍: VxWorks 是世界上使用最广泛的一种在 ...

  5. 嵌入式实时程序设计中C/C++代码的优化

    1 引言 计算机技术和信息技术的高速发展的今天,计算机和计算机技术大量应用在人们的日常生活中,嵌入式计算机也得到了广泛的应用.嵌入式计算机是指完成一种或多种特定功能的计算机系统,是软硬件的紧密结合体. ...

  6. vxworks 实时操作系统

    VxWorks 是美国 Wind River System 公司( 以下简称风河公司 ,即 WRS 公司)推出的一个实时操作系统.Tornado 是WRS 公司推出的一套实时操作系统开发环境,类似Mi ...

  7. QNX 实时操作系统(Quick Unix)

    Gordon Bell和Dan Dodge在1980年成立了Quantum Software Systems公司,他们根据大学时代的一些设想写出了一个能在IBM PC上运行的名叫QUNIX(Quick ...

  8. JavaScript学习之事件原理和实践

    1 基本概念 1.1 事件 JavaScript与HTML之间的交互是通过事件实现的. 事件是文档或浏览器窗口中发生的一些特定的交互瞬间,在事件上可以注册处理程序,以便当事件发生时,处理程序中的代码得 ...

  9. 《浏览器工作原理与实践》<04>从输入URL到页面展示,这中间发生了什么?

    “在浏览器里,从输入 URL 到页面展示,这中间发生了什么? ”这是一道经典的面试题,能比较全面地考察应聘者知识的掌握程度,其中涉及到了网络.操作系统.Web 等一系列的知识. 在面试应聘者时也必问这 ...

随机推荐

  1. 阻塞与非阻塞IO step by step

    谈到IO,阻塞.非阻塞,异步.同步是绕不开的话题.说实话,我也没搞清楚,网上查了许多资料,大家众说纷纭,一种比较靠谱的说法是:”在处理 IO 的时候,阻塞和非阻塞都是同步 IO,使用使用了特殊的API ...

  2. Datagrid数据导出到excel文件的三种方法

    原文连接: http://www.cnblogs.com/xieduo/articles/606202.html 一.文件保存在服务器,提供下载 方法一:导出到csv文件,存放在服务器端任一路径,然后 ...

  3. [5]Telerik Extensions for ASP.NET MVC 开发问题

    1.Controller获取不到checkedNodes的问题 HTML @(Html.Telerik().TreeView()        .Name("TreeView")  ...

  4. 我的WCF摸爬滚打之路(2)

    昨天抽空写了一个wcf的创建和宿主程序的创建文章,下面也有很多园友给了评论,在此谢谢大家给了我继续记录我的摸爬滚打之路信心……抱拳! 上次的文章<我的WCF摸爬滚打之路(1)>中写到,在测 ...

  5. K2与OData和Swagger的集成

    最近K2陆续发布了一些好消息,从与Box的集成到今年取得的融资.这儿还有一个:K2近期宣布获得了DData和Swagger REST的支持,保障K2 Appit和Blackpearl的用户能建立基于工 ...

  6. NET Office 组件Spire

    高效而稳定的企业级.NET Office 组件Spire   在项目开发中,尤其是企业的业务系统中,对文档的操作是非常多的,有时几乎给人一种错觉的是"这个系统似乎就是专门操作文档的" ...

  7. U3D Debug.log的问题

    今天在测试有yield有关的问题时,发现Debug.log()是异步输出机制.不一定会在调用后立即执行. 在C++有类似问题:std::cout 也不一定会立即输出,加上"\n"或 ...

  8. php基础23:数值与数值函数

    <?php //1.自动转换 $a = 5; $b = "5a"; $c = $a + $b; echo $c; echo "<br>"; $ ...

  9. ASP.NET中进行消息处理(MSMQ) 一

    MSMQ是微软消息队列的英文缩写.那么什么是消息队列?这些介绍网上一大片这里就不多说了.本文对于大虾级的人物来说这只是小玩意而已,对于初学者来说这文章还是有一定的帮助,希望路过的大虾们别笑话我班门弄斧 ...

  10. matlab矩阵合并及相关运算

    1.matlab允许向量(和矩阵)合并,且matlab提供了两种合并方式,[a,b]和[a;b],两者的结果是不一样的. a=rand(2,3): b=rand(2,3): c=[a;b]: d=[a ...