Z-Stack Home Developer's Guide—2. Overview中文翻译【Z-Stack Home 1.2.0开发文档】

下面是Z-Stack Home 1.2.0开发资料中的Z-Stack Home Developer’s Guide—2. Overview的中文翻译

2.1 简介

这章节将介绍 Z-Stack协议栈的示例程序。 每一个Z-Stack协议栈的示例程序都是为了实现一个特定的应用程序 使用zigbee协议栈可以非常简单的开始。

这个章节将作为一个通用的概述。 需要一个动手的用户指南, 请参阅Z-Stack Home Sample Application User’s Guide [3]。

每个样本应用程序都使用ZDO公共接口的最小子集,以使设备在ZigBee网络中具有相当的可行性。 另外, 所有的样例程序都利用基本的OSAL API 函数: 网络和内部任务之间的交流, 通过发送和接受消息, 设置和接受任务事件, 设置和接受定时器回调, 使用动态内存, 以及其他的。 除此之外, 每个示例程序会使用HAL API 函数, 例如。 为了控制 LED’s。 因此, 任何样例应用程序都是复制和粘贴的一个很好的例子, 或者作为用户应用程序的基本代码 可以添加额外的应用程序对象。

任何应用程序对象都一定是位于唯一端点的顶部; 任何端点都是由一个简单的描述符定义的。
示例应用程序中的简单描述符中用于端点的数字可以任意选择的。

每个示例应用程序实例化一个应用程序对象, 因此, 仅支持相应的Profile。 但是请注意,2个或者更多的应用程序对象可以在相同的设备上实例化。 当在同一个设备中实例化多个应用程序对象时,每个应用程序对象必须实现一个唯一的Profile Id,并在顶部设置唯一的端点编号。 示例应用程序满足唯一Id和端点编号需求并且能组成到一个设备中只要比较小的修改。

以下段落描述了OSAL 任务:

2.1.1 Initialization

OSAL是有意的作为分配源,这样通过Z-Stack用户整个OSAL的功能就可以被修改了。
设计的目标是为使用Z-Stack as distributed修改OSAL并不是必须的。 有一个除外—OSAL Task 初始化函数, osalInitTasks(), 一定要被用户实现。 示例程序在专用的文件中已经实现, 名字的命名规则: OSAL_”Application Name”.c (比如 OSAL_SampleLight.c)。 BSP将调用osalInitTasks()函数 作为开发板上电的一部分和Z-Stack初始化过程。

2.1.2 Organization

详细的描述在 Z-Stack OSAL API [5] 文档中, OSAL实现了一个合作, 循环任务服务循环。每一个Z-Stack主子系统运行作为一个OSAL任务。 用户运行的应用程序必须创建至少一个OSAL任务。 添加他们的任务到任务数组[tasksArr 定义在 OSAL_”Application Name”.c] 文件中,调用他们的应用程序的初始化函数在osalInitTask()中。
样例程序很清晰的展示了用户如何添加一个任务到OSAL系统中。

2.1.3 Task Priority

这些任务执行的顺序是根据他们在任务数组中的位置[tasksArr in OSAL_”Application Name”.c]。 任务数组的第一个任务拥有最高优先级。

2.1.4 System Services

OSAL 和 HAL 系统服务 是 键盘 (按下开关) 通知 和 串口活动通知。系统服务是专一的, 也就是说,每一个都可以被注册为一个单一的OSAL任务。 不同的系统服务可以通过相同的OSAL任务注册, 或者不同的OSAL 任务。 默认,任何的系统服务都没有注册Z-Stack任务 – 他们都是留给用户自己注册。

2.1.5 Application Design

用户可以一个应用程序实例创建一个任务也可以所有的应用程序实例创建一个任务。 以下是在进行上述设计选择时的一些考虑事项。

2.1.5.1 One OSAL Task per many Application Objects

以下是一个任务对应多个App实例的优点和缺点:
优点: 在接收单一的任务事件(开关或串行端口)时所采取的操作被简化了。
优点: 许多OSAL任务结构所需的堆空间被保存
缺点: 当接收到传入的AF消息或AF数据确认时所采取的操作是复杂的。
– 多路复用的负担是在单个用户任务上的。
缺点: 匹配描述符请求(即自动匹配)的服务发现过程更加复杂
–必须维护一个静态的本地标志,以便在ZDO_NEW_DSTADDR消息时正确地执行

2.1.5.2 One OSAL Task per one Application Object

这个一个task对应一个App对象的优缺点刚好和上面的一个task对应许多的App对象相反:

  • 优点: 传入的AF消息或AF数据确认已经取消多路复用靠协议栈的底层, 因此接收应用程序对象是预期接收方。
  • 缺点: 许多OSAL任务结构所需的堆空间发生了
  • 缺点: 如果两个或更多应用程序对象使用相同的独占资源时,当接收到一个单独的任务事件时所采取的操作可能会更加复杂。

2.1.6 Mandatory Methods

任何的OSAL任务都必须实现2个方法:一个是任务初始化函数另一个是处理任务事件的函数。

2.1.6.1 Task Initialization

