Ember 应用框架是一个嵌入式 C 代码体,可以通过 Ember AppBuilder 来配置它,以实现任何 ZCL(ZigBee Cluster Library)应用。本指南涵盖了 Ember 应用框架的结构和用法。在适当的情况下,我们添加了一些信息来概括最新版本的 Ember 应用框架与先前版本之间的差异。
增加第 18 章。
Ember AF(application framework,应用框架)是一个嵌入式 C 代码体,可以通过 Ember AppBuilder 来配置它,以实现任何 ZCL 应用。该 AF 位于 app/framework
目录中。
本指南涵盖了 Ember AF 的结构和用法。在适当的情况下,我们添加了一些信息来概括最新版本的 Ember AF 与先前版本之间的差异。
使用 Ember AF,只需通过几个步骤就能创建一个应用。
- 使用 Ember AppBuilder 创建 Ember AF 配置文件。该配置文件及所选平台的项目文件由 Ember AppBuilder 生成。本手册的第 17 章概括了 Ember AppBuilder 的使用及其与 Ember AF 的关联。有关如何使用 Ember AppBuilder 的更多详细信息,请参阅 Ember AppBuilder 的 Help 菜单(
Help | Help Contents for indexed help and Help | Dynamic Help for context-sensitive help
)。 - 将应用的细节写入到随配置文件一起生成的回调函数中。使用 Ember AF API 可以做一些事(如在 ZigBee 网络上,与 attribute 交互;发送、接收和响应 command)。有关 Ember AF API 的更多详细信息,请参阅 5. AF API。
- 将生成的项目文件打开到所选芯片的 IDE 中,编译应用,然后将其加载到开发套件上。
- 运行应用并使用 Ember Desktop 控制台窗口和应用 CLI(command line interface,命令行接口)与其进行交互。有关如何使用 Ember Desktop 的更多信息,请参阅 Ember Desktop 的在线帮助(
Help | Help Contents
)。
有关移植过程的信息,请参阅 stack release 中包含的 Ember Application Framework Release Notes (document number 120-8098-000A)。
Ember AF 在 Ember stack 上使用 stack "handler" 接口,并向开发者公开其自身更抽象的和应用特定的接口。
Ember AF 的主要特性之一是将用户创建的代码和 Silicon Labs 创建的代码分离。虽然 Silicon Labs 提供了 Ember AF 的所有源代码,但是用户应该在该框架外创建代码,并且应该通过框架公开的实用程序(utility)和回调(callback)与框架进行交互。Figure 1 展示了 Ember AF 架构的概览及两个代码库的分离。
app/framework/util
中包含的 main
文件使用 Ember Stack handler 接口,并将 Ember AF 结合到 EmberZNet PRO stack 中。两个 main
文件位于 app/framework/util
目录中,af-main-soc.c
用于 SoC(如 EM35xx 平台)和 af-main-host.c
用于与 NCP(Network Co-Processor,网络协处理器)搭配的 host 微处理器。
main
文件执行 emberIncomingMessageHandler()
,并将所有传入消息传递给 Ember AF 以进行 command 处理。一旦传入消息被处理,它们将被传递到对应的 cluster 以进行处理,或者直接传递给 cluster-specific 回调(由 Ember AppBuilder 生成)。Command
处理代码的重要(significant)部分直接由 tool/appbuilder
中包含的 ZCL XML 文档生成。
从 ZCL XML 文档生成的所有代码和头文件与应用头文件和回调文件一起被生成到 app/builder/<application name>/
中。
tool/appbuilder
:Ember AppBuilder 使用的配置和模板文件。
当您在 stack installation 中指向 Ember AppBuilder 时,它会查看此目录以加载该 stack 版本的当前 ZCL 实现的 XML 描述。
请将您的custom cluster
的.XML
文件放置在此位置。有关创建custom cluster
的详细信息,请参阅 Ember AppBuilder Help(Help | Help Contents | Creating custom clusters
)。app/framework
:Ember AF 的所有代码都位于app/framework
中。代码的主要部分已被分解到各自的目录中。app/framework/cli
:与 AF 的 CLI 实现相关的代码。
CLI 的核心代码包含在app/util/serial/command-interpreter2.c
中。CLI 包含数据类型检查和命令用法反馈等。作为结果:- 所有命令都需要与该命令关联的所有参数。如果缺少参数,CLI 将提供有关特定命令用法的用户反馈。
- 传递给 CLI 的参数必须采用以下格式之一:
<int>
: 123(decimal) or 0x1ABC(hex)<string>
: "foo"(string) or {0A 1B 2C}(array of bytes)
app/builder
:由 Ember AppBuilder 生成的所有文件的输出位置。
当您在 Ember AppBuilder 中生成应用时,它会将生成的文件放在此目录下的其中一个目录中(目录名与 Ember AppBuilder 配置中的设备名相同)。例如,如果您的设备名为MyLightSwitch
,则文件将生成到app/builder/MyLightSwitch/
中。在 Ember AppBuilder 中打开示例应用时也是如此,Ember AppBuilder 将会自动地将示例应用文件复制到app/builder
下的相关目录中。app/framework/include
:Ember AF 的所有外部 API。
此目录镜像了 stack 中include
目录的使用。它是所有预期的外部应用接口的单一位置。app/framework/plugin
:Silicon Labs 创建的所有ZCL cluster
代码。
该目录包含所有 Silicon Labs 团队为处理 cluster command 而创建的 cluster 代码。通过从 Ember AppBuilder 的 “plugin” 选项卡中选择插件,可选地将这些代码包含在应用中。如果您选择不包含插件,则您需要负责为所有必需的 cluster command 实现回调。app/framework/scenarios
:所有使用 AF 的示例应用场景(scenario)。
这些示例场景可以在 Ember AppBuilder 中打开(by choosingFile | New | Application Configuration
, selecting a framework and stack combination, and then choosing “Start from a selected sample application.” Ember AppBuilder requests a new application name for the given scenario instance and copies the sample callback code into a directory of the same name withinapp/builder
.)。app/framework/security
:所有与 ZigBee 安全相关的实用程序代码。
与密钥建立相关的代码位于app/framework/cluster
中。app/framework/util
:应用的main
、消息处理以及 Ember AF 使用的任何其他实用程序代码。
该目录包含 Ember AF 的核心(gut)。管理多 endpoint 支持的 attribute 的 attribute 存储文件包含在此目录中。此外,用于访问、读取和写入 attribute 的 API 包含在文件attribute-table.h
和attribute-storage.h
中。
Ember AFV1(Version 1)使用单个头文件来配置 Ember AF、设置 attribute table、并通过预处理器指令打开和关闭部分代码。AFV2(Version 2)使用相同的预处理程序指令来配置框架中的代码。除主要的应用头文件外,Ember AppBuilder 还会生成一个带有后缀 endpoint_configuration.h
的 “endpoint configuration” 头文件。
-
<DeviceName>_endpoint_configuration.h
生成的文件,用于配置 Ember AF 的静态数据结构。这允许跨 endpoint 共享 attribute 元数据,并且每个 endpoint 都有各自用于 attribute 存储的空间。app/framework/util/attribute-storage.c
文件使用endpoint_configuration.h
文件中的#define
配置所有应用的 attribute-related 数据。
每次在 Ember AppBuilder 中修改应用配置时,都必须重新生成该文件。Silicon Labs 建议您不要手工编辑endpoint_configuration.h
文件,因为文件中的每个宏定义都具有一个复杂的关系。
9.1 ZCL Attribute 配置 中更详细地描述了 endpoint 配置文件的作用。 -
<DeviceName>.h
应用的主要头文件。它包含了在框架中打开所需特性的所有#define
。 -
<DeviceName>_callbacks.c
生成的存根回调(stub callback)文件,包含您选择要包含在项目中的所有回调的默认实现。您可以在此处编写您的代码。如果要将其他文件添加到生成的项目文件中,则需要包含其他文件以便编译器可以找到它们。 -
<DeviceName>_board.h
为所选平台生成的板(board)文件。此文件假定您使用的是其中一块 Ember 开发板。它根据 “HAL configuration” 选项卡中所做的选择进行配置。注意:板头文件包含许多选项,这些选项可以根据您的需求配置各种 GPIO。Silicon Labs 建议您查看生成的
<DeviceName>_board.h
文件,并根据需求对目标硬件进行更改。 -
<DeviceName>_tokens.h
如果要在平台(支持 token)的 token(persistent memory)中包含任何 attribute,则此文件将通过 Ember AppBuilder 生成,以配置 token 存储。 -
<DeviceName>.ewp, eww, .xip, .xiw, .mak
为您的应用生成的项目文件。Ember AppBuilder 仅生成与您所选的平台相匹配的项目文件。这些文件可以加载到 IDE 中并进行编辑,以构建项目的其余部分。
从 EmberZNet PRO 4.6 起,Ember AF 和 Ember AppBuilder 已修改为将所有静态的 Ember AF 文件生成到应用构建目录中。在之前的版本中,这些文件的单个版本生成到 app/framework/gen
目录中;从 EmberZNet PRO 4.6 起,此目录已被移除,用以代替的是将所有这些文件生成到 app/builder/<application name>
目录中。这样做是为了支持来自单个 stack 的多个规范版本。生成的文件不再是静态的,它们的内容根据用户在 “Stack” 选项卡中选择的 ZigBee 规范版本而改变。
生成的文件数量根据支持的插件及这些插件所需的内容而异。生成的 Ember AF 文件包括但不限于以下内容:
af-structs.h
:结构的定义,被 Ember AF 用于解析 ota(over the air)发送的数据。att-storage.h
:Ember AF 内的 attribute 存储机制中使用的定义。attribute-id.h
:所有由 ZCL 规范定义的 attribute id,用来加载到 Ember AF 内的所有 profile 中。attribute-size.h
:ZCL 规范中使用的 attribute 类型的大小(以字节为单位)。attribute-type.h
:定义在 ZCL 规范中用于表示数据类型的 ota 值。call-command-handler.c
:通过 ota 接收的所有 non-general command 的 command 处理代码。该生成的代码将 cluster command 从它们的 ota 格式到回调接口。如果没有实现相应的回调,处理代码也会处理这些 command。call-command-handler.h
:call-command-handler.c
的头文件。该文件提供了所有在call-command-handler.c
中实现的函数的定义。callback-stub.c
:提供由 Ember AF 实现的用户回调的存根。只有在用户的应用中未单独定义回调时,才会编译该回调的存根。callback.h
:提供所有可能在 Ember AF 或用户应用中实现的回调的定义。这定义了 ENTIRE 回调接口,Ember AF 主要使用该接口与用户应用交互。cli.h
:此文件仅被文档引擎 doxygen 使用,以记录通用应用框架的 CLI 命令,它没有其他用途。client-command-macro.h
:宏,作为 Ember AF 接口的一部分,用于填充将 ota 发送的包缓冲区。在这里,用户应用配置中配置的 ZCL 支持的每个 command 都用一个宏表示,该宏将对 Ember AF 进行适当的调用,以填充包缓冲区,以便 ota 发送该 command。cluster-id.h
:为从 ZCL 加载到 Ember AF 中的所有 cluster id 提供了定义。command-id.h
:为从 ZCL 加载到 Ember AF 中的所有 command id 提供了定义。debug-printing-test.h
:用于在 Ember AF 中打开调试打印的定义。debug-printing.h
:用于在 Ember AF 中进行调试打印的宏。enums.h
:提供 Ember AF 中使用的所有 ZCL 相关的枚举定义。print-cluster.h
:用于在 Ember AF 内的每个 cluster 上打开打印的定义。stack-handler-stub.c
:所有 stack 处理程序的存根,可在 Ember AF 中覆写(overridden)。stack-handlers.h
:定义可供用户应用覆写的所有 stack 处理函数。<plugin>-callbacks.h
:所有插件回调函数的声明。这些文件的生成取决于为您的应用选择的插件。
Ember AF 的 API 在 app/framework/include/af.h
中提供。此接口文件与 stack 公开 EmberZNet PRO API 的方式一致。随安装提供的 Application Framework API Reference (document 120-3023-000) 有 HTML 和 PDF 这两个版本。
Ember AF 中的许多函数(如 cluster 初始化、cluster tick 和 attribute 管理等)都包含一个单字节的 endpointId
。例如,函数 zclUtilReadAttribute
(在 app/framework/util/attribute-table.c
中)将 endpointId
作为其第一个参数。
Ember AF 的一些示例包括:
boolean emberAfContainsCluster(int8u endpoint, EmberAfClusterId clusterId);
boolean emberAfContainsServer(int8u endpoint, EmberAfClusterId clusterId);
boolean emberAfContainsClient(int8u endpoint, EmberAfClusterId clusterId);
打算提供给用户应用使用的所有 Ember AF API 都包含 “emberAf” 前缀。
用于获取有关 endpoint 和 attribute 的信息的 API 包含在 app/framework/util/attribute-storage.h
中。例如,要确定一个 endpoint 是否包含某个 attribute,应使用函数 emberAfContainsAttribute(int8u endpoint, ClusterId clusterId, AttributeId attributeId)
。该函数返回一个布尔值,指示所请求的 attribute 和 cluster 是否在特定的 endpoint 上实现。
注意:读取和写入 attribute 需要一个 endpoint。如果不包含一个,则编译器会返回一个警告,表示该函数是隐式地声明;而不是一个编译器错误。因此,要注意警告。
Ember AF 回调旨在作为一种方法,以从 Ember AF 中移除所有用户代码。如果将任何应用代码放入到 Ember AF 中,Silicon Labs 会将此视为 Ember AF 的错误,因为这意味着缺少满足您的应用要求的回调。在这种情况下,请在支持门户网站 www.silabs.com/zigbee-support 上打开一张票。
(通常)在调用回调时,Ember AF 会在一些传入消息或请求一些应用数据块时给应用代码一个 first crack。在回调 API 中,一些回调返回一个布尔值来表示消息已被处理,不应进行进一步处理。如果您正在执行与 Ember AF 特定消息处理相冲突的操作,请返回 TRUE 以指示消息已完成。这可确保 Ember AF 不会干扰您对消息的处理。
Ember AppBuilder 能够为您生成一个存根回调文件。默认情况下,如果 Ember AppBuilder 发现该文件已存在于生成目录中,则选择不生成回调存根文件。您必须明确告诉应用程序以覆盖现有的文件。
当您未来重新生成文件时,Ember AppBuilder 会通过询问您是否要覆盖它来保护已生成的回调文件不会被覆盖。默认情况下,Ember AppBuilder 不会覆盖任何先前创建的回调文件。如果您选择覆盖该文件,Ember AppBuilder 会将先前的版本备份到文件 <appname>_callbacks.bak
。
注意:您可以随心地实现回调;它们不一定要在生成的回调文件中实现。但是,如果您在其它位置实现了它们,请从生成的回调文件中清除它们,以便链接器不会抱怨回调函数的重复定义。
为了方便使用,回调接口在 Ember AppBuilder GUI 中被分成几个部分。第一部分,Non Cluster-Related 回调,由位于 tool/appbuilder/callbacks.xml
的 callbacks.xml
文档中描述的回调组成。这些回调已被手动插入到 Ember AF 代码中(用户已经表明他们希望接收关于 Ember AF 的功能的信息)。
所有 global command 都属于此类别。Ember AF 包含 global command 的处理代码。如果任何 global command 回调返回 TRUE,则表示该 command 已由应用处理,并且不应进行进一步的处理;如果回调返回 FALSE,则 Ember AF 将继续正常地处理该 command。
示例:
pre-command received callback(emberAfPreCommandReceivedCallback(EmberAfClusterCommand* cmd, boolean isInterpan)
)在收到 ZCL command 但尚未由 Ember AF 的 command 处理代码处理时调用。该 command 会被解析为一个有用的结构 EmberAfClusterCommand
,它提供了一种简单的方法来访问 command 的相关数据,包括其 EmberApsFrame
、message type
、source
、buffer
、length
以及 command 的任何相关标志。此回调还返回一个布尔值来指示 command 是否已被处理。如果回调返回 TRUE,则假定该 command 已由应用处理,并且不再采取进一步的行动。
Cluster-related 回调由 Ember AF 生成,它允许接收通过 ota 发送的 pre-parsed command。通常,ZCL command 与 cluster-specific 回调一一对应。
Cluster-specific command 回调都返回一个布尔值。此返回值允许您短路(short-circuit)AF 中包含的 command 处理。如果您实现了 cluster-specific command 回调并且它向 Ember AF 返回了一个 TRUE 值,则 AF 将假定该 command 已在框架外部处理,并且已发送任何所需的 command 或默认响应;如果 cluster-specific command 回调返回 FALSE,则 AF 将假定应用代码不理解该 command,并发送状态为 “unsupported cluster command” 的默认响应。
所有 command-related 回调都是在 emberIncomingMessageHandler
的上下文中调用的。这意味着在该上下文中应用可用的 Ember API 也在 command 处理回调中可用。这些 API 列在位于 stack/include/message.h
的 stack API 文件中。Command 回调中可用的 stack API 列在 stack 消息头文件 stack/include/message.h
中并包括:
emberGetLastHopLqi()
emberGetLastHopRssi()
emberGetSender()
emberGetSenderEui64()
emberGetBindingIndex()
emberSendReply() (for incoming APS retried unicasts only)
emberSetReplyBinding()
emberNoteSendersBinding()
任何包含数组参数的 ZigBee 消息都使用一个指向数组开头的 int8u*
指针传递(即使框架知道数组中的参数可能是另一种类型(如 int16u
或 int32u
),因为框架可能运行的各种处理器上,存在字节对齐问题)。实现回调的开发者必须解析数组并为其硬件适当地转换元素。
ZigBee global command 也包含在 Ember AF 回调接口中。这些回调可用于接收对 global command 的响应。例如,如果您的设备向另一个设备发送 global read attribute command
,它可以通过实现 emberAfReadAttributesResponseCallback
来处理 command 响应。
Figure 2 展示了由 AF 实现的 emberIncomingMessageHandler
收到的消息如何处理和如何通过框架代码流向应用实现的回调。
一旦传入消息被确定为一个传入 global command,它就会被传递给 global command 处理以进行处理,如 Figure 3 所示。
否则,如果发现它是 cluster specific command,则会将其传递给 cluster-specific command 处理,如 Figure 4 所示。
注意:已移除本文档中包含的回调参考,取而代之的是在 Ember Application Framework API Reference (document 120-3023-000) 中提供参考。
Ember AF 提供了单个用于访问系统当前时间的 API(int32u emberAfGetCurrentTime()
),该函数的实现如下:
- 如果在系统上实现了 ZCL
time cluster
服务端,则emberAfGetCurrentTime
通过调用int32u emberAfTimeClusterServerGetCurrentTime()
来从服务端检索时间。在这种情况下,将从time cluster
服务端的time attribute
中读取时间并返回。 - 如果未实现
time cluster
服务端,则emberAfGetCurrentTime
将调用emberAfGetCurrentTimeCallback
。
如果您的设备需要知道当前时间但没有实现 time cluster
服务端插件,则它需要负责在系统上的某处维护自身的时间,并在被请求时通过 emberAfGetCurrentTimeCallback
返回该时间。这对于未实现 time cluster
服务端的 SE 设备尤其重要,如 IPD(in-premise display)。在时间管理上,IPD 本质上是独立的。对于实现 time cluster
服务端的 non-Energy Service Portal 来说,它将超出规范(as currently interpreted)。因此,IPD 必须维护自身的时间信息,并在通过 emberAfGetCurrentTimeCallback
请求时将其提供给框架。
如果您的应用包含 time cluster
服务端,则 time cluster
服务端代码始终尝试通过 emberAfGetCurrentTimeCallback
初始化和更新 time cluster
服务端的 time attribute
。如果 emberAfGetCurrentTimeCallback
返回 0,则 time cluster
服务端每秒递增一次存储的 attribute。因此,如果实际时间值可以从系统上的其他设备同步并写入到 time cluster
服务端的 time attribute
中,则可以使用 time cluster
服务端来在系统上实时存储和维护时间,而无需实现 emberAfGetCurrentTimeCallback
。有关如何通过 time cluster
服务端的绑定实现来处理时间的更多信息,请参阅 app/framework/plugin/time-server/time-server.c
。
Ember AF 包含一个时间客户端插件来允许时间客户端同步并跟踪当前 UTC 时间,而无需实现 time cluster
服务端。如果您的设备不是 ESP,它应该实现 time cluster
客户端并使用包含的时间客户端插件来跟踪时间。
在 SoC 和 host 上,Ember AF 及其关联的 cluster 代码使用 Ember 事件机制来调度事件。使用 Ember 事件机制可以节省代码和 RAM,并且可以使嗜睡设备(sleepy device)更好地工作。
在一个高级别上,事件机制提供了一个中心位置,在这里,设备所执行的周期性动作都可以基于某些用户输入、ota 命令或设备初始化来激活和停用。该事件机制优于它所替换的 constant tick 机制,因为它允许 Ember AF 准确地知道设备上的下一个动作将在何时发生。这对于嗜睡设备来说非常重要,因为它们需要精确地知道自己何时必须醒来并执行某些行动(或者更重要的是,由于某些事件正在进行,因此它们不能进入睡眠)。Ember AF 有两种类型的事件:custom 事件和 cluster 事件。Custom 事件由 Ember AF 用户创建,可用于应用中的任何目的。Cluster 事件明确地与 Ember AF 插件中的 cluster 实现相关。
Ember AF 使用 Ember 标准事件机制来控制和运行 Ember AF 中的 “custom” 应用事件。Stack 的事件机制记录在 stack/include/event.h
中。
Ember AF 和 Ember AppBuilder 为创建和向应用添加 custom 事件提供了一个有用的接口。要在 Ember AppBuilder 中创建 custom 事件,请打开 Ember AppBuilder 配置文件中的 “Includes” 选项卡,在 “Custom Events” 部分中,单击 “New” 按钮以创建 custom 事件。这会将事件添加到 Ember AF 将要运行的事件列表中,并将 custom 事件的存根添加到 Ember AppBuilder 生成的 “callbacks” 文件中。
Custom 事件由两部分组成:事件触发时调用的事件函数和用于调度事件的 EmberEventControl
结构。框架的事件机制必须知道这些项中的每一个;这样,它既可以跟踪下一个事件何时发生(以便进入睡眠),也可以知道当事件触发时要调用什么函数。有关创建事件的更多文档,请参阅 stack/include/event.h
。
HaSampleGateway
示例应用使用 custom 事件来管理其状态。该事件由两部分组成:名为 buttonEventControl
的 EmberEventControl
结构,和每次事件触发时调用的事件函数 buttonEventHandler
。事件和事件控件包含在示例应用附带的配置文件中。在创建基于此示例场景的新应用时,可以在 AppBuilder 的 “General” 选项卡的 “Description” 字段中找到 HaSampleGateway
应用的文档。
每个 cluster 都包含一个服务端和一个客户端 “tick” 回调。Ember AppBuilder 为每个端点上的每个 cluster 服务端或客户端(作为单个事件)生成一个事件表。实际的事件表生成到 <DeviceName>_endpoint_config.h
头文件中,该头文件包含在 app/framework/util/af-event.c
中,并被 Ember AF 的事件代码使用。
注意:事件表在编译时静态创建。因此,不能在运行时随意添加或从事件表中移除事件。事件表条目必须存在,然后代码才可以管理它的调度,使其处于活动状态并等待被调用,或者处于停用状态并等待被激活和调度。
插件或应用代码可以通过使用 Ember AF 的事件管理 API 来在事件表中管理 cluster-related 事件。该 API 由两个函数组成:emberAfScheduleClusterTick
和 emberAfDeactivateClusterTick
。
tick 是事件系统中使用的基本时间单位。tick 的持续时间取决于正在使用的平台。使用当前的 Ember 平台,1 tick 大约等于:
其中 MILLISECOND_TICKS_PER_SECOND
是每秒的时钟 tick 数。因此,当使用 t
值作为 delayMs
参数值来调用 emberAfScheduleClusterTick
时,该事件将运行不小于:
当然,该值的实验误差取决于时钟源的可靠性。
emberAfScheduleClusterTick
使用 endpoint
、cluster id
和 client/server identity
来查找事件表中的相关事件。事件表条目由 Ember AppBuilder 生成到 <DeviceName>_endpoint_config.h
中。如果找不到事件表条目,emberAfScheduleClusterTick
会返回 EMBER_BAD_ARGUMENT
给调用者;如果找到事件表条目,则它将会按调用者请求的毫秒数来调度事件,并返回 EMBER_SUCCESS
。
EmberStatus emberAfScheduleClusterTick(int8u endpoint,
int16u clusterId,
boolean isClient,
int32u timeMs,
EmberAfEventSleepControl sleepControl);
EmberAfEventSleepControl
参数仅与嗜睡设备有关;它对非嗜睡设备没有影响。EmberAfEventSleepControl
的可能值在 app/framework/include/af-types.h
中枚举,如下所示:
EMBER_AF_OK_TO_HIBERNATE
表示应用可能会进入长时间深度睡眠状态,直到需要调用该事件为止。如果调度代码在调用该事件之前不关心设备做了什么,则使用此睡眠控制值。EMBER_AF_OK_TO_NAP
表示设备应该周期性小睡,并且应该在小睡间醒来以轮询,直到该事件被调用。如果调度代码希望设备定期轮询直到事件被调用,则使用此睡眠控制值。如果调度事件是一个等待来自网络上其他设备的某些应答的超时,则此特别有用。EMBER_AF_STAY_AWAKE
表示设备不应该睡眠,并且应该保持清醒,直到事件被调用。如果您正在安排一个非常频繁的事件,并且不希望设备周期性小睡,则使用此值,因为设备每次唤醒时都会轮询。如果设备完全不在睡眠状态,则它将每秒轮询一次。
该函数用于关闭事件。在调度的事件被调用以确保事件代码不会继续调用该事件时,应该使用该函数。如果不再需要事件,也可以在事件被调用之前调用该函数。
注意:在 Ember AF 中,
emberAfDeactivateClusterTick
在事件触发之前被自动调用,以确保该事件不会在每个 tick 上继续被调用。您可以在 Ember AppBuilder(从 version 2.1.50 起)生成的事件表输出中看到对emberAfDeactivateClusterTick
的调用。
DeactivateClusterTick 与 ScheduleClusterTick 相似,它们有多个相同的参数,因为它必须在关闭 clusterTick 之前在事件表中找到该 clusterTick。
EmberStatus emberAfDeactivateClusterTick(int8u endpoint,
int16u clusterId,
boolean isClient);