首页 理论教育 ZigBee2006协议栈简介

ZigBee2006协议栈简介

时间:2023-06-30 理论教育 版权反馈
【摘要】:ZigBee 2006协议栈依据IEEE 802.15.4标准和ZigBee协议规范。ZigBee网络中的各种操作需要利用协议栈各层所提供的原语操作来共同完成。IEEE 802.15.4标准和ZigBee协议规范中定义的各层原语操作多达数十条,原语的操作过程也比较复杂,它已经不是一个简单的单任务软件。pfnEventProcessor是指向协议栈相关层的事件处理函数指针。

 ZigBee2006协议栈简介

ZigBee 2006协议栈依据IEEE 802.15.4标准和ZigBee协议规范。ZigBee网络中的各种操作需要利用协议栈各层所提供的原语操作来共同完成。原语操作的实现过程往往需要向下一层发起一个原语操作并且通过下层返回的操作结果来判断出下一条要执行的原语操作。IEEE 802.15.4标准和ZigBee协议规范中定义的各层原语操作多达数十条,原语的操作过程也比较复杂,它已经不是一个简单的单任务软件。对于这样一个复杂的嵌入式通信软件来说,其实现通常需要依靠嵌入式操作系统来完成。

1.任务调度

ZigBee协议栈中的每一层都有很多原语操作要执行,因此对于整个协议栈来说,就会有很多并发操作要执行。本文为协议栈中的每一层都设计了一个事件处理函数,用来处理与这一层操作相关的各种事件。将这些事件处理函数看成是与协议栈每一层相对应的任务,由ZigBee协议栈中调度操作系统抽象层(Operating System Abstraction Layer,OSAL)来进行管理。

这样,对于协议栈来说,无论何时发生了何种事件,都可以通过调度协议栈相应层的任务,即事件处理函数来进行处理。这样,整个协议栈便会按照时间顺序有条不紊地运行。

ZigBee协议栈的实时性要求并不高,因此在设计任务调度程序时,OSAL只采用了轮询任务调度队列的方法来进行任务调度管理。OSAL采用一个链表结构来管理协议栈各层相应的任务。链表中的每一项都是一个结构体,用来记录链表中相关任务的基本信息。链表的建立是按照任务优先级从高到低的顺序进行插入的。其中优先级高的任务将被插入在优先级较低的任务前面。如果两个任务的优先级相同,则按照先后顺序加入链表。这个链表在系统启动的时候建立,一旦建立后便一直存在于整个系统运行的过程中,直到系统关闭或硬件复位才被销毁。

链表中每一项的数据结构声明如下:

在这个结构中pfnInit是指向协议栈相关层的初始化函数指针。例如,在网络层的设计中,任务初始化函数为nwkInit,用来对网络层相关数据进行初始化操作。其函数声明如下:

extern void nwkInit(byte task_id);

其中参数task_id代表为网络层任务分配的唯一任务号。

pfnEventProcessor是指向协议栈相关层的事件处理函数指针。例如,在网络层的设计中,事件处理函数为nwk_event_loop,用来处理与网络层相关的各种事件。其函数声明如下:

其中参数event_flag表示需要在网络层处理的事件。

结构中的taskID表示为任务分配的任务号。

taskPriority表示当前任务的优先级。

events表示需要被处理的事件。如果为0,表示没有要被处理的事件。

与任务链表管理相关的主要操作有添加任务到列表中、获取下一个活动任务、根据taskID值查找相应的任务。现分别说明如下:

(1)在任务管理列表中添加任务

这个函数将遍历整个任务队列链表并按照优先级的高低将优先级高的任务插入到优先级低的任务前;否则,就将任务插入到链表尾部。在这个过程中,将为每个任务分配一个唯一任务号。其函数声明如下:

(2)获取下一个活动任务

这个函数将根据osalTaskRec_t结构中的events标记来获取任务队列中下一个要执行的任务。其函数声明如下:

(3)根据taskID查找任务

这个函数将根据任务列表在建立过程中为协议栈中每个任务分配的任务号,来查找对应的任务。其函数声明如下:

当任务链表建立成功后,系统便开始运行。如果在系统运行的过程中有事件发生,系统就会通过调用相应的任务,即事件处理函数,对所发生的事件进行相应处理。在整个运行过程中,调度程序将始终不停地轮询任务队列链表,以发现需要处理的事件。这个过程涉及两个函数操作:一个是调度程序主循环函数,一个是设置事件发生标志函数。下面分别加以说明:

(1)系统主循环

这个函数将始终不停地轮询任务队列链表,来处理系统发生的各种事件。其函数声明和函数的部分实现如下:

