本篇介绍以下几个函数:

OSVersion()获得版本号函数、

OS_Dummy()虚拟函数、

OS_EventTaskRdy (OS_EVENT *pevent, void *msg, INT8U msk)使任务进入就绪态的函数、

OS_EventTaskWait (OS_EVENT *pevent)使任务进入等待状态的函数、

OS_EventTaskWaitMulti(OS_EVENT **pevents_wait)使任务进入等待状态的函数(多任务下)、

OSVersion()获得版本号函数:

/*$PAGE*/
/*
*********************************************************************************************************
*                                             GET VERSION
*                                               获得版本号
* Description: This function is used to return the version number of uC/OS-II.  The returned value
*              corresponds to uC/OS-II's version number multiplied by 100.  In other words, version 2.00
*              would be returned as 200.
*这个函数是返回一个uC/OS-II的版本值. 这个返回值乘100是uC/OS-II的版本号.
* Arguments  : none
*
* Returns    : the version number of uC/OS-II multiplied by 100.
*********************************************************************************************************
*/
INT16U  OSVersion(void)
{return (OS_VERSION);
}

OS_Dummy()虚拟函数:

/*$PAGE*/
/*
*********************************************************************************************************
*                                            DUMMY FUNCTION
*                                               虚拟函数
* Description: This function doesn't do anything.  It is called by OSTaskDel().
*这个函数不做任务工作. 它是随便访问OSTaskDel()函数.
* Arguments  : none
*
* Returns    : none
*********************************************************************************************************
*/#if OS_TASK_DEL_EN > 0u
void  OS_Dummy(void)
{
}
#endif

OS_EventTaskRdy (OS_EVENT *pevent, void *msg, INT8U msk)使任务进入就绪态的 函数:

