一.ZigBee 协议栈简介

有问题发送邮件至468078841@qq.com
什么是ZigBee 协议栈呢?它和ZigBee 协议有什么关系呢?协议是一系列的通信标准,通信双方需要共同按照这一标准进行正常的数据发射和接收。协议栈是协议的具体实现形式,通俗点来理解就是协议栈是协议和用户之间的一个接口,开发人员通过使用协议栈来使用个协议的,进而实现无线数据收发。

ZigBee 的协议分为两部分,IEEE 802.15.4 定义了PHY(物理层)和MAC(介质访问层)技术规范;ZigBee 联盟定义了NWK(网络层)、APS(应用程序支持子层)、APL(应用层)技术规范。ZigBee 协议栈就是将各个层定义的协议都集合在一直,以函数的形式实现,并给用户提供API(应用层),用户可以直接调用。

                                             Z-Stack协议栈体系结构

二.如何使用ZigBee 协议栈

协议栈是协议的实现,可以理解为代码,函数库,供上层应用调用,协议较底下的层与应用是相互独立的。你需要关心的就是你的应用逻辑,数据从哪里到哪里,怎么存储,处理;还有系统里的设备之间的通信顺序什么的.至于初始化等等工作不需要我们考虑。我们只需要调用相关的API函数就可以了。

三.了解zigbee协议栈的应用文件夹

安装好zigbee协议栈,打开目录Texas Instruments

(一)Components:顾名思义这个是放我们的库的文件夹,里面放了一些我们用到的ZDO,driver,hal,zcl 等库的代码

(二)Documents:这里放的是TI 的开发文档的,里面很多都是讲述协议栈的API

(三)Projects:这个文件夹放的是TI 协议栈的例子程序。

(四)Tools:这个文件夹是放TI 的例子程序的一些上位机之类的程序,作为工具使用。

接下来介绍的东西均需要打开示例工程在这里我们打开\ZStack-CC25302.5.1a\Projects\zstack\Samples\SampleApp\CC2530DB进入zigbee的协议栈中

为了确保程序没问题我们在这里重新编译一下协议栈。

这是我们协议栈的汇总目录

这里是我们zigbee的文件夹,里面写好的代码都分为很多的group
(一)APP:应用层目录,这里用户可以创建不同的工程目录,这里包含项目工程主要内容

(二)HAL:硬件层目录,包含有与硬件相关的配置和驱动及操作函数。

(三)MAC: MAC 层目录,包含了MAC 层的参数配置文件及其MAC 的LIB 库的函数接口文件。

(四)MT:实现通过串口可控各层,于各层进行直接交互。

(五)NWK:网络层目录,含网络层配置参数文件及网络层库的函数接口文件,APS 层库的函数接口

(六)OSAL:协议栈的操作系统。

(七)Profile: AF层目录,包含AF 层处理函数文件。

(八)Security:安全层目录,安全层处理函数,比如加密函数等。

(九)Services:地址处理函数目录,包括着地址模式的定义及地址处理函数。

(十)Tools:工程配置目录,包括空间划分及ZStack 相关配置信息。

(十一)ZDO: ZDO目录。

(十二)ZMac: MAC 层目录,包括MAC 层参数配置及MAC 层LIB 库函数回调处理函数。

(十三)Output:输出文件目录,这个EW8051 IDE 自动生成的。


点击DemoEB可以进行设备类型工作空间选择,必须要选好,不然不可以使用。

CoordinatorEB:为协调器的工作空间。

ROuterEB:为路由器的工作空间。

EndDeviceEB:为无线终端的设备选择。

四.zigbee协议栈的工作流程

在我们这个版本的来说在我们使用者的路径流程是:main()---> osal_init_system()---> osalInitTasks()---> SampleApp_Init()

(一)打开ZMain.c 找到main 函数
学过C语言的都知道,C语言函数是在一直执行main文件里面的内容,首先我们先查看main.c的内容