在样例程序中,任务初始化的函数命名规则:zcl“Application Name”_Init (比如 zclSampleLight_Init())。任务初始化函数应该完成以下:

  • 初始化本地变量或相应的应用程序对象。 任何长期在堆内存的变量应该在这里分配空间,为了让OSAL更高效的管理堆空间。
  • 通过在AF层注册来实例化相应的应用程序对象(比如 afRegister())。
  • 使用可适用的OSAL或HAL系统服务注册 (比如 RegisterForKeys())。

2.1.6.2 Task Event Handler

在示例程序中,事件处理函数的命名规则:zcl“Application Name”_event_loop (比如 zclSampleLight_event_loop())。任何OSAL任务都可以除了强制性事件之外,还可以定义15个事件。

2.1.7 Mandatory Events

一个任务事件,SYS_EVENT_MSG (0x8000),被保留,是OSAL 任务设计的。

2.1.7.1 SYS_EVENT_MSG (0x8000)

全局的系统消息发送通过SYS_EVENT_MSG,具体指定在ZComDef.h文件中。任务事件处理程序应该处理以下这些全局系统消息的最小子集。建议处理以下消息应该直接从样例程序代码学习或者研究样例程序的程序流程。

2.1.7.1.1 AF_DATA_CONFIRM_CMD

这表明 每个over-the-air数据请求成功,通过调用AF_DataRequest()。ZSuccess确认数据请求成功地通过无线传输。数据请求是用AF_ACK_REQUEST标志设置的,然后ZSuccess确认消息是在最终目的地成功接收。否则,ZSuccess只会确认消息是成功地传送到下一站。

2.1.7.1.2 AF_INCOMING_MSG_CMD

这是一个传入的AF消息的指示

2.1.7.1.3 KEY_CHANGE

表明有按键活动

2.1.7.1.4 ZDO_STATE_CHANGE

表明网络状态发生改变

2.1.7.1.5 ZDO_CB_MSG

这是发送到示例应用程序的每一个注册的ZDO响应消息[ZDO_RegisterForZDOMsg]

2.2 Network Formation

作为一个协调器编译的样例应用程序将在一个通道上形成一个网络,通过指定DEFAULT_CHANLIST。协调器将建立一个随机的Pan ID基于自己的own IEEE地址或者通过ZDAPP_CONFIG_PAN_ID,如果它没有定义为0xFFFF。作为路由器或终端编译的样例应用程序设备将尝试在DEFAULT_CHANLIST指定的一个通道上加入一个网络。路由器将被限制只加入Pan ID定义。注意,获得的结果是不确定的,由于 当ZDAPP_CONFIG_PAN_ID没有定义为0xFFFF,协调器和路由或终端设备 之间的行为是不同的。如果ZDAPP_CONFIG_PAN_ID定义为一个有效的值小于等于0xFFFE,那么协调器只会尝试建立一个带指定Pan ID的网络。因此,如果协调器被限制为一个通道,指定的Pan Id已经在该通道上建立了,新开始的协调员将会连续的变化,直到它达到一个惟一的Pan Id。新加入的路由器或终端设备将无法知道建立PanID的值,因此只会加入指定的Pan Id。同样具有挑战性的场景出现在 当允许的信道掩码允许多个通道,协调器不能使用第一个通道由于Pan ID冲突 — 路由器或终端设备将加入指定的Pan ID 在第一个channel 被scan,如果被允许的话。

2.2.1 Auto Start

一个设备将自动开始尝试形成或加入一个网络作为BSP 启动序列的一部分。如果在连接之前,设备应该等待计时器或其他外部事件,HOLD_AUTO_START一定要被定义。为了在以后的时间手动启动连接过程,调用ZDOInitDevice()。

2.2.2 Network Restore

成功加入网络的设备可以“恢复网络”(而不是重置通过OTA信息)即使在失去电源或电池之后。这种自动恢复可以通过定义NV_RESTORE或NV_INIT实现。

2.2.3 Join Notification

该设备被告知网络形成或连接(或网络状态的任何变化)的状态,通过前面提到的ZDO_STATE_CHANGE消息。

2.3 Common Application Framework / Program Flow

本节描述所有样本应用程序通用的初始化和主任务处理概念。在 转到样例程序之前,应该先阅读本部分内容。对于本节中的代码示例,我们将使用SampleLightApp,在 Z-Stack Home已经提供了。

2.3.1 Initialization

在系统启动和初始化期间,任务的初始化函数将被调用。这个函数的结构如下所示,加上一些代码示例:

zclSampleLight_TaskID = task_id;
任务ID由OSAL分配,并通过任务的init函数的参数赋予任务。应用程序必须记住这个任务id,因为它会在以后进行自我触发 通过使用OSAL定时器,事件,消息(比如 当任务给它自己发送一个消息)。这种自我触发通常是将长时间处理分割成更小的块,然后在他们之间延期调用。这种“合作”行为允许其他任务共享CPU时间并防止“饥饿”.

zclHA_Init( & zclSampleLight_SimpleDesc );
这个SampleLightApp程序对象实例化通过上面的代码,这允许Af层知道如何路由到目标profile/endpoint的数据包 — 它将通过发送一个OSAL SYS_EVENT_MSG 消息(AF_INCOMING_MSG_CMD)到任务来做到这一点。

