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.

[参考译文] LAUNCJXL-CC26X2R1:重复的 zcl_SendCommandEx 呼叫中的问题仅为128次工作

Guru**** 2595805 points
Other Parts Discussed in Thread: Z-STACK

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

https://e2e.ti.com/support/wireless-connectivity/zigbee-thread-group/zigbee-and-thread/f/zigbee-thread-forum/1071478/launchxl-cc26x2r1-problem-in-repeated-zcl_sendcommandex-call-just-128-times-working

部件号:LAUNHHXL-CC26X2R1

我正在使用 SDK 提供的 ZR_genericapp_CC26X2R1_LAUNHXL_tirtos_CCS 项目。

正在运行 sendRadarDataTask(),而不是调用 zclGenericApp_Process_loo();

我正在尝试使用 zcl_SendCommandEx 发送通过 UART 接收的数据,该命令对128个软件包有效。

发送软件包129-zcl_SendCommandEx 时,函数返回0作为状态,这意味着一切正常,但:软件包不是通过 ZigBee 发送的

#include <assert.h>
#include <stdio.h>
#include <stdbool.h>
#include <strings.h>
#include "zstackmsg.h"
#include "zcl.h"
#include "uart_radaria_in.h"
#include "circular_buffer.h"
#include "slip.h"

#define GENERICAPP_ENDPOINT     (8)
#define READ_IN_BUFFER_SIZE     (512)
#define PACKET_SIZE             (512)


// Uart Read Buffers
uint8_t readInBuffer[READ_IN_BUFFER_SIZE] = { };
uint8_t packet[PACKET_SIZE] = { };
circular_buffer cb = {};
bool dataComplete = false;


void uartReceive(uint8_t *data, size_t size)
{
    int8_t ret = 0;

    if (size > 0)
    {
        uint8_t c = data[0];

        ret = cb_push_back(&cb, c);

        if (ret != 0)
        {
            printf("Circular Buffer is full\n");
            assert(ret != 0);
        }

        if (c == SLIP_END)
        {
            dataComplete = true;
        }
    }
}

void sendRadarDataTask()
{
    char data;
    ZStatus_t reply;
    uint8_t sequenceNbr = 0;
    uint16_t clusterID = 0;
    uint8_t disableDefaultRsp = 1;

    cb_init(&cb, readInBuffer, READ_IN_BUFFER_SIZE);
    uart_radaria_in_init(uartReceive);

    while (TRUE)
    {
        uart_read(&data, 1);

        if (dataComplete)
        {
            dataComplete = false;
            bzero(packet, PACKET_SIZE);
            size_t packet_size = slip_read_packet(&cb, packet, PACKET_SIZE);

            if (packet_size > 0)
            {
                afAddrType_t destAddr = { .addrMode = afAddr16Bit,
                                          .panId =0xe9ca,
                                          .addr = 0x0,
                                          .endPoint = GENERICAPP_ENDPOINT };

                reply = zcl_SendCommandEx(GENERICAPP_ENDPOINT, &destAddr, clusterID, zstackmsg_CmdIDs_AF_DATA_REQ,
                                              FALSE, ZCL_FRAME_CLIENT_SERVER_DIR, disableDefaultRsp, 0, sequenceNbr++,
                                              packet_size + 1, packet, TRUE);

                printf("Zigbee sent done '%s'- reply was 0x%x\n", packet, reply);
            }
        }
    }
}

我正在将“hello0”发送到“hello129”作为有效负载。

这是调试输出:

ZigBee 发送完成“hello0”-回复为0x0
send-wait-it 应答-返回0
ZigBee 发送完成“fhello1”-回复为0x0
send-wait-it 应答-返回0
ZigBee 发送完成“fhello2”-回复为0x0
send-wait-it 应答-返回0

ZigBee 发送完成“fhello127”-回复为0x0
send-wait-it 应答-返回0
ZigBee 发送完成“fhello128”-回复为0x0
send-wait-it 应答-返回0
ZigBee 发送完成“fhello129”-回复为0x0

这是 Wireshark 捕获:

其它打印输出来自提供的 zstackapi.c (通过打印输出修改):

/**
 * Generic function to send a request message to the ZStack Thread
 * and wait for a "default" response message.
 *
 * @param appServiceTaskId - Application Task ID
 * @param cmdID - Command ID of the message
 * @param pReq - Pointer to the request's structure
 * @param msgSize - length of the message being sent
 * @param pFnMatch - Function pointer to the response matching function
 *
 * @return zstack_ZStatusValues
 */
