(十)Z-Stack1.4.3-1.2.1中事件触发的方式

来源:互联网 发布:詹姆斯07总决赛数据 编辑:程序博客网 时间:2024/05/01 03:19
  在整个协议栈中,我们通过例子程序可以看到,触发任务的事件主要有以下两种方式,
(1)  通过设置一个“软件定时器”,当其溢出时触发事件 osal_start_timeEx()àosalTimerUpdate()àosal_set_evetn()
(2)通过调用系统消息传递机制触发事件 osal_msg_send()àosal_set_event()
(3) 当然还有可以直接调用osal_set_event(),协议栈中也有很多是利用这种方式。
   不过在例子例程和整个协议栈中很少看到,不过上面的两个函数最终都是调用了osal_set_event()函数触发的事件。下面我们首先来看一个soal_set_event()函数。该函数把事件event_flag(这个事件是一个标志位)传递给了task_id所指示的一个任务。表明该任务所需要的事件发生了。
/*********************************************************************
 * @fn      osal_set_event
 *
 * @brief
 *
 *    This function is called to set the event flags for a task.  The
 *    event passed in is OR'd into the task's event variable.
 *
 * @param   byte task_id - receiving tasks ID
 * @param   byte event_flag - what event to set
 *
 * @return  ZSUCCESS, INVALID_TASK
 */
byte osal_set_event( byte task_id, UINT16 event_flag )
{
  if ( task_id < tasksCnt )
  {
  halIntState_t   intState;
    HAL_ENTER_CRITICAL_SECTION(intState);    // Hold off interrupts 关闭中断
    tasksEvents[task_id] |= event_flag;  // Stuff the event bit(s) 填充事件位
    HAL_EXIT_CRITICAL_SECTION(intState);     // Release interrupts 打开中断
  }
   else
    return ( INVALID_TASK );
 
  return ( ZSUCCESS );
}
   通过tasksEvents[task_id] |= event_flag;可以让系统的主循环函数轮询所发生的任务事件,再调用相应任务的事件处理函数进行处理。
   在协议栈里面,调用osal_set_event()的函数最主要是两个:
(1)osalTimerUpdate() 这个函数是在应用中经常使用的一种方式 也就是osal_start_timerEx()中调用的。
(2)osal_msg_send()
   对于1,当有osal_start_timerEx()在系统软件定时器链表中添加一个软件定时器并启动时,系统通过osalTimerUpdate()对链表中的每一个软件定时器进行减1ms操作,当定时器溢出时,调用osal_set_event()触发事件,如下
/************************
static void osalTimerUpdate( uint16 updateTime )
{
 …………
      // When timeout, execute the task
      if ( srchTimer->timeout == 0 )
      {
        osal_set_event( srchTimer->task_id, srchTimer->event_flag );
 …………
}
/************************
   对于2,对msg_ptr一系列处理后,调用osal_set_event()触发事件,该函数把消息msg_ptr(这个消息是一个数据包)传递给了task_id所指示的一个任务。表明把数据包传递给该任务,这个数据包里一般情况下也携带了事件标志event_flag。如下
/************************
byte osal_msg_send( byte destination_task, byte *msg_ptr )
{
 …………
  osal_set_event( destination_task, SYS_EVENT_MSG );
  return ( ZSUCCESS );
}
/***********************
       这两种方式都是在最终调用了osal_set_event()函数。我们要知道所有的任务的事件处理函数,都是通过taskArr[idx](idx,events)调用的。主要是设置事件的标志位来触发事件。然后就是在主循环中不停的检测事件的标志位,如果有事件发生了就会调用相应任务的事件处理函数处理。
   在下面的文章中我们就分析两个事件的整个的OSAL系统中是怎么被触发的。一个是Key按键的触发,另一个是Timer4的触发,也就是应用程序在调用osal_start_timterEx()函数是触发的事件。

  
0 0