Z-Wave Plus应用程序的基本功能由设备类型和角色类型定义。为Z-Wave Plus应用程序确定设备类型和角色类型的正确组合是很重要的。

一旦确定了设备和角色类型,就可以开始应用程序开发。

1. 创建应用程序文件夹并设置构建环境

1.1 选择要创建的应用程序角色

选择一个现有的软件样本,并修改它以满足您的需求。主要根据角色类型进行选择:

  • 总是工作终端设备: SwitchOnOff, WallController, PowerStrip

  • 报告睡眠终端设备: SensorPIR

  • 侦听睡眠终端装置: DoorLock

此外,还有一些其他的选择要考虑

  • Endpoint实现由Power Strip支持。

  • 关联组在Wall Controller中实现。

1.2 创建一个新的Simplicity Studio项目

按照以下步骤设置应用程序的工作目录

1.  要对构建环境有一个大致的了解,请参阅[3]以获得更多信息。

2.  选择其中一个应用程序并在Simplicity studio中创建一个示例项目。

3. 通过重命名根文件夹,例如<MyApp>,将导入的应用程序重命名为适合应用程序的名称。

4.  导航到<MyApp>/src文件夹,将.c文件重命名为<MyApp>.c。

5.  对于任何其他示例,搜索APP_FREQ并将其替换为您正在使用的频率。要了解更多细节,请参考[3]中的第6章。

6.  构建应用程序以验证更改没有破坏任何内容。也可以将应用程序下载到芯片上,以检查应用程序是否运行无误。

2. 配置config_app.h

2.1 通用类型、特定类型和设备选项

一个Z-Wave Plus设备必须使用以下两个定义指定一个通用设备类和一个特定设备类:

  • GENERIC_TYPE

  • SPECIFIC_TYPE

请参考Z-WaveDevelopment Basics和Z-WavePlus v2 Device Type Specification为您的产品选择适当的通用和特定设备类。标识符值在ZW_classcmd.h中定义。

DEVICE_OPTIONS_MASK是一个位掩码,用于指定一组设备选项。有关详细信息,请参阅ZW_basis_api.h文件。

2.2 角色类型、节点类型、图标类型、用户图标类型(Z-Wave Plus Info CC)

角色类型、节点类型、图标类型和用户图标类型都是Z-Wave Plus命令类使用的值。它们使用以下定义进行设置:

  • APP_ROLE_TYPE

  • APP_NODE_TYPE

  • APP_ICON_TYPE

  • APP_USER_ICON_TYPE

关于在Z-Wave Plus Info CC中使用的图标类型的进一步信息,请参考Z-WavePlus Assigned Icon Types。联系Z-Wave联盟获取新的图标类型。

2.3 Manufacturer Specific CC / 固件更新

Manufacturer specific CC需要定义一些特定于产品的值。有关更多信息,请参阅Z-WaveManagement Command Class Specification中的制造商特定命令类。ZAF使用以下宏来处理这些值 :

  • APP_MANUFACTURER_ID

  • APP_PRODUCT_TYPE_ID

  • APP_PRODUCT_ID

固件更新命令类使用以下定义:

  • APP_FIRMWARE_ID: 固件ID由产品类型ID和产品ID组成。

制造商和产品ID用于从制造商的角度识别Z-Wave产品。其他应用程序也可以使用这些信息在用户界面上显示公司标识、产品类型、用户指南等。该信息通过Manufacturer Specific C交互,当前分配的制造商ID列在ZW_classcmd.h文件中。

2.4 关联组信息(AGI)

在应用程序中,AGI必须在config_app.h中配置。

对于Z-Wave Plus产品,生命线组是强制性的。它可以使用以下声明来定义:

#define AGITABLE_LIFELINE_GROUP \ {<command class X>, <command A>}, \ {<command class Y>, <command B>}, \ {<command class Z>, <command C>}

参考Z-WavePlus v2 Device Type Specification可以了解在生命线组中要使用哪些事件和命令类。命令类和命令的定义可以在ZW_classcmd.h中找到。

如果应用程序没有实现Multi Channel端点,其他组(除了生命线)必须使用以下格式定义:  ​​​​​​​

