Skip to content

7.3 协调器设备开发 ​

一句话理解

协调器侧只需两件事:接收上报命令 → 解析属性值显示到屏幕;外加开启对应宏。

协调器设备开发内容 ​

  1. 接收和处理属性数据;
  2. 启用对应的宏定义。

接收和处理属性数据 ​

与读写命令类似,协调器收到上报信息后,产生系统事件 ZCL_INCOMING_MSG。在 zclSampleSw_event_loop() 中:

c
case ZCL_INCOMING_MSG:
  // Incoming ZCL Foundation command/response messages
  zclSampleSw_ProcessIncomingMsg( (zclIncomingMsg_t *)MSGpkt );
  break;

在 zclSampleSw_ProcessIncomingMsg() 中,添加上报命令分支:

c
static void zclSampleSw_ProcessIncomingMsg( zclIncomingMsg_t *pInMsg )
{
  switch ( pInMsg->zclHdr.commandID )
  {
    ...... // 省略其他分支

#ifdef ZCL_REPORT
    case ZCL_CMD_REPORT:      // 属性上报命令
      zclSampleSw_ProcessInReportCmd( pInMsg );   // 上报处理函数
      break;
#endif
    ...... // 省略其他分支
  }
  if ( pInMsg->attrCmd )
    osal_mem_free( pInMsg->attrCmd );
}

属性上报处理函数 ​

zclSampleSw_ProcessInReportCmd() 是自定义函数:

c
#ifdef ZCL_REPORT
static uint8 zclSampleSw_ProcessInReportCmd( zclIncomingMsg_t *pInMsg )
{
  zclReportCmd_t *reportCmd;
  uint8 i;

  reportCmd = (zclReportCmd_t *)pInMsg->attrCmd;

  for ( i = 0; i < reportCmd->numAttr; i++ )   // reportCmd->numAttr 为属性数量
  {
    if ( pInMsg->clusterId == ZCL_CLUSTER_ID_GEN_ON_OFF_SWITCH_CONFIG &&
         reportCmd->attrList[i].attrID == ATTRID_ON_OFF_SWITCH_TYPE )
    {
      int8 attrDat = *(reportCmd->attrList[i].attrData);   // 读取属性值
      HalLcdWriteStringValue( "Rx Value:", attrDat, 10, 4 ); // 显示属性值
    }
  }
  return ( TRUE );
}
#endif // ZCL_REPORT
📥
收到上报
ZCL_INCOMING_MSG 事件触发
→
🔀
分流
commandID == ZCL_CMD_REPORT → 上报处理
→
📊
解析显示
匹配 Cluster + 属性 ID → 取出值 → 屏幕显示

启用对应的宏定义 ​

协调器侧需要开启两个宏:ZCL_REPORT_DESTINATION_DEVICE 和 ZCL_REPORT。

工程 Options → C/C++ Compiler → Preprocessor → Defined symbols:

ZCL_ON_OFF
ZCL_GROUPS
ZCL_REPORT_DESTINATION_DEVICE
ZCL_REPORT

为什么宏不同?

  • 终端侧开 ZCL_REPORTING_DEVICE:表示"我是上报方";
  • 协调器侧开 ZCL_REPORT_DESTINATION_DEVICE + ZCL_REPORT:表示"我是接收方,允许处理上报命令"。

宏决定协议栈编译哪些代码,两边各开各的。

小结

协调器侧 = 接事件(ZCL_INCOMING_MSG)→ 分流(ZCL_CMD_REPORT)→ 解析显示 + 开宏。至此,上报链路"终端 → 协调器"就完整了。

内容来源:紫甲 IoT《ZigBee 3.0 开发指南》第四部分·7.3 协调器设备开发,原站链接


本章自测 ​