/*$PAGE*/
/*
*********************************************************************************************************
*                             MAKE TASK READY TO RUN BASED ON EVENT OCCURING
*                               使一个任务进入就绪态
* Description: This function is called by other uC/OS-II services and is used to ready a task that was
*              waiting for an event to occur.
*描述:该功能被其他oc/os-ii服务调用,用来使正在等待事件发生的任务进入就绪态。
* Arguments  : pevent      is a pointer to the event control block corresponding to the event.
*   参数:              --pevent指针指向与事件对应的事件控制块
*              pmsg        is a pointer to a message.  This pointer is used by message oriented services
*                          such as MAILBOXEs and QUEUEs.  The pointer is not used when called by other
*                          service functions.
*                       --pmsg指针指向消息,只能面向消息的服务才能使用,例如邮箱和队列。其他的不能调用该函数。
*              msk         is a mask that is used to clear the status byte of the TCB.  For example,
*                          OSSemPost() will pass OS_STAT_SEM, OSMboxPost() will pass OS_STAT_MBOX etc.
*                       --msk函数是一个掩码,用来清除TCB的状态字。例如,通过OSSemPost()函数清除OS_STAT_SEM;利用OSMboxPost()函数清除OS_STAT_MBOX。
*              pend_stat   is used to indicate the readied task's pending status:
*                       --pend_stat用来表明已准备好的任务的挂起状态。挂起状态有以下两种:
*                          OS_STAT_PEND_OK      Task ready due to a post (or delete), not a timeout or
*                                               an abort.--挂起结束(正常结束):任务已经准备好进入就绪态。
*                          OS_STAT_PEND_ABORT   Task ready due to an abort.--取消挂起:任务被取消。
*
* Returns    : none
*
* Note       : This function is INTERNAL to uC/OS-II and your application should not call it.
这个函数是uC/OS-II内部函数,你不可以在应用程序调用它,调用此函数也应当关闭中断
*********************************************************************************************************
*/
#if (OS_EVENT_EN)
INT8U  OS_EventTaskRdy(OS_EVENT  *pevent,void      *pmsg,INT8U      msk,INT8U      pend_stat)
{OS_TCB   *ptcb;                                /*指向TCB列表的指针*/INT8U     y;                              /*存放字节索引*/INT8U     x;                              /*存放任务在表中对应的具体位置*/INT8U     prio;                               /*存放优先级(数字越小,优先级越高)*/
#if OS_LOWEST_PRIO > 63u                 /*如果最低优先级大于63u(超出了范围)*/OS_PRIO  *ptbl;                            /*设置一个专门存放超出范围的优先级指针ptb1*/
#endif#if OS_LOWEST_PRIO <= 63u                     /*如果最低优先级<=63*/y = OSUnMapTbl[pevent->OSEventGrp];         /* Find HPT waiting for message首先计算HPT任务在.OSEventTbl[]中的字节索引,其结果是一个从0到OS_LOWEST_PRIO/8+1之间的数                */x = OSUnMapTbl[pevent->OSEventTbl[y]];     /*判断HPT任务在.OSEventTbl[]中相应位的位置*/prio = (INT8U)((y << 3u) + x);              /* Find priority of task getting the msg 根据以上结果计算出HPT任务的优先级*/
#else                                           /*最低优先级>63*/if ((pevent->OSEventGrp & 0xFFu) != 0u)      /*存在事件控制块所在的组*/{   y = OSUnMapTbl[pevent->OSEventGrp & 0xFFu];      /*找到事件所在的组*/}else {y = OSUnMapTbl[(OS_PRIO)(pevent->OSEventGrp >> 8u) & 0xFFu] + 8u;/*没有组,将y置为8(不在组内)*/}ptbl = &pevent->OSEventTbl[y];              /*ptb1指针指向上面求出的组的首地址*/if ((*ptbl & 0xFFu) != 0u)                   /*如果该指针指向的这一行不为0,即存在有效值*/{   x = OSUnMapTbl[*ptbl & 0xFFu];         /*得到该任务在表中相应的位置*/}else {                        x = OSUnMapTbl[(OS_PRIO)(*ptbl >> 8u) & 0xFFu] + 8u;/*为0,将x设为8(不在组内)*/}prio = (INT8U)((y << 4u) + x);            /* Find priority of task getting the msg找到得到消息的任务的优先级*//*因为超过了63,所以此时y占了4位,所以左移4u。上面左移3u是因为y在63内,只占了3位*/
#endifptcb = OSTCBPrioTbl[prio];        /* Point to this task's OS_TCB指针指向任务的TCB*/ptcb->OSTCBDly = 0u;              /* Prevent OSTimeTick() from readying task将OSTCBDly清为0*//*因为最高优先级任务运行条件已经得到满足,必须停止OSTimeTick()函数对.OSTCBDly域的递减操作*/
#if ((OS_Q_EN > 0u) && (OS_MAX_QS > 0u)) || (OS_MBOX_EN > 0u)/*如果生成队列且队列数>0或者生成了邮箱*/ptcb->OSTCBMsg = pmsg;                      /* Send message directly to waiting task直接给等待的任务发送消息*/
#elsepmsg = pmsg;                      /*pmsg不进行变化*//* Prevent compiler warning if not used防止编译警告*/
#endifptcb->OSTCBStat &= (INT8U)~msk;                /* Clear bit associated with event type清除与事件类型相关的位*/ptcb->OSTCBStatPend = pend_stat;                 /* Set pend status of post or abort设置挂起状态*//* 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) /*的确存在多任务*/{   OS_EventTaskRemoveMulti(ptcb, ptcb->OSTCBEventMultiPtr);/* Remove this task from events' wait lists将该任务从事件的等待列表中移除*/ptcb->OSTCBEventPtr = (OS_EVENT  *)pevent;/* Return event as first multi-pend event read返回读到的第一个多挂起事件*/}
#endifreturn (prio);//返回优先级
}
#endif

流程图为:

关于这个函数中的计算优先级的方法:http://blog.sina.com.cn/s/blog_4a3946360102wlwx.html

每个任务的就绪态标志都放入就绪表中,就绪表中有两个变量OSRdyGrp和OSRdyTbl[]。
OSRdyGrp是一个8位的变量,用来记录哪几列有就绪任务bit0~bit7。
OSRdyTbl[列号]用来记录某行中那几个位被置位。
假设有个prio为20的任务,那么填入这两个变量的值应当这么操作:先算出OSRdyGrp中的位置20 / 8 = 2即BIT2,再算OSRdyTbl[OSRdyGrp]中的位置20 % 8 = 4即BIT4,那么看下图可知20的位置确实在表[2][4]的位置 OSRdyGrp |= BIT2     OSRdyTbl[2] |= BIT4。

OSRdyGrp和 OSRdyTbl[ OSRdyGrp]都是8个位的变量 ,这8个位可以是一个置为,也可以是多个置位,总计可以有2^8 64种数值,即0~63,那我们要找最高优先级的任务就是要找矩阵中数值最小的那个任务。这张表就是列出了0~63中为1的最小bit号,

假设bit2 bit4 bit6置为,那么这个值应当是2^6+2^4+2^2 = 84;它最小置位位应当是BIT2,这是我们看出来的,那么我把84(54h)代入第二个表查下,的确是2。这样就能确定最高优先级任务的行列号了
我们看下面的代码
y = OSUnMapTbl[OSRdyGrp];//确定行号
OSPrioHighRdy = (INT8U)((y << 3u) + OSUnMapTbl[OSRdyTbl[y]]);//确定列号