int main( void )
{// Turn off interruptsosal_int_disable( INTS_ALL ); //关闭协议栈所有中断// Initialization for board related stuff such as LEDsHAL_BOARD_INIT();             //初始化协议栈系统时钟// Make sure supply voltage is high enough to runzmain_vdd_check();            //检查芯片电压是否正常// Initialize board I/OInitBoard( OB_COLD );         //初始化I/O // Initialze HAL driversHalDriverInit();              //初始化芯片硬件// Initialize NV Systemosal_nv_init( NULL );         //初始化Flash 存储器// Initialize the MACZMacInit();                   //初始化MAC 层// Determine the extended addresszmain_ext_addr();             //确定IEEE 64位设备地址// Initialize basic NV itemszgInit();                     //初始化非易失变量#ifndef NONWK// Since the AF isn't a task, call it's initialization routineafInit();
#endif// Initialize the operating systemosal_init_system();           //初始化协议栈操作系统// Allow interruptsosal_int_enable( INTS_ALL );  //使能全部中断// Final board initializationInitBoard( OB_READY );        //最终板载初始化// Display information about this devicezmain_dev_info();             //LCD显示设备信息/* Display the device info on the LCD */
#ifdef LCD_SUPPORTEDzmain_lcd_init();             //初始化LCD
#endif#ifdef WDT_IN_PM1/* If WDT is used, this is a good place to enable it. */WatchDogEnable( WDTIMX );
#endifosal_start_system(); // No Return from here 执行操作系统,这里进入将不会退出,一直执行osal_start_systemreturn 0;  // Shouldn't get here.
} // main()

我们接着看一下osal_start_system在这里我们可以点击选中然后goto到函数里面查看。

void osal_start_system( void )
{#if !defined ( ZBIT ) && !defined ( UBIT )for(;;)  // Forever Loop //这是个死循环
#endif{osal_run_system();  //协议栈一直执行这个函数}
}

接着继续goto osal_run_system这个是任务系统轮询的主要函数。他会查找发生的事件然后调用相应的事件执行函数, 如果没有事件登记要发生那就将进入睡眠模式。在协议栈中,所有将要处理的内容定义为事件,这个函数就是查找事件的函数,每个事件都有自己的事件号,根据事件号大小判断优先级,一个一个执行,例如按键按键,就触发按键事件,这个现在知道就可以,在后面我们会介绍。
在这里我们知道了协议栈一直执行事件扫面函数,那我们如何根据需求开发呢,我们要做的就是设置一个自己要监测的事件,然后写交互逻辑。 // 一个任务可以有多个事件

void osal_run_system( void )
{uint8 idx = 0;osalTimeUpdate();//更新事件Hal_ProcessPoll();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);activeTaskID = idx;events = (tasksArr[idx])( idx, events );activeTaskID = TASK_NO_TASK;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
}

我们接下来进行事件的初始设置。在前面main函数中 osalInitTasks(); 为初始化系统任务,我们需要将自己的需求加入其中就可以达到目的。 goto一下进入函数 //osalInitTasks这个是设置任务的函数,然后任务里面也定义了很多事件

void osalInitTasks( void )
{uint8 taskID = 0;// 分配内存,返回指向缓冲区的指针tasksEvents = (uint16 *)osal_mem_alloc( sizeof( uint16 ) * tasksCnt);// 设置所分配的内存空间单元值为0osal_memset( tasksEvents, 0, (sizeof( uint16 ) * tasksCnt));// 任务优先级由高向低依次排列,高优先级对应taskID 的值反而小macTaskInit( taskID++ );  // taskID 0nwk_init( taskID++ );     // taskID 1Hal_Init( taskID++ );     //taskID 2
#if defined( MT_TASK )MT_TaskInit( taskID++ );
#endifAPS_Init( taskID++ );      //taskID 3
#if defined ( ZIGBEE_FRAGMENTATION )APSF_Init( taskID++ );
#endifZDApp_Init( taskID++ );    //taskID 4
#if defined ( ZIGBEE_FREQ_AGILITY ) || defined ( ZIGBEE_PANID_CONFLICT )ZDNwkMgr_Init( taskID++ );
#endif//SampleApp_Init为用户创建任务,我们需要在这里进行任务的添加 现在进入函数我们查看一下SampleApp_Init( taskID );  // taskID 5
}

在这里我们看一下用户应用任务的事件处理函数进入SampleApp_ProcessEvent函数在这里我们可以看到在协议栈初始的时候定义的事件,和处理函数,在后面我们再详细介绍如何使用。