一、单项选择题(每题 4 分,共 40 分) ​

  1. 协调器设备开发主要包括哪两项内容(A. 定义上报事件 + 周期调用上报 API B. 接收和处理属性数据 + 启用对应宏 C. 烧录协调器 + 烧录终端 D. 组网 + 绑定) 答案:B

  2. 协调器收到终端的上报信息后,产生的系统事件是(A. SAMPLEAPP_REPORT_EVT B. ZCL_INCOMING_MSG C. ZDO_STATE_CHANGE_EVT D. KEY_CHANGE) 答案:B

  3. 在 zclSampleSw_event_loop() 中,ZCL_INCOMING_MSG 事件被派发给哪个函数处理(A. zclSampleSw_ReportTest() B. zclSampleSw_ProcessIncomingMsg() C. zcl_SendReportCmd() D. zclSampleSw_Init()) 答案:B

  4. 在 zclSampleSw_ProcessIncomingMsg() 中,用于识别"这是一条属性上报命令"的判断依据是(A. pInMsg->clusterId == 0 B. pInMsg->zclHdr.commandID == ZCL_CMD_REPORT C. pInMsg->attrCmd == NULL D. pInMsg->srcAddr == 0x0000) 答案:B

  5. 真正负责解析上报属性值并显示到屏幕的自定义函数是(A. zclSampleSw_ProcessInReportCmd() B. zclSampleSw_ReportTest() C. zcl_SendReportCmd() D. zclSampleSw_event_loop()) 答案:A

  6. 在 zclSampleSw_ProcessInReportCmd() 中,遍历属性记录的循环次数由哪个变量决定(A. pInMsg->clusterId B. reportCmd->numAttr C. seqNum D. SAMPLEAPP_REPORT_PERIOD) 答案:B

  7. 为了确认收到的正是本实验关心的属性,处理函数中做了哪两项匹配(A. 匹配 Cluster ID 和 attrID B. 匹配短地址和端点 C. 匹配 seqNum 和 numAttr D. 匹配 dataType 和 direction) 答案:A

  8. 在解析完成后,函数通过哪个函数把属性值显示到协调器屏幕上(A. printf() B. HalLcdWriteStringValue() C. UART_Write() D. osal_start_timerEx()) 答案:B

  9. 在 zclSampleSw_ProcessIncomingMsg() 末尾,对 pInMsg->attrCmd 做的操作是(A. 再次发送 B. osal_mem_free 释放内存 C. 清零 D. 复制到新缓冲区) 答案:B

  10. 协调器侧需要开启的两个宏是(A. ZCL_REPORTING_DEVICE 和 ZCL_ON_OFF B. ZCL_REPORT_DESTINATION_DEVICE 和 ZCL_REPORT C. ZCL_GROUPS 和 HAL_LED=TRUE D. ZCL_READ 和 ZCL_WRITE) 答案:B

二、问答题(每题 20 分,共 60 分) ​

  1. 协调器收到一条属性上报命令后,代码层面的处理流程是怎样的?参考答案要点:
  • 产生 ZCL_INCOMING_MSG 事件,进入 zclSampleSw_event_loop();
  • 调用 zclSampleSw_ProcessIncomingMsg(),按 pInMsg->zclHdr.commandID 分流;
  • 当 commandID 等于 ZCL_CMD_REPORT 时,调用自定义函数 zclSampleSw_ProcessInReportCmd();
  • 在该函数中按 numAttr 遍历 attrList,匹配 Cluster ID 与 attrID,读取 attrData;
  • 通过 HalLcdWriteStringValue() 把值显示到屏幕,最后在 ProcessIncomingMsg 末尾 osal_mem_free(pInMsg->attrCmd) 释放内存。
  1. 为什么终端侧和协调器侧开启的宏不同?分别说明两边宏的含义。参考答案要点:
  • 终端侧开 ZCL_REPORTING_DEVICE:表示"我是上报方",协议栈编译发送上报命令相关代码;
  • 协调器侧开 ZCL_REPORT_DESTINATION_DEVICE + ZCL_REPORT:表示"我是接收方,允许处理上报命令";
  • 宏决定协议栈到底编译哪部分代码,两边各开各的;
  • 若宏开错或漏开,对应的上报/接收分支不会被编译进去,链路就不工作。
  1. 在 zclSampleSw_ProcessInReportCmd() 中,为什么要同时判断 clusterId 和 attrID?只判断其中一个行不行?参考答案要点:
  • ZigBee 节点上同一时刻可能存在多个 Cluster,且一个 Cluster 内可能有多个属性;
  • 必须同时匹配 Cluster ID(ZCL_CLUSTER_ID_GEN_ON_OFF_SWITCH_CONFIG)和 attrID(ATTRID_ON_OFF_SWITCH_TYPE),才能确认收到的正是本实验关心的那一个属性值;
  • 只匹配一个会把其他 Cluster/其他属性的上报误当成本实验数据显示;
  • 匹配成功后才读取 attrData 并通过 LCD 打印 "Rx Value:"。

aioteer · 物联网专业课程群

💬AI 伴学配置