ZigBee Zstack协议栈
一、Zstack协议栈概述
什么是Zstack协议栈
为了使Zigbee的开发更加简单高效,TI公司推出了基于cc2530芯片的协议栈Z-STACK.协议栈的实质就是能实现各个功能的实例框架代码,我们想要实现自己的功能程序,只需要在协议栈的基础上修改或添加即可。
- Z-STACK的发展
- 由0.01版本 到 1.5.1a…
- mesh: 之前的升级版本
- HA: 家庭自动化(智能家居)
- SE: 智能能源
…他们的区别是应用部分不同(初学者建议用早期的版本)
二、Zstack协议栈结构
Z-Stack协议栈符合ZigBee协议,由物理层、MAC层、网络层和应用层组成,由于Z-Stack协议栈是一个半开源的协议栈,MAC层和网络层的部分源代码是非开源的,因此我们学习的开源部分,主要包括main函数、APP层、ZDO层、NWK层和HAL层。
1.工程目录结构
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 库函数回调处理函数。
ZMain: 主函数目录, 包括入口函数 main( ) 及硬件配置文件。
Output: 输出文件目录, 这个 EW8051 IDE 自动生成的。
2.main函数解析
int main( void )
{/* 关闭所有中断*/osal_int_disable( INTS_ALL );/* 初始化硬件设备*/HAL_BOARD_INIT();/*电源检测*/zmain_vdd_check();/*初始化I/O*/InitBoard( OB_COLD );/*初始化硬件抽象层HAL驱动*/HalDriverInit();/*初始化NV*/osal_nv_init( NULL );/*初始化 MAC*/ZMacInit();/*确定64位IEEE地址*/zmain_ext_addr();/*初始化NV向量*/zgInit();
#ifndef NONWK/* AF层初始化/afInit();
#endif/*初始化任务*/osal_init_system();/*开启中断*/osal_int_enable( INTS_ALL );/*硬件I/O初始化完毕*/InitBoard( OB_READY );zmain_dev_info();/* 如果定义了LCD,初始化LCD */
#ifdef LCD_SUPPORTEDzmain_lcd_init();
#endif
#ifdef WDT_IN_PM1/* 如果定义了看门狗,看门狗使能 */WatchDogEnable( WDTIMX );
#endif/*操作系统运行*/osal_start_system();return 0;
}
osal_int_disable()
uint8 osal_int_disable( uint8 interrupt_id )
{/*判断ID是否为中断ID*/
if ( interrupt_id == INTS_ALL )
{/*关掉所有中断*/
HAL_DISABLE_INTERRUPTS();
/*中断关闭成功,返回SUCCESS */
return ( SUCCESS );
}
else
{/*如果ID与INST_ALL不同,返回
INVALID_INTERRUPT_ID*/
return ( INVALID_INTERRUPT_ID );
}
}
3.APP层解析
OSAL_SampleApp.c中包含osalInitTasks()与taskArr[]。
osalInitTasks()函数主要功能是为任务分配空间
void osalInitTasks( 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++ );
#if defined( MT_TASK )MT_TaskInit( taskID++ );
#endifAPS_Init( taskID++ );
#if defined ( ZIGBEE_FRAGMENTATION )APSF_Init( taskID++ );
#endifZDApp_Init( taskID++ );
#if defined ( ZIGBEE_FREQ_AGILITY ) || defined ( ZIGBEE_PANID_CONFLICT )ZDNwkMgr_Init( taskID++ );
#endifSampleApp_Init( taskID );
OSAL_SampleApp.c
tasksArr中存放了事件处理回调函数
const pTaskEventHandlerFn tasksArr[] = {macEventLoop,nwk_event_loop,Hal_ProcessEvent,
#if defined( MT_TASK )MT_ProcessEvent,
#endifAPS_event_loop,
#if defined ( ZIGBEE_FRAGMENTATION )APSF_ProcessEvent,
#endifZDApp_event_loop,
#if defined ( ZIGBEE_FREQ_AGILITY ) || defined ( ZIGBEE_PANID_CONFLICT )ZDNwkMgr_event_loop,
#endifSampleApp_ProcessEvent
};
Z-Stack协议栈的APP层主要功能是实现用户定义的事件,APP层由5个文件组成
SamplApp.c文件主要有两个功能:
(1)对应用层用户定义的任务
(2)进行初始化;调用事件处理函数。
- 用户任务初始化函数SampleApp_Init()
- 任务处理函数SampleApp_ProcessEvent()
- 按键处理事件SampleApp_HandleKeys()
- 数据发送函数SampleApp_SendFlashMessage()
- 数据发送函数SampleApp_SendPeriodicMessage()
- 数据接收函数SampleApp_MessageMSGCB()
SampleApp_Init()
void SampleApp_Init( uint8 task_id )
{SampleApp_TaskID = task_id;SampleApp_NwkState = DEV_INIT;SampleApp_TransID = 0;
#if defined ( BUILD_ALL_DEVICES )if ( readCoordinatorJumper() )zgDeviceLogicalType = ZG_DEVICETYPE_COORDINATOR;elsezgDeviceLogicalType = ZG_DEVICETYPE_ROUTER;
#endif
#if defined ( HOLD_AUTO_START )ZDOInitDevice(0);
#endif/*SampleApp_Periodic_DstAddr地址模式初始化为广播地址*/SampleApp_Periodic_DstAddr.addrMode = (afAddrMode_t)AddrBroadcast;/* SampleApp_Periodic_DstAddr端点初始化*/SampleApp_Periodic_DstAddr.endPoint = SAMPLEAPP_ENDPOINT;SampleApp_Periodic_DstAddr.addr.shortAddr = 0xFFFF;SampleApp_Flash_DstAddr.addrMode = (afAddrMode_t)afAddrGroup;SampleApp_Flash_DstAddr.endPoint = SAMPLEAPP_ENDPOINT;SampleApp_Flash_DstAddr.addr.shortAddr = SAMPLEAPP_FLASH_GROUP;
SampleApp_Init()
SampleApp_epDesc.endPoint = SAMPLEAPP_ENDPOINT;
SampleApp_epDesc.task_id = &SampleApp_TaskID;
SampleApp_epDesc.simpleDesc= (SimpleDescriptionFormat_t *)&SampleApp_SimpleDesc;
SampleApp_epDesc.latencyReq = noLatencyReqs;afRegister( &SampleApp_epDesc );RegisterForKeys( SampleApp_TaskID );SampleApp_Group.ID = 0x0001;
osal_memcpy( SampleApp_Group.name, "Group 1", 7 );
aps_AddGroup( SAMPLEAPP_ENDPOINT, &SampleApp_Group );#if defined ( LCD_SUPPORTED )
HalLcdWriteString( "SampleApp", HAL_LCD_LINE_1 );
#endif
}
SampleApp_ProcessEvent()
SampleApp_ProcessEvent()
SampleApp_HandleKeys()
SampleApp_MessageMSGCB()
SampleApp_MessageMSGCB()函数主要实现数据接收功能,数据的接收通过判断簇ID来
与发送端发送的数据进行匹配。
SampleApp_SendPeriodicMessage()
SampleApp_SendPeriodicMessage()函数主要功能是实现周期性数据的发送,通过调用
AF_DataRequest()函数进行数据的发送。
SampleApp.h
4.ZDO层解析
目录结构
ZDApp_Init()函数:初始化ZDO网络设备短地址;获得64位IEEE地址信息;ZDO层初始化;网络设备启动。
5.NWK层解析
目录结构
网络拓扑结构
/*星型网络*/
#define NWK_MODE_STAR 0
/*树型网络*/
#define NWK_MODE_TREE 1
/*网状网络*/
#define NWK_MODE_MESH 2
网络参数设置
/*协议栈模式参数*/
#define NETWORK_SPECIFIC 0
#define HOME_CONTROLS 1
#define ZIGBEEPRO_PROFILE 2
#define GENERIC_STAR 3
#define GENERIC_TREE 4
/*信道设置*/
#define MAX_CHANNELS_868MHZ 0x00000001
#define MAX_CHANNELS_915MHZ 0x000007FE
#define MAX_CHANNELS_24GHZ 0x07FFF800
6.HAL层解析
HAL目录
Common:实现了硬件初始化函数Hal_Init()、硬件抽象层驱动初始化HalDriverInit ()函数和硬件抽象层事件处理函数Hal_ProcessEvent();
Include:中主要包含了硬件资源的定义与函数声明;
Target:主要为LED等硬件资源进行配置、实现硬件资源的实现函数;
Hal_Init()函数主要为硬件抽象层注册任务ID
void Hal_Init( uint8 task_id )
{/* 注册任务 ID */Hal_TaskID = task_id;
}
HalDriverInit()函数主要实现硬件资源的初始化
void HalDriverInit (void)
{/*定时器初始化*/
#if (defined HAL_TIMER) && (HAL_TIMER == TRUE)HalTimerInit();
#endif
/*ADC初始化*/
#if (defined HAL_ADC) && (HAL_ADC == TRUE)HalAdcInit();
#endif
/*DMA初始化*/
#if (defined HAL_DMA) && (HAL_DMA == TRUE)HalDmaInit();
#endif
/*Flash初始化*/
#if (defined HAL_FLASH) && (HAL_FLASH == TRUE)HalFlashInit();
#endif
/*AES初始化*/
#if (defined HAL_AES) && (HAL_AES == TRUE)HalAesInit();
#endif
/*LCD初始化*/
#if (defined HAL_LCD) && (HAL_LCD == TRUE)HalLcdInit();
#endif
/*LED初始化*/
#if (defined HAL_LED) && (HAL_LED == TRUE)HalLedInit();
#endif
/*UART初始化*/
#if (defined HAL_UART) && (HAL_UART == TRUE)HalUARTInit();
#endif
/*KEY按键初始化*/
#if (defined HAL_KEY) && (HAL_KEY == TRUE)HalKeyInit();
#endif
/*SPI初始化*/
#if (defined HAL_SPI) && (HAL_SPI == TRUE)HalSpiInit();
#endif
}
HHal_ProcessEvent()函数由APP层OSAL_SampleApp.c文件调用,主要实现硬件抽象层的各种事件处理,比如系统消息事件、LED闪烁事件、按键事件和睡眠模式事件。
uint16 Hal_ProcessEvent( uint8 task_id, uint16 events )
{uint8 *msgPtr;/*系统消息事件*/if ( events & SYS_EVENT_MSG ){msgPtr = osal_msg_receive(Hal_TaskID);while (msgPtr){osal_msg_deallocate( msgPtr );msgPtr = osal_msg_receive( Hal_TaskID );}return events ^ SYS_EVENT_MSG;}/*LED闪烁事件*/if ( events & HAL_LED_BLINK_EVENT ){#if (defined (BLINK_LEDS)) && (HAL_LED == TRUE)HalLedUpdate();
#endif /* BLINK_LEDS && HAL_LED */return events ^ HAL_LED_BLINK_EVENT;}
/*按键事件*/
if (events & HAL_KEY_EVENT)
{#if (defined HAL_KEY) && (HAL_KEY == TRUE)
/* Check for keys */
HalKeyPoll();
if (!Hal_KeyIntEnable)
{osal_start_timerEx( Hal_TaskID, HAL_KEY_EVENT, 100);
}
#endif
return events ^ HAL_KEY_EVENT;
}
/*睡眠模式*/
#ifdef POWER_SAVING
if ( events & HAL_SLEEP_TIMER_EVENT )
{halRestoreSleepLevel();
return events ^ HAL_SLEEP_TIMER_EVENT;
}
#endif
return 0;
}
HTarget hal_board_cfg.h文件中为硬件资源LED等进行配置,在官方的协议栈中定义了3个LED,分别接CC2530的P1_0、P1_1和P1_4引脚。
/* LED1配置 */
#define LED1_BV BV(0)
#define LED1_SBIT P1_0
#define LED1_DDR P1DIR
#define LED1_POLARITY ACTIVE_HIGH#ifdef HAL_BOARD_CC2530EB_REV17/* LED2配置 */#define LED2_BV BV(1)#define LED2_SBIT P1_1#define LED2_DDR P1DIR#define LED2_POLARITY ACTIVE_HIGH/* LED3配置 */#define LED3_BV BV(4)#define LED3_SBIT P1_4#define LED3_DDR P1DIR#define LED3_POLARITY ACTIVE_HIGH
#endif
控制LED开关状态。
#if defined (HAL_BOARD_CC2530EB_REV17) && !defined (HAL_PA_LNA) && !defined (HAL_PA_LNA_CC2590)/*打开LED*/#define HAL_TURN_OFF_LED1() st( LED1_SBIT = LED1_POLARITY (0); )#define HAL_TURN_OFF_LED2() st( LED2_SBIT = LED2_POLARITY (0); )#define HAL_TURN_OFF_LED3() st( LED3_SBIT = LED3_POLARITY (0); )#define HAL_TURN_OFF_LED4() HAL_TURN_OFF_LED1()/*关闭LED*/#define HAL_TURN_ON_LED1() st( LED1_SBIT = LED1_POLARITY (1); )#define HAL_TURN_ON_LED2() st( LED2_SBIT = LED2_POLARITY (1); )#define HAL_TURN_ON_LED3() st( LED3_SBIT = LED3_POLARITY (1); )#define HAL_TURN_ON_LED4() HAL_TURN_ON_LED1()/*LED状态改变*/#define HAL_TOGGLE_LED1() st( if (LED1_SBIT) { LED1_SBIT = 0; } else { LED1_SBIT = 1;} )#define HAL_TOGGLE_LED2() st( if (LED2_SBIT) { LED2_SBIT = 0; } else { LED2_SBIT = 1;} )#define HAL_TOGGLE_LED3() st( if (LED3_SBIT) { LED3_SBIT = 0; } else { LED3_SBIT = 1;} )#define HAL_TOGGLE_LED4() HAL_TOGGLE_LED1()#define HAL_STATE_LED1() (LED1_POLARITY (LED1_SBIT))#define HAL_STATE_LED2() (LED2_POLARITY (LED2_SBIT))#define HAL_STATE_LED3() (LED3_POLARITY (LED3_SBIT))#define HAL_STATE_LED4() HAL_STATE_LED1()
#endif
在Drives文件中定义了硬件资源的驱动函数文件
- LED:在hal_led.c文件中实现,为LED提供驱动函数;
- ADC:在hal_adc.c文件中实现,为ADC提供驱动函数;
- KEY:在hal_key.c文件中实现,为按键提供驱动函数;
- LCD:在hal_LCD.c文件中实现,为LCD提供驱动函数;
- 定时器:在hal_timer.c文件中实现,为定时器提供驱动函数;
- 串口:在hal_uart.c文件中实现,为串口提供驱动函数;
- DMA:在hal_dma.c文件中实现,为DMA提供驱动函数;
- flash:在hal_flash.c文件中实现,为flash提供驱动函数。
APP应用层调用LED设置函数
HalLedSet(uint8 leds,uint8 mode);
HalLedBlink(uint8 leds,uint8 numBlink,uint8 percend,uint16 period);
ZigBee Zstack协议栈相关推荐
- 【无线通信篇 | Zstack协议栈】CC2530 Zigbee Zstack协议栈组网项目及详细讲解篇
演示视频:https://www.bilibili.com/video/BV1Ew411o7Fp 物联网无线通信技术,ZigBee无线传感网络 CC2530最大的特点就是一个拥有无线收发器(RF)的单 ...
- 【Zigbee技术入门教程-02】一图读懂ZStack协议栈的核心思想与工作机理
[Zigbee技术入门教程-02]一图读懂ZStack协议栈的核心思想与工作机理 广东职业技术学院 欧浩源 Z-Stack协议栈是一个基于任务轮询方式的操作系统,其任务调度和资源分配由操作系统抽 ...
- zigbee之Zstack协议栈使用
zigbee之Zstack协议栈使用 前言 基于zstack协议栈开发的步骤 一.OSAL操作系统 1.操作系统工作流程 2.OSAL初始化函数 3.系统启动函数 (1)任务 (2)事件 4.OSAL ...
- 「ZigBee模块」协议栈-Z-Stack协议栈基础和数据传输实验
花了好久写的...感觉还不错的呢...如果看,请细看...Mua~ Z-Stack协议栈基础和数据传输实验 一.实验目的 终端节点将数据无线发送到协调器,协调器通过串口将数据发送到PC端,并在屏幕上显 ...
- 揭开ZigBee 2006协议栈Z-Stack的”开源“面纱
我们都在说ZigBee 2006协议栈Z-Stack是开源的,但是这个协议栈到底是全部开源的,还是只是开源一部分,让我们来揭开它的"开源"面纱? Z-Stack是在2007 ...
- 02、ZigBee组网原理Z-Stack协议栈工作机理
文章目录 1.组网概述 2.网络初始化预备 3.网络初始化流程 3.1.确定网络协调器 3.2.进行信道扫描过程 3.3.设置网络ID 4.节点通过协调器加入网络 4.1.查找网络协调器 4.2.发送 ...
- 1、zstack协议栈
zstack协议 1.什么是协议栈 2.什么是zstack协议栈 1.什么是协议栈 协议联盟,如ZigBee联盟.蓝牙联盟.WiFi联盟等联盟,是一个组织,他们发布的某种协议规范.如ZigBee联盟发 ...
- Z-Stack协议栈学习笔记7---修改PANID与信道选择
PANID设置 一个zigbee网络的标志就是PANID,PANID是一个16位变量,可以定义65535个不同PANID号的网络.我们可以使用PANID在相同的信道内区分不同的zigbee网络.PAN ...
- Z-stack 协议栈基础知识
Z-stack协议栈简单知识: ZigBee 的协议分为两部分, IEEE 802.15.4 定义了 PHY(物理层)和 MAC(介质访问层)技术规范:ZigBee 联盟定义了 NWK(网络层).AP ...
- 快速了解ZigBee的协议栈
带大家来一起快速的看懂ZigBee的协议栈的运行流程. 1.读任何程序都需要从main函数入手,那我们先来看Zmain.c中的main函数. 问题:在main中我们会看到很多的函数,我们究竟要看哪个函 ...
最新文章
- 操作系统学习:Linux0.12初始化详细流程-打开文件与加载可执行程序
- 套接字(socket)与socket 编程
- html div box,html – 为转换后的div添加box-shadow
- hdu 2007 - 平方和与立方和
- 十年架构师详解JVM运行原理
- 为什么感觉iPhone 11还有很多人去买?
- [转]远远走来一个绿茶婊
- wrong ELF class: ELFCLASS64
- 3.软件架构设计:大型网站技术架构与业务架构融合之道 --- 语言
- DeadObjectException
- 动手学深度学习(三十四)——序列模型
- php varbinary,php – 无法从MSSQL中获取varbinary数据
- Serverless 实战:3 分钟实现文本敏感词过滤
- 【运筹学】整数规划 ( 相关概念 | 整数规划 | 整数线性规划 | 整数线性规划分类 )
- 6G八大关键技术(国泰君安团队)
- [C语言]实现字符串从头尾分别输出字符的动画效果
- ARM架构SMMU驱动详解
- 多线程—如何下载网图
- 【渝粤教育】电大中专电子商务网站建设与维护答案作业 题库
- [模型库]两款经典puma560机器人三维模型