当前位置:首页>> uCOS II 之事件控制块学习

uCOS II 之事件控制块学习

发布时间:2012-11-26作者:智汇小新

  一。 事件控制块ECB数据结构:

  typedef struct

  {

  INT8U OSEventType; //事件类型

  INT8U OSEventGrp; //等待任务所在的组

  INT16U OSEventCnt; //当事件是信号量时的计数器

  void *OSEventPtr; //指向消息或消息队列的指针

  INT8U OSEventTbl[OS_EVENT_TBL_SIZE]; //等待任务列表

  } OS_EVENT;

  二.关键算法:

  1、将一个任务插入到等待事件的任务列表中:

  当调用函数OS_EventTaskWait( )使一个任务进入等待某事件发生时,需要此算法,从而将任务插入到等待事件的任务列表中。

  pevent -》 OSEventGrp |= OSMapTbl[prio 》》 3];

  pevent -》 OSEventTbl[prio》》3] = OSMapTbl[prio & 0x07];

  2、从等待事件的任务列表中使任务脱离等待状态:

  当调用函数OS_EventTaskRdy( )使一个任务进入就绪态时,需要调用此算法,从而使等待的任务脱离等待状态进入就绪。

  if ((pevent -》 OSEventTbl[prio 》》3] &= ~OSMapTbl[prio & 0x07]) == 0)

  {

  pevent -》 OSEventGrp &= ~OSMapTbl[prio 》》3];

  }

  3、在等待事件的任务列表中查找优先级最高的任务:

  当调用函数OS_EventTaskRdy( )使一个任务进入就绪态时,需要调用此算法,从而首先找出在等待事件任务列表中最高优先级的任务进入就绪状态。

  y = OSUnMapTbl[pevent -》 OSEventGrp];

  x = OSUnMapTbl[pevent -》 OSEventTbl[y];

  prio = (y 《《 3) + x;

  三.对事件控制块ECB的基本操作

  1、初始化一个事件控制块:

  函数OSSemCreate( ),OSMutexCreate( ),OSMboxCreate( ),OSQCreate( )建立时,必须调用此函数进行初始化,初始化一个空的等待列表,表中没有任何等待事件的任务。

  OS_EventWaitListInit( );

  2、使一个任务进入就绪态:

  当某个事件发生了时,要将事件等待任务列表中最高优先级的任务进入就绪态,函数OSSemPost,OSMutexPost( ),OSMboxPost( ),OSQPost( )必将调用此函数从而使一个任务进入就绪态。

  OS_EventTaskRdy( );

  3、使一个任务进入等待某事件发生:

  当某个任务须等待一个事件的发生时,信号量、互斥型信号量、邮箱、消息队列会通过相应的PEND函数来调用这个函数。

  OS_EventTaskWait( );

  4、由于等待超时而将任务置为就绪态:

  如果在预先指定的等待时间内任务等待的事件没有发生,那么PNED类型函数将会调用此函数从而将等待超时的任务进入就绪态。

  OS_EventTo( );

  四.事件控制块ECB基本操作代码的分析。

  1、OS_EventWaitListInit( );

  void OS_EventWaitListInit(OS_EVENT *pevent)

  {

  INT8U *ptbl; //定义指针变量ptbl

  pevent -》 OSEventGrp = 0x00; //清除任务所在的组

  OS_EVENT_TBL_SIZE在UCOS_ II.H中定义大小

  ptbl = &pevent -》 OSEventTbl[0];

  #if OS_EVENT_TBL_SIZE 》 0

  *ptbl++ = 0x00; //清除等待任务列表,在这里没有使用for循环是为了节省系统开销

  #endif

  #if OS_EVENT_TBL_SIZE 》 1

  *ptbl++ = 0x00;

  #endif

  #if OS_EVENT_TBL_SIZE 》 2

  *ptbl++ = 0x00;

  #endif

  #if OS_EVENT_TBL_SIZE 》 3

  *ptbl++ = 0x00;

  #endif

  #if OS_EVENT_TBL_SIZE 》 4

  *ptbl++ = 0x00;

  #endif

  #if OS_EVENT_TBL_SIZE 》 5

  *ptbl++ = 0x00;

  #endif

  #if OS_EVENT_TBL_SIZE 》 6

  *ptbl++ = 0x00;

  #endif

  #if OS_EVENT_TBL_SIZE 》 7

  *ptbl++ = 0x00;

  #endif

  }

  2、OS_EventTaskRdy( );

  INT8U OS_EventTaskRdy(OS_EVENT *pevent, void *msg,INT8U msk)

  {

  OS_TCB *ptcb;

  INT8U x;

  INT8U y;

  按照关键算法3,在等待事件的任务列表中找到优先级最高的任务,并确定其优先级。

 

  INT8U bitx;

  INT8U bity;

  INT8U prio;

  y = OSUnMapTbl[pevent -》 OSEventGrp];

  bity = OSMapTbl[y];

  x = OSUnMapTbl[pevent -》 OSEventTbl[y]];

  利用算法2,从等待任务列表中删除此优先级最高的任务。

  bitx = OSMapTbl[x];

  prio = (INT8U)(( y 《《 3) + x);

  if ((pevent -》 OSEventTbl[y] &= ~bitx) == 0x00)

  { pevent -》 OSEventGrp &= ~bity;}

  ptcb = OSTCBPrioTbl[prio]; //知道了任务优先级,从而找到任务控制块的指针

  ptcb -》 OSTCBDly = 0; //由于此任务已经不再等待事件的发生,因此直接清0

  ptcb -》 OSTCBEventPtr = (OS_EVENT *)0;//由于不再等待事件的发生,使指向事件控制块的指针指向NULL

  #if ((OS_Q_EN 》 0) && (OS_MAX_QS 》 0)) || (OS_MBOX_EN 》 0)

  ptcb -》 OSTCBMsg = msg;//如果此函数是邮箱或队列POST函数调用的,则需要将传递来的参数放到它的任务控制块中

  #else

  msg = msg;

  #endif

  ptcb -》 OSTCBStat &= ~msk;

  if (ptcb -》 OSTCBStat == OS_STAT_RDY)]

  {

  OSRdyGrp |= bity; ---最高优先级的任务插入到就绪任务列表,由后续POST函数中的

  OSRdyTbl[y] |= bitx; ---OSSched( )函数进行调度使任务进入就绪,请参考第三章之就绪表

  }

  return (prio);

  }

  3、OS_EventTaskWait( );

  void OS_EventTaskWait(OS_EVENT *pevent)

  {

  OSTCBCur -》 OSTCBEventPtr = pevent;

  if (( OSRdyTbl[OSTCBCur -》 OSTCBY] &= ~OSTCBCur-》OSTCBBitx) == 0x00)

  { OSRdyGrp &= ~OSTCBCur -》 OSTCBBity; } //如果在PEND函数中没有收到有效的信号量,

  //那么将调用此函数进入睡眠态,在这里将任务在任务就绪列表中删除

  pevent -》 OSEventTbl[OSTCBCur -》 OSTCBY] |= OSTCBCur -》 OSTCBBitx;

  pevent -》 OSEventGrp |= OSTCBCur -》 OSTCBBity;//把此任务放到ECB的等待事件的任务列表中去

  }

  4、OS_EventTo( );

  void OS_EventTO (OS_EVENT *pevent)

  {

  if (( pevent -》 OSEventTbl[OSTCBCur -》 OSTCBY] &= ~OSTCBCur -》 OSTCBBitx) ==0x00)

  { pevent -》 OSEventGrp &= ~OSTCBCur -》 OSTCBBitY; }//将超时的任务在等待任务列表中删除

  OSTCBCur -》 OSTCBStat = OS_STAT_RDY; //任务置为就绪态

  OSTCBCur -》 OSTCBEventPtr = (OS_EVENT *)0;

  }