(2)设置事件发生标志(www.xing528.com)

当协议栈中有任何事件发生时,可以通过设置osalTaskRect结构中的events来标记有事件发生,以便主循环函数能够及时加以处理。其函数说明如下:

2.时间管理

在协议栈中的每一层都会有很多不同的事件发生,这些事件发生的时间顺序各不相同。很多时候,事件并不要求立即得到处理,而是要求过一定的时间后再进行处理。因此,往往会遇到下面情况:假设A事件发生后要求10s之后执行,B事件在A事件发生1s后产生,且B事件要求5s后执行。从时间轴的角度上,我们可以知道,B事件虽然在A事件之后发生,但应当在A事件之前被处理。为了按照合理的时间顺序来处理不同事件的执行,这就需要对各种不同的事件进行时间管理。OSAL调度程序设计了与时间管理相关的函数,用来管理各种不同的要被处理的事件。

对事件进行时间管理,OSAL也采用了链表的方式进行,每当发生一个要被处理的事件后,就启动一个逻辑上的定时器,并将此定时器添加到链表之中。利用硬件定时器作为时间操作的基本单元。设置时间操作的最小精度为1ms,每1ms硬件定时器便产生一个时间中断,在时间中断处理程序中去更新定时器链表。每次更新,就将链表中的每一项时间计数减1,如果发现定时器链表中有某一表项时间计数已经减到0,则将这个定时器从链表中删除,并设置相应的事件标志。这样任务调度程序便可以根据事件标志进行相应的事件处理。根据这种思路,来自协议栈中的任何事件都可以按照时间顺序得到处理。从而提高了协议栈设计的灵活性。

在设计过程中需要经常使用这样一个时间管理函数,其函数声明如下:

extern byte osal_start_timer(byte task_id,UINT16 event_id,UINT16 timeout_value);

这个函数为事件event_id设置超时等待时间timeout_value。一旦等待结束,便为task_id所对应的任务设置相应的事件发生标记,从而达到对事件进行延迟处理的目的。

3.原语通信

为了使ZigBee网络能够正常工作,IEEE 802.15.4标准和ZigBee协议规范在协议的各层分别定义了大量的原语操作。其中,请求(Request)、响应(Response)原语分别由协议栈中处于较高位置的层向较低层发起;确认(Confirm)、指示(Indication)原语则从较低层向较高层返回结果或信息。

OSAL调度程序设计了两个相关的函数来完成这个过程,下面分别介绍。

向目标任务发送消息的函数,这个函数主要用来将原语操作的结果以消息的形式向上层任务发送,并产生一个系统事件来通知调度程序。其函数声明如下:

extern byte osal_msg_send(byte destination_task,byte*msg_ptr,byte len);

其中参数destination_task是目标任务的任务号,参数指针msg_ptr指向要被发送的消息,参数len为消息的长度

消息提取函数

这个函数返回一个指向osal_msg_received_t结构的指针,从结构的成员函数可以看出,通过msg_ptr这个指针我们就可以提取出所需要的信息。

下面以MAC层数据返回原语MCPS_Data Confirm所对应的函数为例,来说明如何设计确认(Confirm)、指示(Indication)类型原语。其他相同类型原语的处理过程均类似。其函数实现如下:

这个函数的设计思路是首先利用osal_msg_allocate函数在内存中分配一个用来存储操作结果的空间。然后将这些结果信息存储在MacDataCnf_t数据结构中相对应的成员函数中。最后通过osal_msg_send函数将结果发送到网络层。

网络层在得知有系统事件发生后,便通过调用事件处理函数提取消息信息并进行相应的处理。其处理过程如下所示:

其中ProcessMcpsDataConfirm函数用来对MCPS_Data Confirm原语返回的结果进行处理。

4.软件测试思路

协议栈软件的实现比较复杂,其功能比较繁多,加上嵌入式软件本身由于受到硬件环境的局限,要对其进行验证并不十分容易。因此,为了保证软件功能实现的正确性,可以分步对其进行测试。

首先,为了防止受限于硬件上的一些物理因素,对软件的测试工作可以通过剥离物理层程序,然后设计仿真测试环境来模拟硬件平台的基本操作,使整个软件的工作环境脱离开发板。这样便可以在PC上对软件的工作过程进行仿真,从而保证上层程序设计的正确性。

另一方面,在去掉上层程序后,对物理层程序进行单独验证。测试其基本的硬件操作是否正确,同时也可以排除掉由于硬件操作的错误而带来的上层软件判断的错误。

最后,将经过验证后的程序进行联调,对最终程序做进一步的验证工作,以保证程序的正确性。

免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。

我要反馈