8.1 TI Z-Stack协议栈代码介绍
TI公司在提供Zigbee无线单片机CC2530的同时,也提供了Z-Stack协议栈源代码,以方便设计人员将Z-Stack直接移植到CC2530上使用,使其支持IEEE 802. 15. 4/ZigBee 协议。TI也提供比较多的工具软件,如CC2530的FLASH编程软件,包监视分析软件,以及一些在协议之上的应用案例,简单点对点通信软件、智能家居应用软件等。
为了使我们自己的系统稳定可靠运行,必须保证硬件的设计稳定可靠,满足需要的功能要求外,软件的设计也是同样重要的。为了使整个系统能很好的正常工作,必须让软硬件协同操作,在TI的Z-Stack协议栈之上开发我们自己的软件系统,不愧为一种很好的、省力的方式。自己去写Z-Stack协议栈代码并让其稳定运行是不现实的,不是投入太大就是时间太长。这样,对TI的Z-Stack协议栈代码进行必要的了解是非常必要的。
通过IAR软件打开TI的Z-Stack协议栈,如下图所示:
第一次打开工程印象最深刻的就是左边一排文件夹,非常多,很庞杂,感觉无从下手。我们先不深入目录之下,先了解每个目录放的是什么内容,那么知道各个文件夹大概是什么功能,分布在 ZIGBEE 的哪一层,那么在以后的工作中无论是查询某些功能函数还是修改某些功能函数,甚至是添加或删除某些功能函数就能顺利的找到在什么地方了,方便对Z-Stack协议栈软件的更深入的学习了解。
下面对Z-Stack协议栈的文件夹进行介绍:
APP(ApplicationProgramming):应用层目录,这是用户创建各种不同工程的区域,在这个目录中包含了应用层的内容和这个项目的主要内容,在协议栈里面一般是以操作系统的任务实现的。
APP:用户应用程序及接口,包括串口数据处理、无线接收数据处理、用户LCD显示处理、传感器数据读取和发送等。
HAL(Hardware (H/W) Abstraction Layer):硬件层目录,包含有与硬件相关的配置和驱动及
操作函数。
MAC:MAC 层目录,包含了 MAC 层的参数配置文件及其 MAC 的 LIB 库的函数接口文件。
MT(Monitor Test):实现通过串口可控各层,于各层进行直接交互。
NWK(ZigBee Network Layer):网络层目录,含网络层配置参数文件及网络层库的函数接口文件,APS 层库的函数接口
OSAL(Operating System (OS) Abstraction Layer):协议栈的操作系统。
Profile:AF(Application work)层目录,包含 AF 层处理函数文件。
Security:安全层目录,安全层处理函数,比如加密函数等。
Services:地址处理函数目录,包括着地址模式的定义及地址处理函数。
Tools:工程配置目录,包括空间划分及 ZStack 相关配置信息。
ZDO(ZigBee Device Objects):ZDO 目录。
ZMac: MAC 层目录,包括 MAC 层参数配置及 MAC 层 LIB 库函数回调处理函数。
ZMain:主函数目录,包括入口函数及硬件配置文件。
Output:输出文件目录,这个是EW8051 IDE 自动生成的。
Z-Stack 协议栈用操作系统的思想来构建,采用事件轮询机制。当各层初始化之后,系统进
入低功耗模式,当事件发生时,唤醒系统,开始进入中断处理事件,结束后继续进入低功耗模式。如果同时有几个事件发生,则判断优先级,逐个处理事件。这种软件构架可以极大地降级系统的功耗。
整个Z-Stack 的主要工作流程,大致分为系统启动,驱动初始化,OSAL 初始化和启动,
进入任务轮循几个阶段,下面将逐一详细分析。
1、TI的Z-Stack协议栈启动流程
可打开ZMain文件夹中的ZMain.c文件,查看int main(void)函数,协议栈即从此函数开始运
行。其启动流程如下所示:
2、系统初始化
系统上电后,通过执行ZMain文件夹中ZMain.c的ZSEG int main( )函数实现硬件的初
始化。硬件初始化需要根据HAL文件夹中的hal_board_cfg.h文件配置8051的寄存器。TI 官方发布Z-stack的配置针对的是TI 官方的开发板CC2530DB、CC2530EMK等,如采用其它开发板,则需根据原理图设计改变hal_board_cfg.h 文件配置。如按键多少及其对应的I/O口,LED指示灯的多少及其对应的I/O口,串口的波特率及中断还是DMA操作方式,是否有LCD等。也可以通过宏定义的方式,将硬件的功能模块的操作放开或屏蔽掉。
下面列出main函数,并在其掉用的函数处对其进行注释说明:int main( void ){
//关全局中断
osal_int_disable( INTS_ALL );
//板相关的硬件初始化,如时钟、LED等
HAL_BOARD_INIT();
//确保电源电压比正常运行的电压高
zmain_vdd_check();
//参数堆栈及返回地址堆栈清0
zmain_ram_init();
//判别是上电复位,复位键复位还是看门狗复位
InitBoard( OB_COLD );
//初始话硬件抽象层驱动,如Timers、
Adc,Dma,Flash,Aes,Leds,Uart,Key,Spi,and Lcd等
HalDriverInit();
//初始化FLASH存储器系统
osal_nv_init( NULL );
//初始化基本的非易失性存储器的项目,初始话Z-Stack全局变量。如果一个项目在非易失性//存储器中没有,则将缺省值写入其中。
zgInit();
//初始化MAC层
ZMacInit();
//决定起始的扩展IEEE地址
zmain_ext_addr();
//如果无网络层,则调用afInit()对无线射频部分进行初始化
#ifndef NONWK
afInit();
#endif
//初始化操作系统,初始化存储器系统、消息队列、定时器、电源管理系统、系统任务等
osal_init_system();
//开全局中断
osal_int_enable( INTS_ALL );
//进行板硬件的最后初始化,如键盘,摇杆等初始化
InitBoard( OB_READY );
//如果使用LCD,则调用用于LCD硬件的初始化
#ifdef LCD_SUPPORTED
zmain_lcd_init();
#endif
//显示如IEEE地址等设备信息,
zmain_dev_info();
//如果使用了看门狗,则将看门狗使能
#ifdef WDT_IN_PM1
WatchDogEnable( WDTIMX );
#endif
//启动操作系统,将不会从此函数返回