ZigBee协议栈的OSAL运行机理研究与测试

2017-09-08 23:22张玲丽
物联网技术 2017年8期
关键词:技术支持

张玲丽

摘 要:文中研究分析了ZigBee协议栈的OSAL运行机理,并在此基础之上,通过规范的编程流程,设计了一个行之有效的测试系统,很好地演示了OSAL如何實现多任务切换和处理机制,对后期基于协议栈的编程提供了技术支持。

关键词:ZigBee协议栈;OSAL;任务事件;技术支持

中图分类号:TP39;TN92 文献标识码:A 文章编号:2095-1302(2017)08-00-02

0 引 言

从ZigBee 2006协议栈开始,ZigBee协议栈内加入了实时操作系统,主要制定了一个实现任务间切换、同步与互斥等的机制,而这就是操作系统表象层OSAL (Operating System Abstraction Layer,OSAL)产生的根源。OSAL与标准的操作系统存在一定区别,它只实现了类似操作系统的某些功能,如任务切换、内存管理等,还不能称为真正意义上的操作系统[1]。OSAL专门分配了存放所有任务事件的tasksEvents[]数组,每一个单元对应存放着每一个任务的所有事件,在这个函数中首先通过一个do—while循环来遍历tasksEvents[],找到一个具有待处理事件的优先级最高的任务,序号低的任务优先级高,然后跳出循环,此时,就得到了最高优先级任务的序号idx,然后通过events=tasksEvents[idx]语句将当前具有最高优先级的任务事件取出,接着调用(tasksArr[idx])(inx,events)函数来执行具体的处理。taskArr[]是一个函数指针数组,根据不同的idx可以执行不同的函数[2],其程序流程图如图1所示。

打开一个ZigBee工程文件,在左侧通常可以看到三个文件,分别为“Coordinator.c”、“Coordinator.h”、“OSAL_GenericApp.c”。整个程序所实现的功能都包含在这三个文件中。首先打开Coordinator.c 文件,可以看到两个比较重要的函数GenericApp_Init 和 GenericApp_ProcessEvent。GenericApp_Init是任务的初始化函数,GenericApp_ProcessEvent则负责判断由参数传递的事件类型,然后执行相应的事件处理函数[3]。我们的设计同样需要遵循该流程,既要进行任务初始化也需要完成开中断执行操作系统实体的功能。可以将该工作细化为初始化工作、事件的设置和响应、编写任务事件处理函数。本文设计了一个验证该运行机理的演示代码,展示了不同优先级的任务是如何按先后顺序被初始化及跳转到相应的任务事件处理函数来执行的效果。

1 初始化工作

在Zmain.c中首先应启动系统,即需要完成初始化功能,包括硬件平台和软件架构所需的各个模块,为操作系统的运行做好准备。由于大部分初始化工作协议栈已设置好,此处我们只需特别设置的初始化工作包括初始化工作时钟、初始化串口、初始化定时器、设置串口、使能中断等,同时用户自定义的事件也都需要放到任务初始化函数中进行初始化,此过程分为两步:

(1)将所有任务对应的事件表清空,任务事件表保存在TaskEvents结构当中,该结构是一个uint16类型的数组,数组的每一个元素对应一个任务所有的事件,16位对应了16个事件。其中最高位表示是否为系统事件,最高位为1,则表示为系统事件;最高位为0,则表示为非系统事件。

(2)为每个任务分配任务ID并初始化具体任务,任务ID决定了任务的优先级,ID越小响应的优先级越高,在任务初始化函数中,最新初始化的任务ID最小,优先级最高,ID依次递增,最小ID为0,最大ID为TaskCont-1。其具体代码如下:

void OS_IntTasks( void )

{

uint8 i,taskId = 0;

for( i = 0; i < TaskCont; i ++ )

{

TaskEvents[i] = 0;

}

testOsInt( taskId++ ); //增加任务初始化,确定任务ID

}

倘若需要增加更多任务,只需在testOsInt( taskId++ )注册新任务即可。

2 事件的设置和响应

任务事件的设置有两种方式[4]:一种直接使用uint8osal_set_event( uint8 task_id, uint16 event_flag )函数来设置事件,该函数包含了两个参数,即任务ID和事件标志;另一种方法是设置一个超时事件。设置超时事件与直接设置事件的区别在于,超时事件不会立刻将事件加入到相应任务的事件列表中,而是需要等待一定时间后才会加入,这个事件是通过设置函数的第三个参数来决定。

OSAL_STATE osal_start_timerEx( uint8 taskID,uint16 event_flag,uint16 timeout_value ){ }

从参数来看,该函数与osal_set_event函数相比,多了一个time_out_value参数,该参数用来设置超时值。该超时值的度量单位就是前面初始化timer1时设置的中断节拍。

响应任务事件首先需要得到准备就绪任务的ID,得到就绪任务ID后就可以通过该ID号得到相应的任务事件处理函数:events = (TasksFn[idx])(idx, events),其中TasksFn为任务事件处理函数表,表中的函数与任务ID号相对应。本设计只定义了一个任务响应函数:const OSEventHandle TasksFn[] = {testOsProcess;},其可将任务进程注册到任务函数指针列表中。endprint

