zigbee协议栈简介

本文详细介绍了ZigBee无线网络协议栈的工作原理及其在实际应用中的具体实现过程。从协议栈的各层介绍入手,深入浅出地解析了ZigBee通讯的关键函数及其实现无线数据通信的基本步骤。

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

        协议是一系列的通信标准,通信双方需要共同按照这一标准进行正常的数据发射和接收。协议栈是协议的具体实现形式,通俗点来理解就是协议栈是协议和用户之间的一个接口,开发人员通过使用协议栈来使用这个协议的,进而实现无线数据收发。

        ZigBee 无线网络协议层的架构图:PHY(物理层)、MAC(介质访问层)技术规范、NWK (网络层)、 APS (应用程序支持子层)、APL (应用层)技术规范。

         我们在开发一个应用时,我们只需在应用层进行改动。我们只需的掌握 10 个函数就能使用 ZigBee 通讯。

         实现一个简单的无线数据通信时的一般步骤:

1、组网:调用协议栈的组网函数、加入网络函数,实现网络的建立与节点的加入。
2、发送:发送节点调用协议栈的无线数据发送函数,实现无线数据发送。
3、接收:接收节点调用协议栈的无线数据接收函数,实现无线数据接收。

        Samples 文件夹里面有三个例子: GenericApp、SampleApp、SimpleApp 在这
里们选择 SampleApp 对协议栈的工作流程进行讲解。打开\SampleApp\CC2530DB
下工程文件  SampleApp.eww。找到main()函数:

int main( void )
{
  // Turn off interrupts
  osal_int_disable( INTS_ALL );
// Initialization for board related stuff such as LEDs
  HAL_BOARD_INIT();
// Make sure supply voltage is high enough to run
  zmain_vdd_check();//电压监测
  // Initialize board I/O
  InitBoard( OB_COLD );//
// Initialze HAL drivers
  HalDriverInit();//初始化驱动led、key、lcd、uart
// Initialize NV System
  osal_nv_init( NULL );
// Initialize the MAC
  ZMacInit();
  // Determine the extended address
  zmain_ext_addr();
#if defined ZCL_KEY_ESTABLISH
  // Initialize the Certicom certificate information.
  zmain_cert_init();//不能调到该函数
#endif
// Initialize basic NV items
  zgInit();
#ifndef NONWK
  // Since the AF isn't a task, call it's initialization routine
  afInit();
#endif
// Initialize the operating system
  osal_init_system();
// Allow interrupts
  osal_int_enable( INTS_ALL );
// Final board initialization
  InitBoard( OB_READY );//对按键中断使能初始化
// Display information about this device   显示关于设备的信息
  zmain_dev_info();
  /* Display the device info on the LCD */ //lcd显示关于设备的信息
#ifdef LCD_SUPPORTED
  //zmain_lcd_init();
#endif

#ifdef WDT_IN_PM1
  /* If WDT is used, this is a good place to enable it. */
  WatchDogEnable( WDTIMX );
#endif

  osal_start_system(); // No Return from here

  return 0;  // Shouldn't get here.
}

我们重点看两个函数:

osal_init_system();

osal_start_system();

首先看

uint8 osal_init_system( void )
{
  // Initialize the Memory Allocation System初始化内存分配系统
  osal_mem_init();
// Initialize the message queue初始化消息队列
  osal_qHead = NULL;
// Initialize the timers初始化定时器
  osalTimerInit();
// Initialize the Power Management System初始化的电源管理系统
  osal_pwrmgr_init();
// Initialize the system tasks.初始化系统的任务。
  osalInitTasks();
// Setup efficient search for the first free block of heap.
//对于堆第一空闲块设置有效的搜索。
  osal_mem_kick();
  return ( SUCCESS );
}

中的osalInitTasks()函数:

void osalInitTasks( void )
{
uint8 taskID = 0;
//  分配内存,返回指向缓冲区的指针
tasksEvents = (uint16 *)osal_mem_alloc( sizeof( uint16 ) * tasksCnt); 
//  设置所分配的内存空间单元值为 0
osal_memset( tasksEvents, 0, (sizeof( uint16 ) * tasksCnt));
//  任务优先级由高向低依次排列,高优先级对应 taskID   的值反而小
macTaskInit(taskID  ++ );    //macTaskInit(0)  ,用户不需考虑
nwk_init(taskID ++ );       //nwk_init(1),用户不需考虑
Hal_Init(taskID ++ );      //Hal_Init(2)  ,用户需考虑
#if defined( MT_TASK ) 
MT_TaskInit(taskID ++ );
#endif
APS_Init(taskID ++ );    //APS_Init(3)  ,用户不需考虑
#if defined ( ZIGBEE_FRAGMENTATION )
APSF_Init(taskID ++ );
#endif
ZDApp_Init(taskID ++ );      //ZDApp_Init(4)  ,用户需考虑
#if defined ( ZIGBEE_FREQ_AGILITY ) || defined ( ZIGBEE_PANID_CONFLICT )
ZDNwkMgr_Init(taskID ++ );
#endif
SampleApp_Init(taskID );          // SampleApp_Init _Init(5)  ,用户需考虑
}

在看osal_start_system()函数中的 osal_run_system()函数:

void osal_run_system( void )
{
  uint8 idx = 0;

  osalTimeUpdate();
  Hal_ProcessPoll();  // This replaces MT_SerialPoll() and osal_check_timer().

  do {
    if (tasksEvents[idx])  // Task is highest priority that is ready.
    {
      break;
    }
  } while (++idx < tasksCnt);

  if (idx < tasksCnt)
  {
    uint16 events;
    halIntState_t intState;

    HAL_ENTER_CRITICAL_SECTION(intState);
   events = tasksEvents[idx];//提取需要处理的任务中的事件
    tasksEvents[idx] = 0;  // Clear the Events for this task.
    HAL_EXIT_CRITICAL_SECTION(intState);

    events = (tasksArr[idx])( idx, events );

    HAL_ENTER_CRITICAL_SECTION(intState);
    tasksEvents[idx] |= events;  // Add back unprocessed events to the current task.
    HAL_EXIT_CRITICAL_SECTION(intState);
  }
#if defined( POWER_SAVING )
  else  // Complete pass through all task events with no activity?
  {
    osal_pwrmgr_powerconserve();  // Put the processor/system into sleep
  }
#endif

  /* Yield in case cooperative scheduling is being used. */
#if defined (configUSE_PREEMPTION) && (configUSE_PREEMPTION == 0)
  {
    osal_task_yield();
  }
#endif
}

进入 tasksEvents[idx]数组定义,发现恰好在刚刚 osalInitTasks( void )函数上面。而且 taskID 一一对应。
这就是初始化与调用的关系。taskID 把任务联系起来了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

DreamTracks88

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值