This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] CC2538:通过 MT 处理传入的 AF 命令

Guru**** 655270 points
Other Parts Discussed in Thread: CC2538
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/wireless-connectivity/zigbee-thread-group/zigbee-and-thread/f/zigbee-thread-forum/1135140/cc2538-process-incoming-af-commands-through-mt

器件型号:CC2538

您好!

我想 通过 MT 处理传入的 AF 命令。 我知道我必须在某个地方调用 MT_AfIncomingMsg(),但 我不知道在哪里。

有人可以提供帮助吗?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Panagiotis、您好!

    对于 ZNP 示例、   对于 SYS_EVENT_MSG 事件的 AF_INGING_CMD 情况、它从 ZNP_APP.c -> znpEventLoop 调用。   对于 zclGenericApp_EVENT_LOOP、您可以考虑相同的情况。

    此致、
    Ryan

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我已经在  zclGenericApp_EVENT_LOOP 中添加了该内容  

      if ( events & SYS_EVENT_MSG )
      {
        while ( (MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( zclGenericApp_TaskID )) || ((pMsg = (osal_event_hdr_t *) osal_msg_receive(zclGenericApp_TaskID)) != NULL) )
        {
          switch ( MSGpkt->hdr.event )
          {
            case AF_INCOMING_MSG_CMD:         
              MT_AfIncomingMsg((afIncomingMSGPacket_t *)pMsg);
              break;

    但未输入 :case AF_INVING_MSG_CMD:

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我进行了一次捕获、尝试在其中发现基本群集属性并使用开/关群集。  

    Sniffer Link

    这是我在执行命令时看到的内容

    没有 AF 响应、因此我不知道基本 集群的属性、或者 开/关实际上是否起作用

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您是否在  项目中同时定义了 MT_AF_FUNC 和 MT_AF_CB_FUNC?  监听器日志中的哪些数据包编号与屏幕截图中显示的消息一致?  您可以发送单独的命令来读取开/关属性,我不确定您的基本属性查找消息中包含的内容。 此外、 应监视 AF_DATA_CONFIRM 以获取 AF ACK 消息。

    此致、
    Ryan

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    MT_AF_FUNC 和  MT_AF_CB_FUNC 均 已定义。

    您可以在编号2312、3004上看到开/关、  在3028上看到基本属性查找消息。  

    在屏幕截图中、显示的消息是通过协调器 USB UART 读取的 MT 命令。

    在 基本属性查找消息中,它显示 了基本群集中包含的属性。

    两条消息都是 af 数据请求。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我将  bdb_RegisterSimpleDescriptor 的 epDesc->task_id 更改为 &MT_TaskID,它现在可以正常工作。

    现在、对于每个 af 命令 、我会得到两个响应。 一个响应是我需要的响应、另一个响应是从协调器发送到协调器的 af_register_rsp。 为什么会发生这种情况?

    现在、每个 af 命令都被发送2-3次。  

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您能否发布您观察到的行为的屏幕截图?  我 猜、将  bdb_RegisterSimpleDescriptor 的 epDesc->task_id 更改为 &MT_TaskID 很可能会导致每个传入消息也进入 MT_AfCommandProcessing、并使用案例 MT_AF_register、这会导致 MT_AfRegister 被处理并返回响应。 ZNP bdb_RegisterSimpleDescriptor 将 epDesc->task_id 设置为&zcl_taskID,与 GenericApp 相同,表示这不是要进行的正确更改。  这是一个很好的机会来引用 ZNP_app.c 并注意在 znpEventLoop 中完成的操作,以使用 MT_* API 处理传入的案例。

    此致、
    Ryan

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    例如、我按"Read basic cluster 's attributes"、过程发生三次

    此外、只需启用 MT 命令、我就会获得  每次响应的 ZDO_SRC_RTG_IND_RSP。

    我 已修改事件循环以包含 ZNP 方法、但它会直接返回   

    afIncomingMSGPacket_t *MSGpkt;
    osal_event_hdr_t *pMsg;
     
     if ( events & SYS_EVENT_MSG )
      { 
        //while ( (MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( zclGenericApp_TaskID )) || ((pMsg = (osal_event_hdr_t *) osal_msg_receive(zclGenericApp_TaskID)) != NULL)) 
        while ( (MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( zclGenericApp_TaskID )))
        {
          switch ( MSGpkt->hdr.event)
          {          
            case ZCL_INCOMING_MSG:
              // Incoming ZCL Foundation command/response messages
              zclGenericApp_ProcessIncomingMsg( (zclIncomingMsg_t *)MSGpkt );
              break;
    
            case KEY_CHANGE:
              zclGenericApp_HandleKeys( ((keyChange_t *)MSGpkt)->state, ((keyChange_t *)MSGpkt)->keys );
              break;
    
            case ZDO_STATE_CHANGE:
              zclGenericApp_NwkState = (devStates_t)(MSGpkt->hdr.status);
    
              // now on the network
              if ( (zclGenericApp_NwkState == DEV_ZB_COORD) ||
                   (zclGenericApp_NwkState == DEV_ROUTER)   ||
                   (zclGenericApp_NwkState == DEV_END_DEVICE) )
              {
                giGenAppScreenMode = GENERIC_MAINMODE;
                zclGenericApp_LcdDisplayUpdate();
              }
              break;
    
            default:
              break;
          }
    
          // Release the memory
          osal_msg_deallocate( (uint8 *)MSGpkt );
        }
    
           while (((pMsg = (osal_event_hdr_t *) osal_msg_receive(zclGenericApp_TaskID)) != NULL)) 
        {
          switch (pMsg->event )
          {
            
            case CMD_SERIAL_MSG:
              MT_ProcessIncoming(((mtOSALSerialData_t *)pMsg)->msg);
              break;
            
            case AF_INCOMING_MSG_CMD:         
              MT_AfIncomingMsg((afIncomingMSGPacket_t *)pMsg);
              break;
              
            case AF_DATA_CONFIRM_CMD:
                MT_AfDataConfirm((afDataConfirm_t *)pMsg);
                break;          
    
            default:
              break;
          }
    
          // Release the memory
          osal_msg_deallocate( (uint8 *)pMsg );
        } 
        
        
        // return unprocessed events
        return (events ^ SYS_EVENT_MSG);
      }

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    所有情况都应处于相同的 while 环路下。

    //...
      if ( events & SYS_EVENT_MSG )
      {
        while ( (MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( zclGenericApp_TaskID )) )
        {
          switch ( MSGpkt->hdr.event )
          {
            case AF_INCOMING_MSG_CMD:
              MT_AfIncomingMsg((afIncomingMSGPacket_t *)MSGpkt);
              break;
              
            case ZCL_INCOMING_MSG:
              // Incoming ZCL Foundation command/response messages
              zclGenericApp_ProcessIncomingMsg( (zclIncomingMsg_t *)MSGpkt );
              break;
    //...

    此致、
    Ryan

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我很确定我已经尝试过这样的方法、但它不起作用。 我明天将再次尝试、以确保正确。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    是的、它不起作用。 它不输入 案例 AF_INGING_MSG_CMD、它直接返回 (事件^ SYS_EVENT_MSG);

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您是否定义了 MT_TASK?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    是的。 这就是我定义的

    ewarm
    CC2538_use_alternate_interrupt_map=1
    Feature_reset_macro
    SECURE=1
    TC_LINKKEY_JOIN
    NV_INIT
    NV_RESTORE
    ZTOOL_P1
    MT_TASK
    MT_UTIL_FUNC
    MT_SYS_FUNC
    MT_AF_FUNC
    MT_ZDO_FUNC
    MT_ZDO_CB_FUNC
    MT_ZDO_Mgmt
    MT_ZDO_extensions
    MT_GP_CB_FUNC
    MT_APP_FUNC
    MT_APP_CNF_FUNC
    MT_AF_CB_FUNC
    MT_NWK_FUNC
    xLCD_supported=调试
    组播启用=假
    ZCL_READ
    ZCL_WRITE
    ZCL_BASIC
    ZCL_Identify
    ZCL_REPORT_DESTINATION_DEVICE
    xLEGACY_LCD_DEBUG
    HAL_UART=true
    xHAL_SPI=true
    USB_Setup_MAX_Number_of_interfaces=5
    HAL_UART_USB
    XMT_UART_DEFAULT_O溢=假
    XMT_UART_DEFAULT_PORT

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您的申请是否已注册该端点、以及如何 按如下方式处理 afBuildMSGIngoing?

    #if defined ( MT_AF_CB_FUNC )
      // If ZDO or SAPI have registered for this endpoint, dont intercept it here
      if (AFCB_CHECK(CB_ID_AF_DATA_IND, *(epDesc->task_id)))
      {
        MT_AfIncomingMsg( (void *)MSGpkt );
        // Release the memory.
        osal_msg_deallocate( (void *)MSGpkt );
      }
      else
    #endif
      {
        // Send message through task message.
        osal_msg_send( *(epDesc->task_id), (uint8 *)MSGpkt );
      }

    此致、
    Ryan

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我认为端点已在 bdb_RegisterSimpleDescriptor 中注册

    void bdb_RegisterSimpleDescriptor( SimpleDescriptionFormat_t *simpleDesc )
    {
      endPointDesc_t *epDesc;
    
      // Register the application's endpoint descriptor
      //  - This memory is allocated and never freed.
      epDesc = osal_mem_alloc( sizeof ( endPointDesc_t ) );
      if ( epDesc )
      {
        // Fill out the endpoint description.
        epDesc->endPoint = simpleDesc->EndPoint;
        //epDesc->task_id = &MT_TaskID;   // all messages get sent to ZCL first
        epDesc->task_id = &zcl_TaskID; 
        epDesc->simpleDesc = simpleDesc;
        epDesc->latencyReq = noLatencyReqs;
    
        // Register the endpoint description with the AF
        afRegister( epDesc );
      }
    }

    afBuildMSGIngoing 的处理方式与您发送给我的处理方式相同。

    默认情况下、端点在 通用应用示例中未注册吗?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    端点是否与正在发送的传入消息相同、 并且 afBuildMSGIncoming 是否输入 MT_AfIncomingMsg 或 osal_msg_send?

    此致、
    Ryan

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    它不输入  MT_AfIncomingMsg、它直接进入 osal_msg_send。

     它是同一个端点,因为数据包详细信息显示它将其发送到正确的端点, 并且 bdb_RegisterSimpleDescriptor()参数 是 zclGenericApp_SimpleDesc  

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    此行为将确认 MT 应用程序不会截取传入数据包、因为端点未被保留以供 MT 任务处理(而是由 ZCL 任务注册端点)。  您可以尝试处理 MT_AfIncomingMsg、也 可以在输入 osal_msg_dallocate 之前不使用 osal_msg_dallocate 释放存储器、或将消息发送到 MT 任务注册的终结点、该终结点也没有附加应用程序(这会导致  在修改 bdb_RegisterSimpleDescriptor 时观察到的行为)。

    此致、
    Ryan

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我在 BuilfdMSGIngoing 中进行了此更改、现在它可以正常工作了。

    #if defined ( MT_AF_CB_FUNC )
      if(epDesc->endPoint != 0){
        MT_AfIncomingMsg( (void *)MSGpkt );
      }
    #endif
        // Send message through task message.
        osal_msg_send( *(epDesc->task_id), (uint8 *)MSGpkt );

    如果我在 zcl_event_loop 中放置 MT_AfIncomingMsg、它也同样起作用

    if ( *msgPtr == AF_INCOMING_MSG_CMD ){
        zcl_ProcessMessageMSG( (afIncomingMSGPacket_t *)msgPtr );
        MT_AfIncomingMsg( (afIncomingMSGPacket_t *)msgPtr );
    }

    感谢您的帮助!!!