static zstack_ZStatusValues sendReqDefaultRsp(uint8_t appServiceTaskId,
                                              zstack_CmdIDs cmdID, void *pReq,
                                              int msgSize)
{
    zstack_ZStatusValues status = zstack_ZStatusValues_ZMemError;
    uint8_t msgStatus;

    //Make sure allocate space enought for the msg, even
    //if the message does not have payload
    if(msgSize < sizeof(zstackmsg_genericReq_t))
    {
      msgSize = sizeof(zstackmsg_genericReq_t);
    }

    zstackmsg_genericReq_t *pMsg =
        (zstackmsg_genericReq_t *)OsalPort_msgAllocate(msgSize);

    // Make sure the allocation was successful
    if(pMsg != NULL)
    {
        // Fill in the message header
        pMsg->hdr.event = cmdID;
        pMsg->hdr.status = 0;
        pMsg->hdr.srcServiceTask = appServiceTaskId;

        // Update the messges's request field
        pMsg->pReq = pReq;

        printf("SEND-");
        // Send the message
        msgStatus = OsalPort_msgSend( stackServiceTaskId, (uint8_t*) pMsg );

        // Was the message sent successfully
        if(msgStatus == OsalPort_SUCCESS)
        {
            bool gotRsp = false;

            // Return status
            zstackmsg_genericReq_t *pCmdStatus = NULL;

            while(!gotRsp)
            {
                printf("Wait-");
                // Wait for the response message
                OsalPort_blockOnEvent(Task_self());

                pCmdStatus = (zstackmsg_genericReq_t*)OsalPort_msgFindDequeue(appServiceTaskId, pMsg->hdr.event);

                if(pCmdStatus)
                {
                  gotRsp = true;
                  printf("Got reply-");
                }
            }

             // setup return of
            status = (zstack_ZStatusValues)pCmdStatus->hdr.status;
        }

        // pCmdStatus is the same as pMsg
        OsalPort_msgDeallocate( (uint8_t*)pMsg);
    }
    printf("Returning %d\n", status);
    // function status
    return(status);
}

正如您从打印输出中看到的,关于编码,一切都行之有效。

为什么 ZigBee 封装不发送? 我是否需要冲水?

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

    我忘记提到的是:这的目的是通过 Zigbee 桥接 UART,接收站点(也是 LAUNHHXL-CC26X2R1)在 ZCL 命令接收回叫时将收到的数据包写入 UART。

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

    不应在 while 循环中连续调用 zcl_SendCommandEx。 您应该创建一个定期事件来调用 zcl_SendCommandEx,而不是使用 while 循环。

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

    感谢您的快速回复: zcl_SendCommandEx 在收到完整的数据包(如果(数据完成))时被呼叫,在定期事件中处理 SendCall 的区别是什么(因为数据完成是定期的)。

    为了放慢速度,我添加了一个任务延迟,同样的行为...

     while (TRUE)
        {
            uart_read(&data, 1);
    
            if (dataComplete)
            {
                dataComplete = false;
                bzero(packet, PACKET_SIZE);
                size_t packet_size = slip_read_packet(&cb, packet, PACKET_SIZE);
    
                if (packet_size > 0)
                {
                    afAddrType_t destAddr = { .addrMode = afAddr16Bit,
                                              .panId =0xe9ca,
                                              .addr = 0x0,
                                              .endPoint = GENERICAPP_ENDPOINT };
    
                    reply = zcl_SendCommandEx(GENERICAPP_ENDPOINT, &destAddr, clusterID, zstackmsg_CmdIDs_AF_DATA_REQ,
                                                  FALSE, ZCL_FRAME_CLIENT_SERVER_DIR, disableDefaultRsp, 0, sequenceNbr++,
                                                  packet_size + 1, packet, TRUE);
                    Task_sleep(50000);
                    assert(reply == 0);
                    // printf("Zigbee sent done '%s'- reply was 0x%x\n", packet, reply);
                }
            }
        }

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

    我曾建议创建一个调用 zcl_SendCommandEx 的事件,而不是使用 while 循环。

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

    大家好,托马斯,

    有关发布/挂起事件的详细信息,请参阅  《Z-Stack 用户指南》的“线程同步”部分。  我不建议基于此功能延迟 Zigbee 应用程序任务。  您还可以等待上一条消息成功传输,并在  zstackmsg_Cmdlet _AF_DATA_CONFIRM_IND 中检查 transID,有关 详细信息,请参阅 Z-Stack 概述部分。  此外,您可能需要考虑进一步 监视堆分配 ,并在必要时增加 HEAPMGR_SIZE。

    此致,
    瑞安

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

    正如 Yikai 所说的那样,我们重新考虑了这个问题,现在它已经开始工作了,感谢您提供的更多信息

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

    很好地知道它的工作方式和我的建议一样。