zigbee组网过程浅析

本文深入解析了zigbee协议栈的组网过程,从ZMain.c的main函数开始,详细介绍了osal_init_system()、osalInitTasks()以及各层初始化,特别是ZDO_InitDevice()在网络配置中的作用。通过ZDApp_NetworkInit()触发网络初始化,进一步探讨了ZDO_NetworkInit()和ZDO_StartDevice()在协调器节点创建网络中的角色,以及路由器和终端节点如何加入网络。整个过程涉及任务初始化、事件处理和原语交互,揭示了zigbee网络构建的内部机制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

       zigbee协议栈使用的是zstack版本,该协议栈的整体功能有点类似于操作系统。下面以SimpleApp例程为例,对协议栈的组网流程进行描述。

       协议栈是用C语言实现的,由于C语言的入口都是main函数,因此需要找到main函数,下图为协议栈各层列表(主要包括应用层、硬件层、MAC层、网络层、安全层、服务层等),TI公司的编程比较规范,文件的命名就意味着相关的功能。


图1 协议栈的整体架构

       可以看到,ZMain文件下面有ZMain.c文件,而该文件就是整个协议栈的入口地址。打开ZMain.c文件,可以看到函数intmain( void );该函数就是整个协议栈最开始的入口。在main函数里面可以看到语句:

 // Initialize the operating system

  osal_init_system();

       该语句的实际含义是初始化zigbee协议栈。

       进入函数osal_init_system()的内部(具体方法:使鼠标停留在osal_init_system上,并且单击右键,在弹出的选项中选择“go todefinition of osal_init_system”),定位到下列语句:

 // Initialize the system tasks.

  osalInitTasks();

       从这个函数的名字就可以知道它是用于初始化系统任务的。在zigbee协议栈中,一个非常重要而且贯穿协议栈生命周期的概念就是任务,也就是说协议栈的信息处理和数据传输等过程都是通过任务来实现的,即如果某个节点需要传输一个数据包,它会通过调用相关任务通知操作系统需要发送数据包。

既然任务是个非常重要的概念,那么就很有必要进入到osalInitTasks()函数内部,看看这个函数究竟是初始化那些任务!!

       类似,点击右键进入osalInitTasks函数内部,下面是该函数的内容:

voidosalInitTasks( void )

{

  uint8 taskID = 0;

 

  tasksEvents = (uint16 *)osal_mem_alloc(sizeof( uint16 ) * tasksCnt);

  osal_memset( tasksEvents, 0, (sizeof( uint16) * tasksCnt));

 

  macTaskInit( taskID++ );

  nwk_init( taskID++ );

  Hal_Init( taskID++ );

#ifdefined( MT_TASK )

  MT_TaskInit( taskID++ );

#endif

  APS_Init( taskID++ );

  ZDApp_Init( taskID++ );

  SAPI_Init( taskID );

}

 

       函数内部表明,函数执行了协议栈各层的初始化操作,包括mac层、网络层、硬件层等各层初始化。这里看到了此语句:ZDApp_Init(taskID++ );该语句的作用是初始化zigbee设备对象(ZDO),那zigbee设备对象是用来干什么的呢?为什么要对它进行初始化呢?

       一句话,应用层可以通过ZigBee设备对象(ZDO)对网络层参数进行配置和访问。也就是说ZDO会对要组建的zigbee网络进行各种配置。

       那ZDApp_Init()内部又是怎么实现的呢?同理进入到ZDApp_Init()内部,可以看到ZDApp_Init()就是对网络的各种初始化配置,定位到下列语句:

  if ( devState != DEV_HOLD )//在本人的zstack上devState不是DEV_HOLD

  {

    ZDOInitDevice( 0 );

  }

所以就执行了语句:ZDOInitDevice(0 );该函数是什么作用呢??它是负责启动网络。在函数ZDOInitDevice()内,定位到下列语句:

 // Trigger the network start

  ZDApp_NetworkInit( extendedDelay );

到这里就设置了定时触发启动网络了;

 

而ZDApp_NetworkInit()函数内部是怎么样出发网络启动的呢??

右键点击ZDApp_NetworkInit(),进入到ZDApp_NetworkInit()内部,它的函数体如下:

 

voidZDApp_NetworkInit( uint16 delay )

{

  if ( delay )

  {

    // Wait awhile before starting the device

    osal_start_timerEx( ZDAppTaskID,ZDO_NETWORK_INIT, delay );

  }

  else

  {

    osal_set_event( ZDAppTaskID,ZDO_NETWORK_INIT );

  }

}

在ZDApp_NetworkInit()内部有个if-else选择分支,if分支是经过一段时间后,再添加网络初始化任务,而else分支则是直接执行网络初始化任务,即else分支是直接执行语句osal_set_event(ZDAppTaskID, ZDO_NETWORK_INIT),而if分支经过一个延时后,再执行osal_set_event(ZDAppTaskID, ZDO_NETWORK_INIT)语句。说到底,ZDApp_NetworkInit()的内部就是执行语句:osal_set_event(ZDAppTaskID

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值