zigbee协议事件的捕获

程序中事件如何被捕获呢?也就是tasksEvents这个数组里的元素什么时候被设定为非零数,来表示有事件需要处理的?

我将以SampleApp这个例程中按键事件的处理过程来说明。

刚看了一天的zigbee程序,任务的的处理机制还存在疑惑,经过查看前辈们的心得经验自己心中的谜团慢慢解开,下边就说一下自己的理解体会。

首先,按键被按下时会检测出来按键操作,我们需要找到事件处理函数即 Hal_ProcessEvent ,在HAL/Commen/Hal_devicers.c中很容易找到按键检测相关程序:

  if (events & HAL_KEY_EVENT)
  {

#if (defined HAL_KEY) && (HAL_KEY == TRUE)
    /* Check for keys */
    HalKeyPoll();

    /* if interrupt disabled, do next polling */
    if (!Hal_KeyIntEnable)
    {
      osal_start_timerEx( Hal_TaskID, HAL_KEY_EVENT, 100);
    }
#endif // HAL_KEY

    return events ^ HAL_KEY_EVENT;
  }

程序中HalKeyPoll();是对按键状态的查询函数,

    if (!Hal_KeyIntEnable)
    {
      osal_start_timerEx( Hal_TaskID, HAL_KEY_EVENT, 100);
    }
这个程序是对按键状态的检测,如果按键状态没有改变会延迟100毫秒并对Hal_TaskID这个ID所示的任务发送一个HAL_KEY_EVENT事件,这样可以理解为每100毫秒按键任务( 即Hal_ProcessEvent)就被执行一次按键状态的检测,HalKeyPoll这个函数就是检测按键key的实时状态值,在此函数中下列程序不难看出keys的状态值被保存

  if (keys && (pHalKeyProcessFunction))
  {
    (pHalKeyProcessFunction) (keys, HAL_KEY_STATE_NORMAL);
  }

pHalKeyProcessFunction这个函数指针指向那个函数?

接下来我们看一下main函数中 InitBoard( OB_READY ); 这个函数,进入这个函数之后会看到
 HalKeyConfig(HAL_KEY_INTERRUPT_DISABLE, OnBoard_KeyCallback);

然后我们找一下HalKeyConfig的定义,在HAL/Commen/Hal_devicers.c中HalDriverInit初始化函数中找到  HalKeyInit();进入

进入之后我们看到:  pHalKeyProcessFunction  = NULL;在初始化中pHalKeyProcessFunction并没有指向任何一个函数。

在HalKeyInit函数下边的一个函数我们看到是void HalKeyConfig (bool interruptEnable, halKeyCBack_t cback)函数,也就是我们刚要找的函数,在此函数中我们看到

  pHalKeyProcessFunction = cback;

cback是HalKeyConfig传进来的参数,所以想知道pHalKeyProcessFunction所指向的函数必须找到其调用的地方,也就是我们刚刚在main函数中找到的InitBoard函数中 HalKeyConfig(HAL_KEY_INTERRUPT_DISABLE, OnBoard_KeyCallback);

现在我们可以理解到  当发生按键任务事件时,Hal_ProcessEvent函数中HalKeyPoll()函数会获取按键变化的状态值,并把这状态值通过 (pHalKeyProcessFunction) (keys, HAL_KEY_STATE_NORMAL);保存 ,而pHalKeyProcessFunction这个函数指针所指向的函数就是 HalKeyConfig(HAL_KEY_INTERRUPT_DISABLE, OnBoard_KeyCallback);中的OnBoard_KeyCallback函数,所以Hal_ProcessEvent 任务处理函数中按键任务函数HalKeyPoll中(pHalKeyProcessFunction) (keys, HAL_KEY_STATE_NORMAL);按键状态值发生变化后,对应的OnBoard_KeyCallback函数内部程序也会进行一系列的处理,

接下来看一下OnBoard_KeyCallback函数

void OnBoard_KeyCallback ( uint8 keys, uint8 state )

HalKeyPoll中按键状态值

  if (keys && (pHalKeyProcessFunction))
  {
    (pHalKeyProcessFunction) (keys, HAL_KEY_STATE_NORMAL);
  }

我理解是参数一 一对应关系。

在OnBoard_KeyCallback函数中可以看到

 OnBoard_SendKeys( keys, shift ) != ZSuccess这个程序,进入发送函数

uint8 OnBoard_SendKeys( uint8 keys, uint8 state )
{
  keyChange_t *msgPtr;

  if ( registeredKeysTaskID != NO_TASK_ID )
  {
    // Send the address to the task
    msgPtr = (keyChange_t *)osal_msg_allocate( sizeof(keyChange_t) );
    if ( msgPtr )
    {
      msgPtr->hdr.event = KEY_CHANGE;
      msgPtr->state = state;
      msgPtr->keys = keys;

      osal_msg_send( registeredKeysTaskID, (uint8 *)msgPtr );
    }
    return ( ZSuccess );
  }
  else
    return ( ZFailure );
}

这样不难看出对于相应的任务状态值,其中osal_msg_send( registeredKeysTaskID, (uint8 *)msgPtr );函数中registeredKeysTaskID这个与前边pHalKeyProcessFunction相同,怎么相同呢?

我们找到main函数进入osal_init_system->osalInitTasks->SampleApp_Init,在初始化中找到
RegisterForKeys( SampleApp_TaskID ); // 登记所有的按键事件
进入这个函数

uint8 RegisterForKeys( uint8 task_id )
{
  // Allow only the first task
  if ( registeredKeysTaskID == NO_TASK_ID )
  {
    registeredKeysTaskID = task_id;
    return ( true );
  }
  else
    return ( false );
}

我们可以知道registeredKeysTaskID 所指示的任务就是我们所需要响应按键的SampleApp这个任务

osal_msg_send( registeredKeysTaskID, (uint8 *)msgPtr );那这个就是我们向SampleApp发送了一个附带按键信息的消息

进入这个函数uint8 osal_msg_send( uint8 destination_task, uint8 *msg_ptr )

找到  osal_set_event( destination_task, SYS_EVENT_MSG );这个函数作用就是设置destination_task这个事件为SYS_EVENT_MSG ,而destination_task正是由osal_msg_send这个函数通过传参而来的,指的就是SampleApp这个任务。

进入函数

uint8 osal_set_event( uint8 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
    return ( SUCCESS );
  }
   else
  {
    return ( INVALID_TASK );
  }
}

在函数中我们可以看到    tasksEvents[task_id] |= event_flag;  // Stuff the event bit(s)

到这里就可以和void osal_run_system( void )这个系统任务函数联系到一起,实现从任务事件的触发到系统任务的执行

(开始自己个人经验小结,有问题多多指教)

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值