计算优先级的方法也显而易见了:就绪列表或事件表中求索引号-》同一个表求相应位的位置-》计算优先级。

这个函数比较费解的,一个是求优先级的方法;一个是查表以及进行的逻辑运算。需要认真研究才可以搞懂。

OS_EventTaskWait (OS_EVENT *pevent)使任务进入等待状态的函数:

当某个任务须等待一个事件的发生时,信号量、互斥型信号量、邮箱以及消息队列会通过相应的PEND函数调用本函数,使当前任务从就绪任务表中脱离就绪态,并放到相应的事件控制块ECB的等待任务表中。

/*$PAGE*/
/*2018/2/7
*********************************************************************************************************
*                                   MAKE TASK WAIT FOR EVENT TO OCCUR
*                                   使一个任务进入等待某事件发生状态
* Description: This function is called by other uC/OS-II services to suspend a task because an event has
*              not occurred.
*描述:这个功能被其他uc/os-ii服务调用,当事件没有发生时挂起该任务
* Arguments  : pevent   is a pointer to the event control block for which the task will be waiting for.
*参数:                 --pevent是指向事件控制块的指针
* Returns    : none
*返回值:无
* Note       : This function is INTERNAL to uC/OS-II and your application should not call it.
注释:该功能为内部功能函数,你的应用程序不能调用
*********************************************************************************************************
*/
#if (OS_EVENT_EN)                               /*如果可以生成事件*/
void  OS_EventTaskWait(OS_EVENT *pevent)        /*使任务进入等待函数*/
{INT8U  y;OSTCBCur->OSTCBEventPtr = pevent;           /*将指向事件控制块的指针赋给当前任务控制块中指向事件的指针,建立任务与事件控制块ECB之间的链接*/pevent->OSEventTbl[OSTCBCur->OSTCBY] |= OSTCBCur->OSTCBBitX;    /* Put task in waiting list将任务放置在等待列表中*/pevent->OSEventGrp |= OSTCBCur->OSTCBBitY;y = OSTCBCur->OSTCBY;            /* Task no longer ready任务不再为就绪态*/OSRdyTbl[y] &= (OS_PRIO)~OSTCBCur->OSTCBBitX;if (OSRdyTbl[y] == 0u)  /*将任务从就绪任务表中删除*/{                     OSRdyGrp &= (OS_PRIO)~OSTCBCur->OSTCBBitY;}
}
#endif

OS_EventTaskWaitMulti(OS_EVENT **pevents_wait)使任务进入等待状态的函数(多任务下):