uint16 SampleApp_ProcessEvent( uint8 task_id, uint16 events )
{afIncomingMSGPacket_t *MSGpkt;(void)task_id;  // Intentionally unreferenced parameterif ( events & SYS_EVENT_MSG )//如果是SYS_EVENT_MSG 这个事件进入这里{MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( SampleApp_TaskID );//类型转换while ( MSGpkt ){switch ( MSGpkt->hdr.event ){// Received when a key is pressedcase KEY_CHANGE:  //如果是按键按下进入下面这个函数SampleApp_HandleKeys( ((keyChange_t *)MSGpkt)->state, ((keyChange_t *)MSGpkt)->keys );break;// Received when a messages is received (OTA) for this endpointcase AF_INCOMING_MSG_CMD://如果是接受到RF消息进入这里SampleApp_MessageMSGCB( MSGpkt );break;// Received whenever the device changes state in the networkcase ZDO_STATE_CHANGE: //如果网络状态改变,这个绝壁进入,SampleApp_NwkState = (devStates_t)(MSGpkt->hdr.status);if ( (SampleApp_NwkState == DEV_ZB_COORD)|| (SampleApp_NwkState == DEV_ROUTER)|| (SampleApp_NwkState == DEV_END_DEVICE) ){// Start sending the periodic message in a regular interval.osal_start_timerEx( SampleApp_TaskID,SAMPLEAPP_SEND_PERIODIC_MSG_EVT,SAMPLEAPP_SEND_PERIODIC_MSG_TIMEOUT );}else{// Device is no longer in the network}break;default:break;}// Release the memory释放消息占用的内存osal_msg_deallocate( (uint8 *)MSGpkt );// Next - if one is available//  返回while ( MSGpkt )重新处理事件,直到缓冲区没有等待处理事件为止MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( SampleApp_TaskID );}// return unprocessed events  返回未处理的事件return (events ^ SYS_EVENT_MSG);}// Send a message out - This event is generated by a timer//  (setup in SampleApp_Init()).if ( events & SAMPLEAPP_SEND_PERIODIC_MSG_EVT ) //如果是 SAMPLEAPP_SEND_PERIODIC_MSG_EVT 事件进入这里 这里是网络状态改变之后标志位值1的{// Send the periodic messageSampleApp_SendPeriodicMessage();// Setup to send message again in normal period (+ a little jitter)osal_start_timerEx( SampleApp_TaskID, SAMPLEAPP_SEND_PERIODIC_MSG_EVT,(SAMPLEAPP_SEND_PERIODIC_MSG_TIMEOUT + (osal_rand() & 0x00FF)) );// return unprocessed eventsreturn (events ^ SAMPLEAPP_SEND_PERIODIC_MSG_EVT);}// Discard unknown eventsreturn 0;
}

了解以上的流程我们就可以了解到协议栈的整体运行机制了。并且大概的概念。

下面我们介绍本节涉及zigbee协议栈的函数;

函数名osal_start_timerEx

函数声明uint8 osal_start_timerEx( uint8 taskID, uint16 event_id, uint16 timeout_value )

这是一个定时器的函数,将在timeout_value毫秒之后将任务号为taskID的任务,事件号为event_id的事件标志位置为1.这个时候就可以通过evens&进行判断

有问题请发邮件至468078841@qq.com
zigbee协议栈串口收发 From zigbee菜鸟笔记(十 二)点击进入

