如果你已经初步了解了ZigBee是什么或者接触过一些ZigBee的芯片,那么你一定对z-stack协议栈有所耳闻。如果还没有的话,建议先阅读小编的前两篇博文喔~
Zigbee学习(一)架构及入网
Zigbee学习(二)认识Profile和Cluster
1.下载安装Z-Stack
Z-Stack是TI(德州仪器)提供的协议栈代码,配套ZigBee MCU CC2530或CC2538,方便开发人员迅速移植以及开发应用。它用一个非常简单的基于轮转查询的操作系统osal来实现ZigBee 协议栈以及各任务处理。接下来我们就来解析Z-Stack的代码框架。
附上TI官网上Z-Stack下载地址,作为Z-Stack 3.0官方下载地址,大家放心使用!
打开https://www.ti.com/tool/Z-STACK,单击Download按钮,就可以下载啦(如果没有注册的貌似需要先注册)。
下载后是一个exe后缀的安装包,双击它运行并将其安装在windows电脑上就可以来看代码啦。
2.源码框架解析
2.1 初始化及轮询入口
首先我们找到入口文件ZMain.c里的入口函数main.c
如图可以看到main中的结构,一些比较关键的初始化函数被放在一个临界区中,以免上电初始化被中断打断而导致程序出错。关闭和打开总中断都是操作EA寄存器(中断总寄存器),接着再进行一些外设初始化、看门狗使能,就到了进入操作系统的入口,程序会在**osal_start_system();**中一直轮询,此函数不会返回。
下面是具体的解析,大家可以对照代码及注释:
2.2 初始化操作系统
在main的初始化函数中有一个重要函数osal_init_system();用于初始化操作系统,在这个初始化中将对任务事件按优先级进行初始化osalInitTasks();
TI在这份源代码中已经提供了一些应用,这部分是需要用户自己修改和根据自己的应用来实现的,我们就选其中的一个OSAL_GenericApp.c来看看如何初始化任务。
当我们进入OSAL_GenericApp.c中的osalInitTasks,发现有一系列的初始化函数用于各层的任务事件初始化。在任务初始化osalInitTasks中,给每一个任务事件分配了一个taskID(递增),优先级越高,taskID越小(可以这样记:优先级越高就越优先初始化)。在每一个任务事件初始化中都会将这个taskID赋值给该任务,任务事件处理数组是通过任务id来调用的(后面会提到)
要特别注意的是初始化任务调度函数的顺序要和任务事件处理数组中的顺序一一对应。我们往上翻一翻代码就会看到任务事件处理函数的数组。
2.3 任务事件调度
回到ZMain.c中,在main()的最后一行return 0;前,有一个进入操作系统的入口。当初始化完成后,就要进入操作系统进行任务轮询了。进入osal_start_system(),看到里面有一个死循环用于不停运行这个操作系统。
进入osal_run_system();找到轮询部分
当if条件成立的时候,即任务数组中有任务待执行,程序就会往下执行
在调用任务处理函数时,任务处理函数会将消息压入队列。然后通过osal_set_event函数来将相应的事件标志位置1,执行完后,通过osal_clear_event函数将相应的事件标志位置0。
举个栗子,当调用到zcl_event_loop这个任务处理函数,先检查消息队列中是否有任务事件,如果有,则会在osal_msg_receive中使用osal_set_event传递事件标志位,若没有,则使用osal_clear_event清除事件标志位。
在任务处理函数中,还会有消息的解析、消息组包、外设输出响应等功能。根据开发者的不同需求添加。
不积跬步,无以至千里。如果有收获的话,给小编点个赞叭!