#define AGITABLE_ROOTDEVICE_GROUPS \ {<profile 1 MSB>, <profile 1 LSB>, {<command class X, command A}, "<group 2 name>"}\ {<profile 2 MSB>, <profile 2 LSB>, {<command class X, command A}, "<group 3 name>"}

如果应用程序实现Multi Channel端点,则必须使用端点组填写AGI定义。多通道端点实现的一个例子是Power Strip应用。​​​​​​​

#define AGITABLE_ROOTDEVICE_GROUPS \ AGITABLE_ENDPOINT_1_GROUPS, \ AGITABLE_ENDPOINT_2_GROUPS, \ AGITABLE_ENDPOINT_3_GROUPS, \ AGITABLE_ENDPOINT_4_GROUPS

AGITABLE_ENDPOINT_X_GROUPS表示端点x的非生命线组。每个端点组都被定义为由AGITABLE_ROOTDEVICE_GROUPS定义的根设备组,但有一个匹配的定义名、其他配置文件、命令类等。​​​​​​​

#define AGITABLE_ENDPOINT_1_GROUPS \ {<profile X MSB>, <profile X LSB>, {<command class>, <command>}, "group name"}, \ {ASSOCIATION_GROUP_INFO_REPORT_PROFILE_CONTROL, ASSOCIATION_GROUP_INFO_REPORT_PROFILE_CONTROL_KEY01, {COMMAND_CLASS_SWITCH_MULTILEVEL_V4, SWITCH_MULTILEVEL_SET_V4}, "Button 1"}

当产品实现Multi Channel端点时,它必须映射到根关联组。根组映射提供向后兼容性,因为不支持Multi Channel的设备必须能够询问根设备支持哪些组。根组映射定义到端点组的根设备映射中的组。

Root Device Group

Endpoint ID

Endpoint Ggroup ID

Root Device Group 2

Endpoint 1

Endpoint 1 Group 2

Root Device Group 3

Endpoint 2

Endpoint 2 Group 2

下面显示了如何在config_app.h中配置根组映射。根组映射设置的详细信息取决于应用程序。​​​​​​​

#define ASSOCIATION_ROOT_GROUP_MAPPING_CONFIG \ {<ROOT DEVICE GROUP 2>, <ENDPOINT ID 1>, <ENDPOINT GROUP 2>}, \ {<ROOT DEVICE GROUP 3>, <ENDPOINT ID 2>, <ENDPOINT GROUP 2>}

请参考Wall Controller应用程序中的config_app.h文件获取组映射的示例。SensorPIR还显示了AGI是如何设置的。

组定义用于在应用程序的main源文件中初始化AGI。

2.5 安全

安全级别在config_app.h文件中配置,并定义了REQUESTED_SECURITY_KEYS标志。定义可以在ZW_security_api.h文件中找到。

开发产品时必须指定应用程序安全级别位。安全级别为默认值No-secure。

#define REQUESTED_SECURITY_KEYS \ (SECURITY_KEY_S2_UNAUTHENTICATED_BIT|SECURITY_KEY_S0_BIT)

添加功能:

ApplicationSecureKeysRequested()包含安全密钥标志REQUESTED_SECURITY_KEYS。

2.3 设置config_rf.h

Tx功率应该通过修改文件config_rf.h来设置,以符合当地监管机构的要求。

该文件包含2个定义: ​​​​​​​

#define APP_MAX_TX_POWER 0#define APP_MEASURED_0DBM_TX_POWER 33

其中,APP_MEASURED_0DBM_TX_POWER用于在传导环境中将TX功率调谐到0dbm。在旋转过程中,‘APP_MAX_TX_POWER’应该为0 (0dBm)。

APP_MAX_TX_POWER取值范围为-100 ~ +100 deci dBm (-10dBm ~ +10dBm),用于Tx功率调优完成后,应用框架对Tx功率进行调整。

有效范围是:

100 >= (APP_MAX_TX_POWER + APP_MEASURED_0DBM_TX_POWER) >= -100

要设置最大功率,请使用​​​​​​​

#define APP_MAX_TX_POWER 100#define APP_MEASURED_0DBM_TX_POWER 0

设置TX功率的步骤