RegisterForKeys( zclSampleLight_TaskID );
示例程序用上面的代码注册 按键通知的系统服务。

2.3.2 Event Processing

当样例应用程序发生OSAL事件时,事件处理函数,将从OSAL任务处理循环中调用。任务事件处理程序的参数是一个16位位掩码;在任何对函数的调用中都可以设置一个或多个位。如果设置了多个事件,那么它强烈建议一个任务只对其中一个事件采取行动(可能最关键的一个,几乎总是,SYS_EVENT_MSG时优先级最高的一个)。未处理的事件将导致新的调用这个任务事件处理程序在所有其他处理程序之后都有机会处理它们的事件。

if ( events & SYS_EVENT_MSG )
{
MSGpkt = (afIncomingMSGPacket_t*)osal_msg_receive(zclSampleLight_TaskID );
while ( MSGpkt )
{

请注意,尽管建议一个任务只在可能的多个未决事件中的一个上执行任务处理功能的调用,它也被推荐(并在示例应用程序中实现)处理所有可能出现的SYS_EVENT_MSG消息,所有这些消息都位于OSAL的“时间片”中。

switch ( MSGpkt->hdr。event )
建议一个任务实现SYS_EVENT_MSG消息可能类型的最小子集,这个推荐的子集如下所述:
case KEY_CHANGE:
zclSampleLight_HandleKeys ( ((keyChange_t *)MSGpkt)->state,
((keyChange_t *)MSGpkt)->keys );
break;

如果一个OSAL任务已经注册了按键通知,所有的按键将受到一个 KEY_CHANGE系统事件消息。程序流程有两种可能的路径,它会导致一个任务接收到这个KEY_CHANGE消息。
从物理按键上产生的程序流如下所列:

  • HAL发现了按键状态(通过H/W中断或者 H/W轮休 )
  • HAL 的OSAL任务发现了 按键状态改变然后调用 OSAL 按键改变的回调函数。
  • OSAL 按键改变回调函数将发送 OSAL 系统事件消息(KEY_CHANGE)到这个注册 接受key change event(RegisterForKeys)通知 的Task ID。

case AF_DATA_CONFIRM_CMD:
// The status is of ZStatus_t type [defined in ZComDef.h]
// The message fields are defined in AF.h
afDataConfirm = (afDataConfirm_t *)MSGpkt;
sentEP = afDataConfirm->endpoint;
sentStatus = afDataConfirm->hdr。status;
sentTransID = afDataConfirm->transID;

任何对AF_DataRequest()的调用都会返回ZSuccess,这将导致“回调”
AF_DATA_CONFIRM_CMD系统事件消息。

发送的事务Id(sentTransID)是识别消息的一种方法。尽管示例应用程序只会使用单个事务Id计数器,为每个不同的短点保留一个单独的Transaction Id计数器可能是有用的 或者 即使是为了消息确认,端点中的每个集群ID也是如此,重试,拆开,在组装,等。注意任何事务ID状态变量(counter)通过调用AF_DataRequest()增长当这个函数调用成功(因此,它是一个传入参数 通过引用,而不是值传递)。

AF_DataRequest()的返回值是ZSuccess表示,这条信息已经被网络层接受,网络层试图将它发送到Mac层,Mac试图将通过OTA发送。

发送的状态(句子状态)是OTA这个消息的结果。ZSuccess表示 消息被传送到网络中下一跳的ZigBee设备。如果AF_DataRequest() 调用使用AF_ACK_REQUEST标志,然后ZSuccess表示消息被递送到目标地址。除非消息的寻址模式是间接的(比如 消息被发送到网络反射器来执行
绑定表格查找并将消息重新发送到匹配设备),在这种情况下,ZSuccess表示消息被传送到网络反射器。有几种可能的发送状态值表示失败。

case ZDO_STATE_CHANGE:
zclSampleLight_NwkState = (devStates_t)(MSGpkt->hdr。status);
if ( (zclSampleLight_NwkState == DEV_ZB_COORD) ||
(zclSampleLight_NwkState == DEV_ROUTER) ||
(zclSampleLight_NwkState == DEV_END_DEVICE) )
{
giLightScreenMode = LIGHT_MAINMODE;
。。。
}
break;

每当网络状态发生变化时,所有任务都会被通知系统事件消息ZDO_STATE_CHANGE

// Release the memory
osal_msg_deallocate( (uint8 *)MSGpkt );

请注意,OSAL消息系统的设计要求任务接受者释放 为消息分配的内存。

任务的事件处理函数应该尝试获取下一个未决的SYS_EVENT_MSG消息:
// Get the next message
MSGpkt = (afIncomingMSGPacket_t*)osal_msg_receive(zclSampleLight_TaskID);
}

处理完一个事件后,处理函数应该返回未处理的事件,比如 在处理完SYS_EVENT_MSG事件后,应该返回以下内容:

// Return unprocessed events
return ( events ^ SYS_EVENT_MSG);
}

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值