zigbee协议栈工作流程 From zigbee菜鸟笔记(十 一)相关推荐

  1. ZIGBEE通讯-7.ZigBee协议栈简介

    想要学习协议栈,必须先知道协议是什么.协议定义的是一系列的通信标准,通信双方需要共同按照这一标准进行正常的数据收发,而协议栈是协议的具体实现形式,通俗的理解为用代码实现的函数库,以便于开发人员调用. ...

  2. zigbee菜鸟笔记(一)zigbee的基础知识

    一.什么是zigbee 有问题发送邮件至468078841@qq.com ZigBee,也称紫蜂,是一种低速短距离传输的无线网上协议,底层是采用IEEE 802.15.4标准规范的媒体访问层与物理层. ...

  3. ZigBee协议栈简介和流程

    ZigBee协议栈实际上就是ZigBee协议的API接口 一般步骤为: 1.组网:调用协议栈的组网函数.加入网络函数,实现网络的建立与节点的加入 2.发送:发送节点调用协议栈的无线数据发送函数,实现无 ...

  4. 第1章 ZigBee协议栈初始化网络启动流程

    igBee的基本流程:由协调器的组网(创建PAN ID),终端设备和路由设备发现网络以及加入网络. 基本流程:main()->osal_init_system()->osalInitTas ...

  5. ZigBee协议栈浅显解读(一)

    目前ZigBee开发主要用的是TI的CC2530.CC2530内部集成看增强型的51所以对于只学过51的小白入门不成问题. 本篇文章我只会介绍ZigBee的协议栈. 我们打开ZigBee协议栈后可以加 ...

  6. ZIGBEE通讯-10.ZigBee协议栈的无线点灯

    在ZIGBEE协议栈中已经自带了按键与LED的驱动与使用函数,所以只需要将按键与LED修改为使用的开发板所连接IO就可以使用了.接下来将主要分析在协议栈中按键的初始化.按键的检测以及按键事件的传递与处 ...

  7. ZigBee协议栈之osal浅析

    ZigBee是目前比较流行的一种低功耗无线组网技术,主要用于智能家居控制以及智能工业生产.ZigBee大的特点就是低功耗.自组网. 说到ZigBee就不得不提IEEE802.15和ZigBee联盟,他 ...

  8. CC2530 ZigBee协议栈 学习心得

    最近一直在学习研究cc2530这款单片机,感觉自己的C语言水平还是不够有得提升的空间,但还是有不少收获.    CC2530是一款支持ZigBee无线组网协议的低功耗单片机,cc2530主要的应用场景 ...

  9. zigbee协议栈OSAL分析

    本文从源程序出发,分享本人学习zigbee协议栈的一些理解,介绍zigbee协议栈OSAL任务调度及用户自定义任务的调度处理过程.为了便于抓住本质,理清思路,本文剔除一些无关部分. 程序的入口是ZMa ...

  10. zigbee协议栈学习(二)

    协议栈规范的 ID号可以通过查询设备发送的 beacon 帧获得.在设备加入网络之前,首先 需要确认协议栈规范的 ID."特定网络"规范 ID号为0: ZigBee协议栈规范的 I ...

最新文章

  1. 【通知】有三AI学社正式成立了,高质量人脉圈子,欢迎入社
  2. stanford python中文分词
  3. NgRx store.dispatch方法的单步调试
  4. 高性能 TCP UDP 通信框架 HP-Socket v3.2.3
  5. 五大算法之二--动态规划
  6. vijos 1083 小白逛公园
  7. selenium+unittest自动化测试(一)---环境搭建及用例编写规则
  8. Android Studio 红米3 一直运行或者debug不成功,提示 Failed to establish session 解决方案
  9. 雷军:《硅谷之火》给了我一个世界级的梦想
  10. 电视机魔百盒显示连接服务器失败,【当贝市场】魔百盒EPG主页加载不出来办法详解...
  11. 百度地图标记点加点击事件和鼠标移入事件并添加数据
  12. Eclipse中jsp文件ISO-8859-1编码转换为UTF-8或者GBK方法
  13. Linux一键安装部署环境
  14. 【前端冷知识】冷门函数之Math.hypot
  15. csdn博客文章头部自动生成目录
  16. 十分担心外行人抢内行人的饭碗
  17. 大数据开发 - Java入门2
  18. 人与树林交相辉映的效果
  19. [iOS]Advanced Memory Management Programming Guide 高级内存管理编程指南(官方文档翻译)
  20. K8s 支持一键部署

热门文章

  1. 线性代数常用的公式LaTeX表示
  2. JavaScript学习之初识JS
  3. (内附教程链接及模板下载)如何利用ICEM进行内流道的抽取
  4. Quartz数据库存储
  5. 2019年TW的技术雷达
  6. KITTI raw data 镜像地址
  7. 下载Windows10纯净官方镜像
  8. PMP考试提分必刷题
  9. pr视频两边模糊_pr教程:如何制作视频画面局部模糊效果?-吾尊时尚
  10. JAVA项目--银行管理系统