公司简介

宜科(天津)电子有限公司是中国工业自动化的领军企业,于2003年在天津投资成立,销售和服务网络覆盖全国。作为中国本土工业自动化产品的提供商和智能制造解决方案的供应商,宜科在汽车、汽车零部件、工程机械、机器人、食品制药、印刷包装、纺织机械、物流设备、电子制造等诸多领域占据领先地位。宜科为智慧工厂的整体规划实施提供自系统层、控制层、网络层到执行层自上而下的全系列服务,产品及解决方案涵盖但不局限于云平台、MES制造执行系统、工业现场总线、工业以太网、工业无线通讯、机器人及智能设备组成的自动化生产线、自动化电气控制系统集成、智能物流仓储系统等,以实现真正智能化的生产制造,从而带来生产力和生产效率的大幅提升,以及对生产灵活性和生产复杂性的管理能力的大幅提升。多年来,宜科以创新的技术、卓越的解决方案和产品坚持不懈地为中国制造业的发展提供全面支持,并以出众的品质和令人信赖的可靠性、领先的技术成就、不懈的创新追求,在业界独树一帜。帮助中国制造业转型升级,加速智能制造进程,成为中国工业4.0智慧工厂解决方案当之无愧的践行者。

更多详情>>

联系我们

  • 联系人:章清涛
  • 热线:18611695135
  • 电话:
  • 传真:
  • 邮箱:18210150532@139.com

Copyright © 2015 ilinki.net Inc. All rights reserved. 智汇工业版权所有

电话:010-62314658 邮箱:service@ilinki.net

主办单位:智汇万联(北京)信息技术有限公司

京ICP备15030148号-1