/*$PAGE*/
/*2018/2/7
*********************************************************************************************************
*                          MAKE TASK WAIT FOR ANY OF MULTIPLE EVENTS TO OCCUR
*                               多事件情况下的任务等待函数
* Description: This function is called by other uC/OS-II services to suspend a task because any one of
*              multiple events has not occurred.
*描述:该功能被uc/os-ii服务调用,当多事件中的任何一个发生时,挂起任务
* Arguments  : pevents_wait     is a pointer to an array of event control blocks, NULL-terminated, for
*                               which the task will be waiting for.
*参数:                         --pevents_wait指向事件控制块数组的指针(指针的指针)。以null结尾。
* Returns    : none.
*返回值:无
* Note       : This function is INTERNAL to uC/OS-II and your application should not call it.
注释:该功能为uc/os-ii内部功能,你的应用程序不能调用它。
*********************************************************************************************************
*/
#if ((OS_EVENT_EN) && (OS_EVENT_MULTI_EN > 0u))                      /*如果可以产生事件并且多事件数量>0*/
void  OS_EventTaskWaitMulti(OS_EVENT **pevents_wait)                /*调用函数*/
{OS_EVENT **pevents;OS_EVENT  *pevent;INT8U      y;OSTCBCur->OSTCBEventPtr = (OS_EVENT  *)0;                        /*当前TCB的事件指针设置为0*/OSTCBCur->OSTCBEventMultiPtr = (OS_EVENT **)pevents_wait;       /*将事件等待指针赋给当前TCB中的多事件指针*/pevents = pevents_wait;pevent = *pevents;while (pevent != (OS_EVENT *)0) {                               /* Put task in waiting lists将任务放到等待列表中*/pevent->OSEventTbl[OSTCBCur->OSTCBY] |= OSTCBCur->OSTCBBitX;pevent->OSEventGrp |= OSTCBCur->OSTCBBitY;pevents++;pevent = *pevents;}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

OS_EventTaskRemove(OS_TCB   *ptcb,OS_EVENT *pevent)从事件等待列表中移除任务函数:

/*$PAGE*/
/*2018/2/7
*********************************************************************************************************
*                                   REMOVE TASK FROM EVENT WAIT LIST
*                                       从事件等待列表中移除任务函数
* Description: Remove a task from an event's wait list.
*描述:将任务从一个事件的等待列表中移除
* Arguments  : ptcb     is a pointer to the task to remove.
*参数:                 --ptcb是一个指向要移除任务的指针
*              pevent   is a pointer to the event control block.
*                       --pevent是一个指向事件控制块的指针
* Returns    : none
*返回值:无
* Note       : This function is INTERNAL to uC/OS-II and your application should not call it.
注释:该功能为内部函数,你的应用程序不能调用。
*********************************************************************************************************
*/
#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

后面这两个函数在前面的基础上就比较好理解了。不再赘述。

本篇博客重点还是放在两张表的学习上。

OS_CORE.C(9)相关推荐

  1. OS_CORE.C(11)

    OS_SchedNew(void)找到将要运行的最高优先级任务函数 和任务调度函数OS_Sched(void): /* **************************************** ...

  2. OS_CORE.C(10)

    今天看os_core.c文件中的各种初始化函数. OS_EventWaitListInit(OS_EVENT *pevent)初始化事件控制块的等待列表: /*$PAGE*/ /*2018/2/8 * ...

  3. OS_CORE.C(总结)

    在内核的功能模块中,重点函数为: static  void  OS_InitEventList(void);/*初始化事件列表*/ static  void  OS_InitMisc(void);/* ...

  4. OS_CORE.C(1)

    第一个函数(获得信号量.互斥量.邮箱或者队列名字的函数)的流程图和分析图如下所示: /*$PAGE*/ /* ********************************************* ...

  5. OS_CORE.C(8)

    本篇介绍的是OSStart()函数和OSStatInit()函数和OSTimeTick()函数. OSStart()多任务开始函数: /*$PAGE*/ /* ******************** ...

  6. OS_CORE.C(6)

    先介绍一下优先级反转的相关知识: 优先级翻转是当一个高优先级任务通过信号量机制访问共享资源时,该信号量已被一低优先级任务占有,因此造成高优先级任务被许多具有较低优先级任务阻塞,实时性难以得到保证. 例 ...

  7. OS_CORE.C(5)

    /*$PAGE*/ /* *************************************************************************************** ...

  8. OS_CORE.C(3)

    OSTCBCur->OSTCBStat |= events_stat | /* Resource not available, ...无法获得资源的话就将其挂起 */OS_STAT_MULTI; ...

  9. OS_CORE.C(7)

    本篇介绍的是调度器的上锁和解锁: 调度器上锁函数OSSchedlock()的功能是用于禁止任务调度,使任务保持对CPU的控制权. 调度器开锁函数OSSchedUnlock()的功能是解除对任务调度的禁 ...

最新文章

  1. java单循环 比较得分_java – 为什么两个单独的循环比一个快?
  2. 内网渗透测试:内网信息收集与上传下载
  3. 公司网络推广分享新站如何更快的获得首页排名的技巧!
  4. html:(27):类和ID选择器的区别和子选择器
  5. 新松机器人发行价_知识创造财富,“机器人第一股”背后的院士是怎样炼成的?...
  6. C++ 对象关系映射(ORM)介绍
  7. LVM逻辑卷管理@设备、格式、摩、引导自己主动安装一个完整的章节
  8. 力扣-414 第三大的数
  9. Linq中查询List组合相同值数量大于1
  10. google erath api v3 与v2版本在定位方面的区别
  11. 信奥中的数学:微积分 高等数学 数学分析
  12. 汽车UDS诊断详解及Vector相关工具链使用说明——总述
  13. UE4 人物运动基本设置
  14. 鸿蒙系统分布式操作,如何通俗解释鸿蒙系统分布式操作
  15. 在线旅游OTA行业调研报告-携程美团同程飞猪booking对比分析
  16. matlab贝塔分布,怎么拟合贝塔分布函数
  17. 004-CentOS换清华源
  18. 可穿戴设备,朝“超人”迈进
  19. 抖音电商的带货情况究竟如何,抖音电商带货前景如何
  20. 峰会 | 2019长三角科技金融峰会召开 区块链应用前景持续探索

热门文章

  1. 第一篇:Django基础
  2. DBI(i80)/DPI(RGB)/DSI【转】
  3. asp实现批量录入数据
  4. adb logcat通过包名过滤(dos命令find后跟变量)
  5. MTP 多媒体传输协议
  6. 听说你还没学Spring就被源码编译劝退了?30+张图带你玩转Spring编译
  7. 重构:改善饿了么交易系统的设计思路
  8. 排除万难,我终于入了程序员的坑!
  9. 解读:大数据在电信行业的五大应用
  10. 微服务实践(五):微服务的事件驱动数据管理