【转】TI Z-stack协议栈学习-添加新任务

开始学习TI的zigbee协议栈,无线龙的资料看得比较乱,在网络找到不少分析协议栈的文章,先贴上来,等自己有空了再好好原创一下吧。

协议栈版本:ZStack-1.4.3-1.2.1

TI Z-stack协议栈学习-添加新任务

1.Zstack中如何实现自己的任务 http://zhenling.chen.blog.163.com/blog/static/1940851920097710392587/

在Zstack(TI的Zigbee协议栈)中,对于每个用户自己新建立的任务通常需要两个相关的处理函数,包括:

(1).用于初始化的函数,如:SampleApp_Init(), 这个函数是在osalInitTasks()这个osal(Zstack中自带的小操作系统)中去调用的,其目的就是把一些用户自己写的任务中的一些变量,网络模式,网络终端类型等进行初始化;

(2).用于引起该任务状态变化的事件发生后所需要执行的事件处理函数,如:

SampleApp_ProcessEvent(),这个函数是首先在const pTaskEventHandlerFn tasksArr[ ] 中进行设置(绑定),然后在osalInitTasks()中如果发生事件进行调用绑定的事件处理函数.

下面分3个部分分析.

1.用户自己设计的任务代码在Zstack中的调用过程

(1).main() 执行(在ZMain.c中)

main() ---> osal_init_system()

(2). osal_init_system()调用osalInitTasks(), (在OSAL.c中)

osal_init_system() ---> osalInitTasks()

(3). osalInitTasks()调用SampleApp_Init() , (在OSAL_SampleApp.c中)

osalInitTasks() ---> SampleApp_Init()

在osalInitTasks()中实现了多个任务初始化的设置,其中macTaskInit( taskID++ )到ZDApp_Init( taskID++ )的几行代码表示对于几个系统运行初始化任务的调用,而用户自己实现的SampleApp_Init()在最后,这里taskID随着任务的增加也随之递增.所以用户自己实现的任务的初始化操作应该在osalInitTasks()中增加.

void osalInitTasks( void )

{

uint8 taskID = 0;

//这里很重要, 调用osal_mem_alloc()为当前OSAL中的各任务分配存储空间(实际上是一个任//务数组),并用tasksEvents指向该任务数组(任务队列).

tasksEvents = (uint16 *)osal_mem_alloc( sizeof( uint16 ) * tasksCnt);

osal_memset( tasksEvents, 0, (sizeof( uint16 ) * tasksCnt)); //将taskSEvents所指向的空间清零

macTaskInit( taskID++ );

nwk_init( taskID++ );

Hal_Init( taskID++ );

#if defined( MT_TASK )

MT_TaskInit( taskID++ );

#endif

APS_Init( taskID++ );

ZDApp_Init( taskID++ );

SampleApp_Init( taskID ); //用户自己需要添加的任务

}

2.任务处理调用的重要数据结构

这里要解释一下,在Zstack里,对于同一个任务可能有多种事件发生,那么需要执行不同的事件处理,为了方便,对于每个任务的事件处理函数都统一在一个事件处理函数中实现,然后根据任务的ID号(task_id)和该任务的具体事件(events)调用某个任务的事件处理函数,进入了该任务的事件处理函数之后,再根据events再来判别是该任务的哪一种事件发生,进而执行相应的事件处理.pTaskEventHandlerFn 是一个指向函数(事件处理函数)的指针,这里实现的每一个数组元素各对应于一个任务的事件处理函数,比如SampleApp_ProcessEvent对于用户自行实现的事件处理函数uint16 SampleApp_ProcessEvent( uint8 task_id, uint16 events ),所以这里如果我们实现了一个任务,还需要把实现的该任务的事件处理函数在这里添加.

const pTaskEventHandlerFn tasksArr[] = {

macEventLoop,

nwk_event_loop,

Hal_ProcessEvent,

#if defined( MT_TASK )    //一个MT任务命令

MT_ProcessEvent,

#endif

APS_event_loop,

ZDApp_event_loop,

SampleApp_ProcessEvent

};

注意, tasksEvents和tasksArr[]里的顺序是一一对应的, tasksArr[]中的第i个事件处理函数对应于tasksEvents中的第i个任务的事件.

//计算出任务的数量

