楼主: cyril3

深入浅出Z-Stack 2006 OSAL多任务资源分配机制

[复制链接]
anbin 发表于 2011-4-5 10:17:45 | 显示全部楼层
太牛了,向楼主学习!
mumu201001 发表于 2011-4-6 16:43:06 | 显示全部楼层
向楼主学习~~~达人啊~
chenliangmagica 发表于 2011-4-10 10:42:17 | 显示全部楼层
太好了   但是能不能给个按键的例子  这样能更清楚它的执行过程  比如:通过一个按键控制一个led灯,需要修改zstack的每个地方能列出来,这样对我们这些初学者将会很有帮助的    希望楼主 能贴出来共享一下按键的实例
fsrcwxy 发表于 2011-4-15 08:40:49 | 显示全部楼层
顶!!!!!!!!!!!!
c87812369 发表于 2011-4-19 01:32:59 | 显示全部楼层
回复 1# cyril3


    首先赞一个,谢谢楼主的无私分享。菜鸟的我们就是因为你们的无私分享才会进步得更快!
    这里我对你这篇教程有些许不懂之处:“ 那么如何向OSAL声明处理按键事件的任务是GenericApp呢?”
    这里我还不是很明白:
"在GenericApp_Init(GenericApp的任务初始化函数)中有这么一个语句:
  {
        RegisterForKeys( GenericApp_TaskID );
  }
"
这句话为什么是向OSAL声明处理按键事件的任务是GenericApp呢??
处理按键事件的任务是GenericApp_ProcessEvent,在tasksArr[] 定义并初始化时已经确定的了,见贴在最后的代码。
那么,对于下面这个函数,它的作用是什么呢?求详解。
uint8 RegisterForKeys( uint8 task_id )
{
  // Allow only the first task
  if ( registeredKeysTaskID == NO_TASK_ID )
  {
    registeredKeysTaskID = task_id;
    return ( true );
  }
  else
    return ( false );
}

在楼主的详解之前,请允许我把我自己的见解说出来跟大家讨论:{
在Onboard.c中搜索可得:
registeredKeysTaskID是在本文件Onboard.c中定义的全局变量:static uint8 registeredKeysTaskID = NO_TASK_ID;初始化为NO_TASK_ID。
而另外,对于 registeredKeysTaskID,它有如下这种用法:(调用 osal_msg_send()函数向registeredKeysTaskID发送信息,而这个registeredKeysTaskID估计就是按键处理任务的ID了)。
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 );

}

那么,这意味着, RegisterForKeys()函数的“注册”意义只在于本文件内(如果registeredKeysTaskID变量没有在别的文件内被extern声明),作用就是让osal_msg_send( )用来向taskarr[]中的GenericApp_ProcessEvent发送消息。
貌似registeredKeysTaskID在这里做了无用功:
osal_init_system( void )--->
osalInitTasks()--->
GenericApp_Init( taskID )/*在osalInitTasks里的taskID已经是Taskarr[]数组里面对应于按键处理函数的标号了because of按顺序注册*/--->
RegisterForKeys( GenericApp_TaskID );--->/*在这个函数里面,GenericApp_TaskID = task_id;    task_id是GenericApp_Init( taskID )的参数 taskID*/
那么,RegisterForKeys( uint8 task_id )不就是拿了一个已经确定了的按键处理函数ID去注册确定按键处理函数的ID吗?怎么理解这种行为?


  FILE NAME:OSAL_GenericApp.c
 /*********************************************************************
* GLOBAL VARIABLES
*/

// The order in this table must be identical to the task initialization calls below in osalInitTask.
const pTaskEventHandlerFn tasksArr[] = {
  macEventLoop,
  nwk_event_loop,
  Hal_ProcessEvent,
#if defined( MT_TASK )
  MT_ProcessEvent,
#endif
  APS_event_loop,
#if defined ( ZIGBEE_FRAGMENTATION )
  APSF_ProcessEvent,
#endif
  ZDApp_event_loop,
#if defined ( ZIGBEE_FREQ_AGILITY ) || defined ( ZIGBEE_PANID_CONFLICT )
  ZDNwkMgr_event_loop,
#endif
  GenericApp_ProcessEvent
};
pattision 发表于 2011-4-19 17:45:11 | 显示全部楼层
回复 66# c87812369


把GenericApp_ProcessEvent放在tasksArr[]中只是把任务事件处理函数的指针告知操作系统,而并没有说明该任务会去处理“按键”事件。
而RegisterForKeys( uint8 task_id )函数的作用就在告诉操作系统与其参数task_id对应的任务需要处理“按键”事件。
至于其中的判断语句 if ( registeredKeysTaskID == NO_TASK_ID ) 是为了避免多个任务同时登记“按键通知”服务*。NO_TASK_ID 意味着先前没有任务登记按键通知,那么就可以记下其任务ID以便在按键状态改变时向其发送消息。else 的情况是已经有任务登记了“按键通知”,那么就出现冲突,返回错误。

*此处的“按键通知”是OSAL的一个系统服务,而且是独占性的系统服务。该服务的作用就是当按键状态改变时通过消息通知登记该服务的任务。“独占性”就是说该服务只能被一个任务登记。也就是说不能两个任务都处理按键事件。
 楼主| cyril3 发表于 2011-4-19 23:41:36 | 显示全部楼层
回复 67# pattision


    正解
stoneR_Z 发表于 2011-5-6 17:06:18 | 显示全部楼层
后来者,顶下啊
zhuifeng 发表于 2011-5-14 11:36:39 | 显示全部楼层
分析很清楚,有用,谢了!
nauxgig 发表于 2011-5-15 15:11:37 | 显示全部楼层
学习了,谢谢!!!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表