发表时间:2008-6-10
1、前言
ZigBee(IEEE802.15.4)是一种低速率(2~200kbps)WPAN IEEE标准,传输速率只有100kbps;同时,它又具有功耗低、架构简单、成本低的特点,满足多种无线要求,尤其在工控(监视器、传感器和自动控制设备)等领域更是显示出其独有的优势。
随着射频技术、集成电路技术的发展,无线通信功能的实现越来越容易,数据传输速度也越来越快。本文在分析了ZigBee网络特点的基础上,对ZigBee通信协议栈实现中的内存,时钟管理等关键技术进行了研究,并提出了相应的实现方案。
2、ZigBee技术及其优势
ZigBee技术是一种近距离、低复杂度、低功耗、低数据速率低成本的双向无线通信技术,主要适合于自动控制和远程控制领域,可以嵌入各种设备中,同时支持地理定位功能。
2.1 ZigBee协议栈结构
图1 ZigBee的体系结构
ZigBee Protocol Stack体系结构如图1所示,它主要有5层体系组成。由ZigBee联盟与IEEE 802. 15.4的任务小组来共同担任标准的制定。其中物理层、MAC层标准主要由IEEE802. 15. 4的任务小组完成.而数据链路接层,以及传输过程中的网络层、还有与用户的接口是由ZigBee联盟主导。
在这个通信协议层次中,IEEE802.15.4/ZigBee各层协议的功能如下:
◆ 物理层。IEEE802.15.4运行在2.4 GHz ISM频段。采用直接序列扩频DSSS(Direct Sequence SpreadSpectrum)调制方式,以降低数字集成电路的成本,并且都使用相同的包结构,以便低作业周期、低功耗地运作。
◆ MAC层。负责处理所有的物理无线信道访问,并产生网络信号和同步信号,支持PAN连接和分离,提供两个对等MAC实体之间可靠的链路等。
◆ 网络接口层。负责处理ZigBee网络路由,实现网络地址和MAC地址的相互转换。
◆ 应用层。为用户应用进程间数据通信提供的接口。
发送时,ZIGBEE应用进程在调用应用层服务时,应该提供所有服务所需的参数;然后由应用层服务将数据经过编码后,传给网络接口层对象,调用网络层数据传输服务把数据发送出去。
接收时,应用层收到来自通信端口的数据后,上传给应用层服务;由应用层服务根据服务报文中的目的应用进程标识ID,将接收到的数据传送到应用层中相应的用户应用进程,由用户应用进程对相应的参量进行更新和进一步的处理。
2.2 Zigbee技术的主要优点
1) 省电。由于工作周期很短、收发信息功耗较低、并且采用了休眠模式, Zigbee技术可以确保2节五号电池支持长达6个月到2年左右的使用时间,当然不同的应用功耗是不同的。
2) 可靠。采用了碰撞避免机制,同时为需要固定带宽的通信业务预留了专用时隙,避免了发送数据时的竞争和冲突.MAC层采用了完全确认的数据传输机制,每个发送的数据包都必须等待接收方的确认信息。
3) 成本低。模块的初始成本估计在6美元左右,很快就能降到1. 5美元到2. 5美元之间,且Zigbee协议是免专利费的。
4) 时延短。针对时延敏感的应用做了优化,通信时延和从休眠状态激活的时延都非常短,设备搜索时延典型值为30 ms,休眠激活时延典型值是15 ms,活动设备信道接入时延为15 ms。
5) 网络容量大。一个ZigBee网络可以容纳最多254个从设备和一个主设备,一个区域内可以同时存在最多100个ZigBee网络。
6) 安全。ZigBee提供了数据完整性检查和鉴权功能,加密算法采用AES-128,同时各个应用可以灵活确定其安全属性。
3、ZIGBEE协议中的内存管理
嵌入式系统软件设计中采取的内存管理方案有两种――静态分配和动态分配。一般来说,嵌入式系统总是两种方案的组合,纯粹的静态分配一般只使用在不计成本来保证严格实时性的场合,而且静态分配容易使系统失去灵活性。考虑到ZigBee协议栈主要应用于低速率低传输量的网络设备中,所以我们在ZigBee协议栈设计中主要采用动态内存管理方式。动态内存管理机制在嵌入式软件设计是难点,也是直接关系到整个系统性能的关键,它必须满足以下几个特性:
在ZigBee协议栈设计中,针对网络部分和非网络部分的内存需求,我们把整个系统内存分成报文缓冲区和通用缓冲区两个不同的区域。先从系统申请固定大小的静态内存做为报文缓冲区和通用缓冲区,在每块内存区上定义自身的内存分配和回收算法,通过这种设计,能够确保网络系统不使用系统全部可用内存,应用程序也不会使用网络已用内存,从而实现了内存区域隔离,也防止了协议栈耗尽所有系统内存,提高了系统的稳定性和可靠性。
3.1 报文缓冲区
ZigBee协议中用户数据从本地嵌入式设备传输到远程设备的过程中,要经过各层协议,对消息的封装,去封装和拷贝操作几乎是不可避免的。而通常所采用的用一段连续的内存区来存储,传递数据的做法会有一下的缺陷:
(1)当从上层向下层传递数据时,下层协议需要对数据进行封装,而上层在申请内存时不会考虑到下层的需要。这样就会导致下层协议处理时需要重新申请内存并进行内存拷贝,从而影响程序的效率。
(2)当从下层向上层传递数据时,下层协议专有的数据结构赢得对上层协议不可见。因此也需要重新申请内存进行拷贝。
(3)随着数据的逐层处理,其内容可能有所增删,而连续内存很难处理这样动态的数据增删。
因此,必须要有一种能适应数据动态增删,而在逻辑上又呈现连续性的数据结构,以满足各层之间的数据传递,而不是进行内存拷贝。因此在ZigBee协议栈设计中采取的报文内存管理方案必须满足以下要求:
(1)适合存放不同长度的数据。
(2)方便地操作变长缓存。
(3)尽量减少为完成这些操作所做的数据拷贝。
综合考虑系统效率和ZigBee网络报文的特点,在ZigBee协议栈设计中,我们设计的每个缓冲块的长度固定,大小以满足ZigBee网络中的大多数报文的长度为标准,这里我们设置每个缓冲块的长度为128字节,大于这个长度的报文,就用多个缓冲块形成的缓冲链来满足。
ZIGBEE_BUFFER类型的缓冲区是报文缓冲区,其内部结构如图2所示,该结构包括两个指针,两个长度域,其中next 域指针指向下一个ZIGBEE_BUFFER的缓冲块,pdata域指向ZIGBEE_BUFFER中的数据起始位,tot_len域包括整个数据链的数据长度,len域包含该缓冲块中的数据长度。ZIGBEE_BUFFER整个结构的大小取决域所使用的处理器体系结构中一个指针的大小及可能的最小alignment的大小。在带有32位指针和4个字节alignment的体系结构,整个的大小为16字节。
图2 ZIGBEE_BUFFER报文缓冲区
一个ZIGBEE_BUFFER链,如图3所示:
缓冲区的操作函数:
void buf_init( void );
zigbee_buf_t * buf_alloc( void );
zigbee_buf_t * buf_new(u16_t tot_len);
void buf_delete(zigbee_buf_t *buffer);
zigbee_buf_t * buf_adjust(zigbee_buf_t *buffer, s16_t flen, s16_t blen);
void buf_read(zigbee_buf_t *buffer, u8_t *pdata, u16_t *len);
void buf_write(zigbee_buf_t *buffer, u8_t *pdata, u16_t *len);
对报文缓冲区使用这种设计方法,能够实现从中断发送,到协议处理,用户接收等整个过程中,数据只需要一次拷贝,减少了对数据空间需求(不用频繁地进行数据硬复制),从而提高了ZIGBEE协议处理地实时性。
3.2 通用缓冲区
在ZigBee协议栈设计中,通用缓冲区管理的实现很简单,它分配和回收邻近的内存区域并且调整已分配的内存块。它使用系统中全部内存的特定区域, ZIGBEE_MEM类型的缓冲区是通用缓冲区,主要满足协议栈中与报文无关的内存需求。
在ZIGBEE_RAM内部,内存管理通过将一种小的结构放置在每一个被分配的内存块的顶端上来追踪分配的内存,这个结构(图4)设置两个指针指向内存中下一个和前一个分配块,还有一个flag标志用来指示这个内存块是否已经被分配。使用最先适用的原则,通过搜索一个未使用的内存块来分配内存。当一个内存块被释放时,flag标志被设为0,为了防止碎片,检测下一个和上一个内存块的flag标志,如果它们还没有被使用,几个块合并成一个大的未使用的块。
4、ZigBee协议中的时钟管理
在ZigBee协议栈设计中,定时器的有效管理尤为重要,能不能对定时器进行合理的管理往往成为提高整个协议栈实时性能的瓶颈。对定时器的组织和管理最简单的方式是采取先进先出(FIFO)方式的链表单队列,这种组织管理方式会有一下两个问题:
(1)定时队列太长,找到所有到点定时器的时间开销难以接受;
(2)当定时器中断发生时要对所有的定时器的时长域进行减法操作,该部分时间性开销也很大。
另外,在实现ZigBee协议的芯片中,外设资源相对有限,为了使该协议栈能够广泛的应用于多种硬件平台,我们使用一个硬件定时器为基准时钟,然后在其基础上设计了简单递增时钟队列,以满足ZigBee系统对时间的要求。
在系统中,为每个任务分配申请一个简单相对递增时钟队列,队列中的定时节点按照定时时长排列有序,时长短的靠前,如图5所示,定时节点1的时长为5 ticks, 定时节点2的时长为2ticks, 定时节点3的时长为4ticks, 在队列中,定时节点的时长值改为相对前一定时节点时长的差值,即相对时长。当时钟中断发生时,只需对队头的时长域进行减1操作,所有的到点定时节点也均集中于队列的前面。
每个队列中又可以有多个时钟节点。逻辑时钟队列中,每个定时节点的数据结构如下所示:
typedef void (* timer_fun)(void *arg);
struct timer_node{
struct timer_node *next; /* 指向下一个定时节点 */
u32 time; /* 定时时间 */
timer_fun hander; /* 定时时间到后执行的函数 */
void *arg; /* 定时时间到后执行函数的参数 */
}
一个时钟队列如下图所示:
逻辑时钟队列的处理函数有:
void time_queue_init( void );
u8_t time_task_add(u32_t msec, time_fun hander, void *arg);
u8_t time_task_delete(time_fun hander, void *arg);
在ZIGBEE协议栈设计中,利用此种定时队列,能够使用一个基准定时器就可以简单,有效的实现确定性调度和时间同步所需的定时功能。
5、结论
本协议栈设计采用标准C进行开发,并在chipcon公司出产的cc2430芯片上进行了测试,测试结果表明:采用分类链式内存管理和相对递增时钟队列的内存和时钟管理方法的ZigBee通信协议栈通信过程稳定,速度快。