const uint8 tasksCnt = sizeof( tasksArr ) / sizeof( tasksArr[0] );

uint16 *tasksEvents;

3. 对于不同事件发生后的任务处理函数的调用

osal_start_system() 很重要,决定了当某个任务的事件发生后调用对应的事件处理函数

void osal_start_system(void)

{

#if !defined ( ZBIT )

for(;;) // Forever Loop

#endif

{

uint8 idx = 0;

Hal_ProcessPoll(); // This replaces MT_SerialPoll() and osal_check_timer().

//这里是轮训任务队列,并检查是否有某个任务的事件发生

do {

if (tasksEvents[idx]) // Task is highest priority that is ready.

{

break;

}

} while (++idx < tasksCnt);

if (idx < tasksCnt)

{

uint16 events;

halIntState_t intState;

HAL_ENTER_CRITICAL_SECTION(intState);

events = tasksEvents[idx];   //处理该idx的任务事件, 是第idx个任务的事件发生了

tasksEvents[idx] = 0; // Clear the Events for this task.

HAL_EXIT_CRITICAL_SECTION(intState);

//对应调用第idx个任务的事件处理函数,用events说明是什么事件

events = (tasksArr[idx])( idx, events );

//当没有处理完,把返回的events继续放到tasksEvents[idx]当中

HAL_ENTER_CRITICAL_SECTION(intState);

tasksEvents[idx] |= events; // Add back unprocessed events to the current task.

HAL_EXIT_CRITICAL_SECTION(intState);

}

#if defined( POWER_SAVING )

else // Complete pass through all task events with no activity?

{

osal_pwrmgr_powerconserve(); // Put the processor/system into sleep

}

#endif

}

}

=========================================================================

2.Z-stack添加一个新的任务 http://www.wyouxi.com/index.php/group_thread/view/id-8583

在osalInitTasks()和tasksArr[]添加相应的项就可以了。 1.修改osalInitTasks()void osalInitTasks( void ){……OuhsApp_Init( taskID++ ); PhotoApp_Init( taskID); } 2.修改tasksArr[]const pTaskEventHa ...

在osalInitTasks()和tasksArr[]添加相应的项就可以了。

1.修改osalInitTasks()

void osalInitTasks( void )

{

……

OuhsApp_Init( taskID++ );

PhotoApp_Init( taskID);

}

2.修改tasksArr[]

const pTaskEventHandlerFn tasksArr[] = {

……

OuhsApp_ProcessEvent

PhotoApp_ProcessEvent

};

3.添加_Init()和_ProcessEvent()

void PhotoApp_Init( uint8 task_id )

{

PhotoApp_TaskID = task_id;

PhotoInit();

RegisterForPhoto( PhotoApp_TaskID );

}

uint16 PhotoApp_ProcessEvent( uint8 task_id uint16 events )

{

afIncomingMSGPacket_t *MSGpkt;

if ( events &SYS_EVENT_MSG )

{

MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( PhotoApp_TaskID );

while ( MSGpkt )

{

switch ( MSGpkt->hdr.event )

{

case PHOTO_CHANGE:

HalLedblink( HAL_LED_1 3 30 300 );

//P0IE = 1;

break;

}

// Release the memory

osal_msg_deallocate( (uint8 *)MSGpkt );

// Next - if one is available

MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( PhotoApp_TaskID );

}

// return unprocessed events

return (events ^ SYS_EVENT_MSG);

}

// Discard unknown events

return 0;

}

时间: 2024-10-13 11:45:22

【转】TI Z-stack协议栈学习-添加新任务的相关文章

Zigbee Z‐STACK协议栈和TinyOS

ZigBee 和 Tinyos 关于ZigBee和TinyOS ZigBee的基础是IEEE 802.15.4.但IEEE仅处理低级MAC层和物理层协议,因此Zigbee联盟扩展了IEEE,对其网络层协议和API进行了标准化,这就是Z‐STACK,Z‐STACK协议栈是TI公司研发,通过ZigBee联盟认证的免费协议栈,协议内部包括了WSN(无线传感器网络)的OS的模型,协议栈具有国际化,标准化的特点,协议栈已提供十几种应用场景,可以非常轻松的让用户开发出满足国际标准的产品. TinyOS是一个