在该设计中增加了一个超时事件,即在osal_start_timerEx函数中调用了osalAddTimer函数[5],将事件加入到系统时钟资源当中。该系统时钟资源由一个结构体数据定义,其原型如下:

typedef struct

{

void *next;//指向下一个节点

uint16 timeout;//超时事件中的超时值保存在此处,当该值减到0时,将该时钟资源记录的任务事件增加到事件列表当中

uint16 event_flag;//事件标识

uint8 task_id;//任务ID

} osalTimerRec_t;

在系统轮询时,除了对任务事件进行查询外,还增加了扫描事件查询函数OS_Scan(),在该函数里对timer1的中断服务函数进行自增运算,每次在OS_Scan中清零,而temp则记录了mcuTimerCounterForOSAL的拷贝,即每次轮询花费的系统时间。但关键在于OSALTimerUpdate函数若导致超时,则会将设置有事件标识的时钟资源的超时值进行自减,将运行时间在timerout中减去,一旦判断timerout值为0,便将相应的事件进行设置,同时取消该超时事件记录。

本设计分别采用直接设置事件法和设置超时事件法来设置以下两个事件:

(1)在任务号为testOSTaskID的任务中设置系统事件0x8000和非系统事件0x0001,osal_set_event(testOSTaskID,0x8001 );

(2)在任务号为testOSTaskID的任务中设置超时事件0x0002,打开定时器,并设置超时值为3 000 ms,osal_start_timerEx(testOSTaskID, 0x0002, 3000)。

3 编写任务处理函数

本设计需要在Coordinator.c中增加对应的任务处理函数,在任务处理函数中实现对系统事件0x8000、非系统事件0x0001和超时事件0x0002的处理。对应的任务处理函数如下:

uint16 testOsProcess( uint8 taskId, uint16 events )

{

//系统任务

if( events & 0x8000 )

{

uartsendstring((void *)”OS SYS events\r\n”,15);

return events ^ 0x8000;

}

//串口信息任务

if( events & 0x0001 )

{

uartsendstring((void *)”OS test events\r\n”,16);

return events ^ 0x0001;

}

if(events & 0x0002 )

{

uartsendstring((void *)”OS Timer events\r\n”,17);

osal_start_timerEx(testOSTaskID, 0x0002, 3000);//打开超时定时器,3 s超时

return events ^ 0x0002;

}

return 0;

}

对于0x8000事件,通过串口发送”OS SYS events\r\n”字符串;对于0x0001事件,通过串口发送”OS test events\r\n”字符串;对于0x0002事件,通过串口发送”OS Timer events\r\n”字符串,并周期性设置该事件。

4 结 语

为了验证OSAL是如何按照处理事件的优先级顺序来依次处理事件的,将上述编写好的代码组织形成工程文件,并下载到相关硬件开发板或平台上,采用串口通信線把网关底板和计算机连接起来。打开串口调试助手并正确设置后,从串口输出数据,其视图如图2所示,先显示OS SYS events,然后显示OS test events,之后每间隔3 s显示一次OS Timer events。

由此可见,操作系统是优先处理系统强制事件,然后处理用户自定义事件。由于本设计中事件1和事件2的优先级一样,因此优先处理先准备好的事件,由于设置定时器事件时设置了3 s的超时,因此交换两事件的任务ID号后处理和显示的顺序不变。如果有多个同时准备好的时间,系统会按照任务ID号从小到大的顺序依次处理。本设计为展示ZigBee协议栈里所包含的精简OS系统如何进入任务轮询状态并按照一定的任务优先级进入任务事件处理,提供了行之有效的测试方案。

参考文献

[1]王小强,欧阳骏,黄宁淋.ZigBee无线传感器网络设计与实现[M].北京:化学工业出版社,2012.

[2]郑海杰,宋开新.综合OSAL的ZigBee协议栈设计[J].杭州电子科技大学学报(自然科学版),2015(6):32-35.

[3]陈亚琳.Zigbee协议栈消息事件处理分析[J].南京工业职业技术学院学报,2014(4):44-48.

[4]李战明,刘宝,骆东松.ZigBee技术规范与协议栈分析[J].微型机与应用,2009,28(5):45-48.

[5]章伟聪,俞新武,李忠成.基于CC2530及ZigBee协议栈设计无线网络传感器节点[J].计算机系统应用,2011,20(7):184-187,120.

[6]李志瑞,程万里,杜永章.基于CC2530无线MEMS加速度传感器设计与验证[J].物联网技术,2015,5(6):6-8.

[7]潘军.基于ZigBee的无线传感器网络的研究与应用[D].大连:大连海事大学,2012.

[8]宋国青. ZigBee自动抄表系统的研究与实现[D].桂林:桂林电子科技大学,2010.endprint

猜你喜欢
技术支持
AR技术支持下部编版教材的教与学
提升技术支持能力, 深化“林肯之道”
博格华纳致力于创造清洁高效的世界, 为汽车驱动系统提供先进的技术支持
多种现代技术支持的第二语言学习
Web3.0技术支持下的幼儿园智能化教学探究
精准扶贫需要技术支持
信息技术推动学习方式转变——技术支持的课堂导入
技术支持下的历史学科探究任务设计
iPad技术支持下的翻转课堂模式探索*——暨“分式方程”的翻转课例展示
为Windows 7让路 微软开始淘汰Windows XP