a) 将APP_MAX_TX_POWER设置为0,将APP_MEASURED_0DBM_TX_POWER设置为0,编译应用程序。

b) 使用产品上的这些设置对Tx功率进行测量。重要的是,这是在成品上完成的。

c) 将APP_MEASURED_0DBM_TX_POWER设置为测量的传导值。

d) 将“APP_MAX_TX_POWER”设置为产品使用区域所需/允许的Tx功率。

e) 编译固件。

f) 按照调节限值(步骤d)进行调节辐射测量,例如50deci dBm (5 dBm)。如果调节测量允许再增加1/2db,则将1/2dbm改为55并重新编译。如果一个方向的辐射太高,例如需要少1/2db,那么将其改为45deci dBm并重新编译。

2.4 设置非易失性存储器

所有应用程序都必须打开一个NVM3[18]文件系统,ZAF使用该文件系统在非易失性内存中存储文件。应用程序还可以使用文件系统来存储应用程序特定的文件。通过调用在ZAF_nvm3_app.c中找到的applicationfilesystemit(..)函数来打开文件系统。

应用文件系统在flash中占用12k字节。为了使文件系统在所有情况下都能正常工作,建议在其中存储的数据不要超过4k字节,包括应用程序特定的文件和ZAF使用的文件。应用程序开发人员不能增加应用程序文件系统的默认大小(NVM3_APP_NVM_SIZE),因为这会使它与用于存储Z-Wave协议文件的区域冲突。

NVM3文件系统使用RAM中的缓存在flash中存储文件的位置。默认情况下,缓存中的最大文件数设置为10。如果ZAF和应用程序使用的文件总数超过10,则必须相应地增加ZAF_nvm3_app.c中的NVM3_APP_CACHE_SIZE,否则文件系统将大大减慢。

必须为NVM3文件系统中的每个文件分配一个单独的20位对象密钥,作为文件标识[18]。整数范围0x51000-0x5FFFF已经被保留用作ZAF的文件标识符,并且不能用于特定于应用程序的文件。特定于应用程序的文件最好使用范围为0x00000-0x0FFFF的标识符。

每个示例应用程序都列出了它在一个名为g_aFileDescriptors[]的数组中使用的文件。该列表包含应用程序中ZAF使用的文件标识符和文件大小。一些示例应用程序在列表中还包含特定于应用程序的文件。在启动时,应用程序检查列表中的所有文件是否都在文件系统中。所有应用程序文件系统都必须有一个文件标识符ZAF_FILE_ID_APP_VERSION,该文件包含应用程序的版本号。如果该文件丢失,则认为该文件系统未写入或损坏,从而重新格式化该文件系统,并将所有文件设置为默认值。

要将特定于应用程序的文件引入到文件系统,只需定义一个尚未使用的新的20位对象键值。一旦使用函数nvm3_writeData()首次写入该文件,该文件将被添加到文件系统中。​​​​​​​

#define FILE_ID_MYNEWFILE (0x00112)typedef struct SMyAppData{ int32_t status; uint8_t vector[10];} SMyAppData;SMyAppData wrtData;wrtData.status = -5;memset(&(wrtData.vector), 0x55, sizeof(wrtData.vector));//This call will create and write a file containing wrtData in the file system.nvm3_writeData(pFileSystemApplication, FILE_ID_MYNEWFILE, &wrtData, sizeof(wrtData));SMyAppData rdData;//This call will read the content of the file to rdData. Please be warned that it is//not possible to read part of the file. If sizeof(rdData) < sizeof(wrtData) above, //the read function will return an error.nvm3_readData(pFileSystemApplication, FILE_ID_MYNEWFILE, &rdData, sizeof(rdData));

建议将默认内容写入函数SetDefaultConfiguration()中特定于应用程序的文件,该函数将在格式化文件系统后调用。

执行固件更新时,应用程序文件系统的内容保持不变。如果文件标识符保持不变,则仍然可以使用以前固件使用的旧文件。当开发固件的新版本时,需要增加应用程序config_app.h中的APP_VERSION、APP_REVISION或APP_PATCH号,在其中添加新文件或以任何方式更改文件。引导加载程序不接受版本号较低或相同的文件。然后,在新固件的第一次启动时,应用程序将能够通过读取标识符ZAF_FILE_ID_APP_VERSION的文件来识别芯片上的文件系统属于旧版本的固件。