linux学习(一) 在unbuntu下添加新用户

最近装了一个双系统,开始要折腾unbuntu了,Linux系统是一个多用户的操作系统,很多操作需要管理员权限才能完成,所有管理员权限是很重要的,对于初学者来说,我们最好用一个一般用户的权限就行了,相对于初学者的我们,对于很多东西还不懂,如果用了一个管理员权限,很可能造成很多不可逆的影响.遂捣鼓了一番,添加一个标准用户来供我们学习的一般需求. 第一步,我们打开系统设置:找到里面的用户账户选项: 第二步:对当前的用户进行解锁: 第三步:解锁之后我们就可以添加新用户了: 第四步:我们就可以创建新用户啦

存储学习之--StarWind高级配置(添加新的存储和扩展SIZE)

存储学习之--StarWind高级配置(添加新的存储和扩展SIZE)     在配置完StarWind的存储后,可以按照需求来增加或扩展共享存储设备的容量,以下是具体的操作步骤.  一.添加新的存储(New Target) 选择添加新的target 命名新的target 选择存储设备类型 选择虚拟的方式 以镜像方式添加 建立镜像文件和指定Size 设置共享存储属性,支持Cluster 设置Cache大小 完成创建 创建成功 查看新的存储属性 二.扩展存储的尺寸 选择扩展Size 指定扩展后的Si

学习ASP.NET Core Razor 编程系列十——添加新字段

学习ASP.NET Core Razor 编程系列目录 学习ASP.NET Core Razor 编程系列一 学习ASP.NET Core Razor 编程系列二——添加一个实体 学习ASP.NET Core Razor 编程系列三——创建数据表及创建项目基本页面 学习ASP.NET Core Razor 编程系列四——Asp.Net Core Razor列表模板页面 学习ASP.NET Core Razor 编程系列五——Asp.Net Core Razor新建模板页面 学习ASP.NET C

一个新人如何学习在大型系统中添加新功能和Debug

文章背景: 今年七月份正式入职,公司主营ERP软件,楼主所在的组主要负责二次开发,使用的语言是Java. 什么叫二次开发呢?ERP软件的客户都是企业.而这些企业之间的情况都有所不同,一套标准版本的企业资源管理系统必然难以百分之一百地满足每一家公司的所有要求.所以,在客户提出需求之后,程序员对系统进行增减修改,这就是二次开发. 另外,我们组还负责修复客户报上来的各种漏洞. 学会如何添加新模块新功能 为什么说从头到尾只看代码是不可行的? 基本上,财务系统跨越的年限都会有十几二十年,代码数千万级别,更

Django学习(七)---添加新文章页面

在template中添加add_article.html页面 (form  input)请求方法使用post 这个页面涉及到了两个响应函数 1)显示页面的响应函数  2)表单提交的响应函数 add_article.html如下: <!DOCTYPE html> <html> <head> <title>增加新文章</title> </head> <body> <form action="{% url 'bl

ECC协议栈学习总结

            ECC协议栈学习总结 目录 1 前言    3 2  ECC通讯原理... 3 2.1   ECC通讯模型... 3 2.2   ECC通讯实现... 5 2.2.1 物理层实现..................................................................................................... .5 2.2.2 数据链路层实现...............................

C# Stack 集合学习

Stack 集合学习 学习自:博客园相关文章 Stack<T>集合 这个集合的特点为:后进先出,简单来说就是新元素都放到第一位,而且顺序移除元素也是从第一位开始的. 方法一:Push(T value); 添加一个元素到集合顶部位置. 方法二:Pop(); 添加一个元素到集合顶部位置. 方法三:Peek(); 添加一个元素到集合顶部位置. Stack<string> sTest=new Stack<string>(); sTest.Push("D");

37个实用网站—学习实用新知识

原文链接:https://entrepreneurs.maqtoob.com/the-37-best-websites-to-learn-something-new-895e2cb0cad4#.5jkbivynw 作者:Kristyna Z. CEO@maqtoob| Entrepreneur Coach | More: kristyna.co 学费昂贵,整日在拥挤的教室中,令人心碎的可怜成绩,还记得自己在学校痛苦的学习生活吗?忘掉他们吧!以下的网站及APP涵盖科学.艺术及科技专题. 它们会教会