ZigBee是目前比较流行的一种低功耗无线组网技术,主要用于智能家居控制以及智能工业生产。ZigBee大的特点就是低功耗、自组网。
说到ZigBee就不得不提IEEE802.15和ZigBee联盟,他们公共制定了ZigBee协议栈的标准。组网过程就是基于ZigBee协议栈,协议栈完成了绝大部分的工作,留给没У木褪怯τ贸绦蚪涌凇P檎痪拖褚桓霾僮飨低骋谎没е恍枰ㄖ朴τ贸绦蚓涂梢允褂谩�
先来看一下ZigBee协议栈架构,操作系统下面的可以当做BootLoader,操作系统上面的可以看做应用程序。对于用户来说,只要了解操作系统,会定制task,那么就可以使用协议栈了。
接下来我们以TI公司的ZigBee协议栈为标准,了解一下osal操作系统机制,以方便后续定制task。
Osal源于一种简单的操作系统思想---轮询。在ZigBee协议栈中,OSAL负责调度各个任务的运行,如果有事件发生了,则会调用相应的事件处理函数进行处理。那么,事件和任务的事件处理函数是如何联系起来的呢?
ZigBee中采用的方法是:建立一个事件表,保存各个任务的对应的事件,建立另一个函数表,保存各个任务的事件处理函数的地址,然后将这两张表建立某种对应关系,当某一事件发生时则查找函数表找到对应的事件处理函数即可。
在ZigBee协议栈中,有三个变量至关重要。
● tasksCnt—该变量保存了任务的总个数。
该变量的声明为:uint8 tasksCnt,其中uint8的定义为:typedef unsigned char uint8
● tasksEvents—这是一个指针,指向了事件表的首地址。
该变量的声明为:uint16 *tasksEvents,其中uint16的定义为:typedef unsigned short uint16
● tasksArr—这是一个数组,数组的每一项都是一个函数指针,指向了事件处理函数。
该数组的声明为:const pTaskEventHandlerFn tasksArr[],其中pTaskEventHandlerFn的定义为:typedef unsigned short (*pTaskEventHandlerFn)( unsigned char task_id, unsigned short event ),这是定义了一个函数指针。tasksArr数组的每一项都是一个函数指针,指向了事件处理函数。
事件表和函数表的关系如下图
我们现在来总结下OSAL的工作原理:通过tasksEvents指针访问事件表的每一项,如果有事件发生,则查找函数表找到事件处理函数进行处理,处理完后,继续访问事件表,查看是否有事件发生,无限循环。OSAL就是一种基于事件驱动的轮询式操作系统。事件驱动是指发生事件后采取相应的事件处理方法,轮询指的是不断地查看是否有事件发生。
下面从代码中看一下osal运行机制。在Zmain文件夹下有个Zmain.c文件,打开该文件可以
找到main()函数,这就是整个协议栈的入口点。main()函数原型如下:
int main( void )
{
// Turn off interrupts
osal_int_disable( INTS_ALL );
// Initialization for board related stuff such as LEDs
HAL_BOARD_INI