2.5 看门狗使能/禁用

看门狗定时器在应用程序中默认是启用的,如果应用程序任务运行超过1秒而不释放处理器,将重置设备。

为了在开发过程中禁用看门狗,注释掉ApplicationTask函数内部的WDOGn_Enable()函数调用,如下所示:

注意:看门狗应该总是在生产代码中启用,但可以在调试版本中禁用 ​​​​​​​

static voidApplicationTask(SApplicationHandles* pAppHandles){ // Init DPRINT("Enabling watchdog\n"); WDOGn_Enable(DEFAULT_WDOG, true); <<-- Comment out this line to disable the watchdog

2.6 应用程序源文件

应用程序必须实现一个用于初始化的函数:ApplicationInit(..)。该函数在系统启动时被Z-Wave主函数调用,并获得唤醒原因作为输入参数,请参阅ZW_basis_api.h文件。应用程序特定的硬件初始化,如引脚配置,应该从这个函数完成。配置完成后,函数必须通过调用ZW_UserTask_ApplicationRegisterTask(..)来注册应用程序任务,以便应用程序可以开始运行。

应用程序任务函数ApplicationTask(..)被FreeRTOS注册在准备运行的任务列表中。在软件示例中,ApplicationTask(..)在启动时首先执行特定于应用程序的软件初始化。其中,它使用针对不同类型事件的事件处理程序来配置事件分发功能。随后,它进入无限循环,让事件分发程序处理任何事件。参见9.5节中的描述。FreeRTOS调度器将确保应用程序任务根据其优先级得到处理器时间。

2.6.1 配置命令类列表

应用程序使用3个命令类列表根据包含状态发送节点信息帧(NIF)。这三个列表定义了以下的​​​​​​​

NIF:  - Not included - Non-securely included - Securely included

以下命令类列表用于节点未被包含或未被安全包含的情况。当包含设备时,Security和Security_2命令类将被ZAF删除。这个命令类列表出现在NIF中:

static code BYTE cmdClassListNonSecureNotIncluded[]

以下命令类列表在安全包含节点时使用。它表示不安全支持的命令类,即使设备已经安全地包含在内。

static code BYTE cmdClassListNonSecureIncludedSecure[]

以下命令类列表在安全包含节点时使用。它只包含安全支持的命令类。该命令类列表通过安全命令类、支持的安全命令报告命令发布。

static BYTE cmdClassListSecure[]

2.6.2 Endpoint配置

如果您的设备必须实现端点,那么必须在config_app.h文件中设置AGI和关联组映射。在AGI中配置每个端点之后(参见2.4节),必须调用AssociationInitEndpointSupport()而不是AssociationInit()来进行关联组映射。

最后,需要通过调用Transport_AddEndpointSupport()函数为端点初始化传输层。这个函数设置端点的功能和命令类列表。请阅读[13]以获得关于单个端点和聚合端点的更多信息。

void Transport_AddEndpointSupport( EP_FUNCTIONALITY_DATA* pFunctionality, EP_NIF* pList, BYTE sizeList);

2.6.3 多线程应用

Z-Wave应用程序默认运行以下线程:

  • Z-Wave协议线程,用于执行协议栈

  • 主应用程序线程用于执行应用程序代码,并作为Z-Wave协议线程的接口。

一个应用程序可以扩展创建额外的FreeRTOS线程\任务。这些线程被称为用户任务,以区别于主应用程序线程(负责与Z-Wave协议线程通信)。

用户任务是使用ZW_UserTask模块(ZW_UserTask.h)创建的,该模块包含ZW_UserTask_t数据类型的定义和可用api用于创建任务。

ZW_UserTask_t定义如下:

typedef struct { TaskFunction_t pTaskFunc; char* pTaskName; void* pUserTaskParam; ZW_UserTask_Priority_t priority; ZW_UserTask_Buffer_t* taskBuffer;} ZW_UserTask_t;
  • pTaskFunc是任务执行的函数

  • pTaskName为任务名称

  • pUserTaskParam是传递给任务函数的参数指针

  • priority是任务的优先级。可用的优先级有:

    > USERTASK_PRIORITY_BACKGROUND

    > USERTASK_PRIORITY_NORMAL

    > USERTASK_PRIORITY_HIGHEST

  • taskBuffer是FreeRTOS处理任务所需的静态分配内存。

以下是可用的api

ReturnCode_t ZW_UserTask_Init(void);
  • ZW_UserTask_Init() 函数用于初始化ZW_UserTask模块。不需要显式地调用它,因为它在引导时已经被调用了。

> 如果再次调用该函数,它将返回Code_Fail_InvalidState

ReturnCode_t ZW_UserTask_CreateTask(ZW_UserTask_t* task, TaskHandle_t* xHandle);
  • ZW_UserTask_CreateTask() 可以用于创建额外的任务。

> 此函数需要以下输入参数

task是指向ZW_UserTask任务参数的指针。

xHandle是FreeRTOS返回的任务句柄。

> 这个函数可以返回以下代码:

Code_Fail_InvalidState—如果模块还没有初始化。

Code_Fail_InvalidOperation—如果已经创建了最大的用户任务。

Code_Fail_InvalidParameter—如果优先级设置超出界限或任何输入参数为NULL。

Code_Fail_Unknown—如果FreeRTOS创建任务失败。​​​​​​​

bool ZW_UserTask_ApplicationRegisterTask( VOID_CALLBACKFUNC(appTaskFunc)(SApplicationHandles*), uint8_t iZwRxQueueTaskNotificationBitNumber, uint8_t iZwCommandStatusQueueTaskNotificationBitNumber, const SProtocolConfig_t * pProtocolConfig);
  • ZW_UserTask_ApplicationRegisterTask() 用于创建主应用程序线程。关于函数使用和行为的更多详细信息,请参见2.6节。

有关api的更多信息,请参阅ZW_UserTask.h文件。有关可用返回码的详细信息,请参阅ZW_global_definitions.h中定义的ReturnCode_t。

一个如何使用这些api的例子可以在SensorPIR应用程序中找到(参见SensorPIR.c中的ApplicationInit(…))

2.6.3.1 限制和建议

以下限制和建议适用于用户任务:

  • 除了主应用程序线程之外,最多可以创建三个用户任务。

  • UserTask优先级的分配都低于Z-Wave协议线程的优先级(这在定义可用优先级级别的ZW_UserTask模块中强制执行)。

  • 在FreeRTOS调度程序启动之前必须创建用户任务(使用函数ZW_UserTask_CreateTask),因此,它们的创建只能在ApplicationInit(…)中进行(参见7.6节)。

  • 没有提供主应用程序线程和用户任务之间的通信。但是,建议使用FreeRTOS队列和事件。

  • 用户任务不能直接与Z-Wave协议线程通信。它们需要使用主应用程序线程作为中介。

> 除了电源管理器api,它可以从所有任务中调用。

Z-Wave 700应用程序框架第四章 - 从零开始一个Z-Wave Plus应用相关推荐

  1. Z-Wave 700应用程序框架第七章 - 固件更新和引导加载程序

    本节的目的是描述如何生成和管理固件更新映像. ZW700 SDK附带三个引导加载程序映像. 一个是FG14模块的OTW图像. 这个引导加载程序只适用于运行SerialAPI的FG14设备. 另外两个引 ...

  2. 微信小程序(第十四章) - 信息查询页面的实现

    微信小程序(第十四章)- 信息查询页面的实现 前言 页面标题实现 信息框的实现 页面结构实现 页面样式实现 学生到校离校信息查询列表实现 页面结构实现 页面样式实现 正在加载实现 页面结构实现 页面样 ...

  3. HTML+CSS+JavaScript网页制作案例教程-黑马程序员-第四章课后习题(播放器图标)

    黑马程序员编著的教材  HTML+CSS+JavaScript网页制作案例教程 第四章:播放器图标-课后习题参考代码 ........ 记得 关注,收藏,评论哦,作者将持续更新.... 我自己做的效果 ...

  4. 学堂在线-程序设计基础-第四章

    文章目录 第四章-筛法与查找 4.1 插花游戏 笔记 代码实现 4.2 筛法 笔记 4.2.3 代码实现 4.2.5 代码实现 4.2.7 代码实现 4.2.7 韩信点兵问题的数学理解 4.3 线性查 ...

  5. Python程序开发——第四章 字典与集合

    目录 一.字典 (一)字典的创建 (二)字典的访问 (三)字典的增删改查 1.字典的添加 2.字典的删除 3.字典的修改 4.字典的查询 二.集合 (一)集合的分类 (二)集合的创建 (三)集合元素的 ...

  6. 【传智播客】Javaweb程序设计任务教程 黑马程序员 第四章 课后答案

    所有章节答案合集-->传送门 [测一测] 学习完前面的内容,下面来动手测一测吧,请思考以下问题: 1.简述请求转发与重定向的异同?(至少写3点) 2.请写出禁止浏览器缓存页面的核心代码. 3.请 ...

  7. 移动开发技术_微信小程序_第四章测试

    第4章自测已完成 重做 还可以重做1次 截止时间:2022-12-19 09:36:00 1 [单选题]下面不属于scroll-view组件属性的是(). A. scroll-x B. scroll- ...

  8. 第三部分:Android 应用程序接口指南---第三节:应用程序资源---第四章 本地化...

    第4章 本地化 Android系统会在很多地区的不同设备上运行.为了能够将应用提供给更多的用户,你的应用应该以不同的方式处理文本.音频文件.数字.货币和图形,以适合于你应用使用的地点. 本文档描述了本 ...

  9. 【前端框架】react框架 第四章 react组件进阶

    目录 1. 组件的props 特点 2. 组件通迅的三种方式 父组件传递数据给子组件 子组件传递数据组父组件 兄弟组件 3. Context Context使用步骤 4. props深入 props校 ...

最新文章

  1. Web请求响应简单整理
  2. android4.0 编译报错 Xmx2048m错误 .
  3. PHP的autoload自动加载机制使用说明
  4. JS编程建议——2:正确辨析JavaScript句法中的词、句和段
  5. 百度云服务器安装git并做远程仓库
  6. db2有主键时默认hash分区_不允许设置db2主键问题的解决
  7. Elasticsearch--分词-自定义扩展词库---全文检索引擎ElasticSearch工作笔记022
  8. [Asp.net]Uploadify上传大文件,Http error 500 解决方案
  9. 千万主播薇娅们直播间用的直播六个话术
  10. 【小程序】一个提醒休息的小程序,供大家娱乐
  11. List集合之ArrayList
  12. [疑难解答]MSN常见问题及回答(转)
  13. Diffusion扩散模型简述 + 代码demo
  14. R语言实战 R语言读取不同文件类型中数据的4种方法
  15. linux下搭建阿帕奇服务器
  16. 天龙八部谁是主角?(MR词频统计)
  17. python wxpython菜鸟教程_wxpython新手向教程
  18. Python基础知识笔记(三)——字典、集合
  19. ROS中usb摄像头的使用_(usb_cam)
  20. iOS 语音搜索通讯录算法

热门文章

  1. 【python】解决网页gb2312编码中文乱码问题
  2. 人脸识别门禁入主社区 新潮不代表不安全
  3. ajax分页功能实现php,详解AJAX分页效果的简单实现
  4. Plant simulation16.0汽车总装车间仿真第二步:仿真模型搭建Part01——滑橇线物流输送
  5. Lichee_RV学习系列---移植dhrystone
  6. 计算机白板培训报道,巧用白板,增色课堂——南宁市五象教育集团小学部开展希沃白板五实操培训活动...
  7. 病毒种类可分为那几类?芒果xo是否带有病毒?
  8. 剑指offer_31:HZ偶尔会拿些专业问题来忽悠那些非计算机专业的同学。今天测试组开完会后,他又发话了:在古老的一维模式识别中,常常需要计算连续子向量的最大和,当向量全为正数的时候,问题很好解决。但
  9. win10系统U盘安装详细经验附系统软件
  10. 【SAP Abap】关于SAP汇率表 TCURR 的CDS开发实例