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.

[参考译文] CC1352P7:Beagleplay -在1352中使用协处理器二进制文件、配置的 Fh、200kbps -使用更大的通道列表自发重新加入的发生率更高。

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

https://e2e.ti.com/support/wireless-connectivity/sub-1-ghz-group/sub-1-ghz/f/sub-1-ghz-forum/1457530/cc1352p7-beagleplay---using-coprocessor-binary-in-1352-configured-fh-200kbps---higher-incidence-of-spontaneous-re-joins-with-larger-channel-list

器件型号:CC1352P7
主题中讨论的其他器件:UNIFLASH

工具与软件:

我要测试一个使用 Beagle Play 作为传感器网络收集器的系统。 它使用的是协处理器模型、其中的收集器在 BeaglePlay Linux 框中运行。 我注意到、在 Fh 模式下运行时、如果我将通道列表设置为8通道左右、那么该通道在运行时不会出现问题。 但是、如果配置默认的64个通道、每天每个传感器可重新连接3-10次。 出现这种情况的原因有多大? 该方法很难确定、因为它会在通道列表减少时消失、从而使数据包监听作为一种调试方法变得不切实际。

一些相关信息:

  • 都是 cc1352R1器件。
  • 网络配置为 FH、200kbps 2GFSK。
  • 传感器固件基于 DMM_154SENSOR_REMOTE_DISPLAY_OAD_APP
  • 传感器设置为每20秒发送一次数据报告、每90秒轮询一次。
  • 跟踪间隔(TRACKING_INIT_TIMEOUT_VALUE)已设置为300秒。
  • 该网络连接了9个传感器。 另一个只有两个传感器的测试网络不会出现此问题。
  • 传感器距离收集器大约10英尺、这应该可以排除饱和度问题。

我要寻找的是一些可能导致这种情况的要检查的事情的想法和/或如何缩小原因的建议。

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

    你好、Joshua:

    1. 您可以使用 SmartRF Studio 进行简单的本底噪声测试、只需在执行该测试时倾听背景噪声、即可确保测试中没有噪音干扰。
    2. 在重新连接之前、您是否能够在传感器上看到断开的原因? 了解是否有特定信道容易断开连接会很有用。
    3. 传感器是每次都是相同的、还是所有传感器之间都不同? 如果是相同的频率、您可以检查这些特定器件上的频率偏移。
    4. 您说您正在使用 DMM 示例。 在发生这种情况时、您是否也在使用 BLE?

    谢谢、

    Marie H.

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

    Marie、

    1.) 我还没有完成这项工作、但我会再次报告。

    2.) 我没有看到断开原因。 您能否提供有关如何最好地捕捉此信息的信息? 我认为可能需要检测传感器中的同步丢失回调?

    3.)它因传感器群而异。

    4.) 我只使用广告、而且很少使用。 每30秒突发4次广播。 我确实注意到、当我从恰好每30秒更改为每30.25秒时、重新连接的频率略有下降。 我这样做是因为传感器以20秒的间隔发送数据、我不希望广告与其他第三个报告周期的数据报告相媲美。

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

    Marie、

    使用的64个通道的噪声测量。 "你以为我会那么单纯吗?

    如果建议排除最差的通道、您是否有推荐的算法或方法来排除最差的通道? 是否有示例?

    此致、

    Josh

    有何影响 调整 已报告 RSSI
    0 902.4. -101.
    1. 902.8. -98
    2. 903.2. -102.
    3. 903.6. -100
    4. 904. -85.
    5. 904.4. -102.
    6. 904.8. -96.
    7. 905.2. -102.
    8. 905.6. -94.
    9. 906. -97
    10. 906.4. -101.
    11. 906.8. -85.
    12. 907.2. -100
    13. 907.6. -97
    14. 908. -95
    15. 908.4. -102.
    16. 908.8. -94.
    17. 909.2. -102.
    18. 909.6. -85.
    19. 910. -102.
    20. 910.4. -100
    21. 910.8. -90
    22. 911.2. -104.
    23. 911.599999999999 -97
    24. 911.99999999999999 -102.
    25. 912.399999999999 -93.
    26. 912.799999999999 -97
    27. 913.199999999999 -103.
    28. 913.599999999999 -96.
    29. 913.99999999999999 -102.
    30. 914.399999999999 -94.
    31. 914.799999999999 -102.
    32. 915.199999999999 -102.
    33. 915.599999999999 -100
    34. 915.99999999999999 -100
    35. 916.399999999999 -84.
    36. 916.799999999999 -100
    37. 917.199999999999 -100
    38. 917.599999999999 -90
    39. 917.99999999999999 -100
    40. 918.399999999999 -93.
    41. 918.799999999999 -102.
    42. 919.199999999999 -97
    43. 919.599999999999 -100
    44. 919.999999999999 -102.
    45. 920.399999999999 -92.
    46. 920.799999999999 -104.
    47. 921.199999999999 -102.
    48. 921.59999999999999 -102.
    49. 921.99999999999999 -102.
    50. 922.399999999999 -101.
    51. 922.799999999999 -103.
    52. 923.199999999999 -92.
    53. 923.599999999999 -104.
    54. 923.99999999999999 -95
    55. 924.399999999999 -100
    56. 924.799999999999 -102.
    57. 925.199999999999 -98
    58. 925.599999999999 -103.
    59. 925.99999999999999 -85.
    60. 926.399999999999 -102.
    61. 926.799999999999 -102.
    62. 927.199999999999 -92.
    63. 927.599999999999 -101.
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    在这种情况下、噪声似乎是一个红色错误。

    我观察到在使用协处理器配置时、来自协处理器的大量错误格式的消息、这会触发 host_collector 二进制文件中的错误。 具体来说、在文件 mT_msg.c 的函数 mT_msg_rx 中、在出现 Rx 校验和错误时重新开始解析不能正常工作。 问题在于、一旦发生错误、mt_msg 就不会复位、因此当解析重新启动时、代码会认为接收缓冲区中已经有字节、但没有字节。 这会导致无法恢复、或者恢复非常慢。 固定代码(从第25行开始更改)如下所示:

    /*!
     * @brief - read a message from the interface.
     * @param pMI - msg interface
     * @returns NULL if no message received, otherwise a valid msg
     */
    static struct mt_msg *mt_msg_rx(struct mt_msg_interface *pMI)
    {
        int r;
        int nneed;
        struct mt_msg *pMsg;
    
        /* do we allocate a new message? */
        if(pMI->pCurRxMsg == NULL)
        {
            pMI->pCurRxMsg = MT_MSG_alloc(-1, -1, -1);
            /* allocation error :-(*/
            if(pMI->pCurRxMsg == NULL)
            {
                return (NULL);
            }
            pMI->pCurRxMsg->pLogPrefix = _incoming_msg;
            MT_MSG_setSrcIface(pMI->pCurRxMsg, pMI);
        }
    
        // JVT, move this block of code down below the try_again: label, so that when
        // a checksum or other error happens, the parsing is correctly restarted.
    
        //else
        //{
        //    MT_MSG_resetMsg(pMI->pCurRxMsg, -1, -1, -1);
        //}
        // pMsg = pMI->pCurRxMsg;
        // LOG_printf(LOG_DBG_MT_MSG_traffic,
        //            "%s: rx-msg looking for start\n",
        //            pMI->dbg_name);
    
    try_again:
        /* zap what we have */
        MT_MSG_resetMsg(pMI->pCurRxMsg, -1, -1, -1);
    
        pMsg = pMI->pCurRxMsg;
    
        LOG_printf(LOG_DBG_MT_MSG_traffic,
                   "%s: rx-msg looking for start\n",
                   pMI->dbg_name);
    
    
        /* zap the existing buffer for debug reasons */
        memset((void *)(&(pMsg->iobuf[0])), 0, pMsg->iobuf_idx_max);
    
        /* how many bytes should we get? */
        nneed = (
            (pMI->frame_sync ? 1 : 0) + /* sync */
            (pMI->len_2bytes ? 2 : 1) + /* len */
            1 + /* cmd0 */
            1 + /* cmd1 */
            0 + /* unknown length yet */
            (pMI->include_chksum ? 1 : 0)); /* checksum */
    
    read_more:
        r = mt_msg_rx_bytes(pMI, nneed, pMI->intermsg_timeout_mSecs);
        if(r == 0)
        {
            LOG_printf(LOG_DBG_MT_MSG_traffic, "%s: rx-silent\n", pMI->dbg_name);
            return (NULL);
        }
    
        if(r < 0)
        {
            /* something is wrong */
            LOG_printf(LOG_DBG_MT_MSG_traffic, "%s: Io error?\n", pMI->dbg_name);
            return (NULL);
        }
    
        /* we start reading at byte 0 in the message */
        pMsg->iobuf_idx = 0;
    
        /* should we find a frame sync? */
        if(pMI->frame_sync)
        {
            /* hunt for the sync byte */
            /* and move the sync byte to byte 0 in the buffer */
            uint8_t *p8;
    
            p8 = (uint8_t *)memchr((void *)(&pMsg->iobuf[0]),
                                   0xfe,
                                   pMsg->iobuf_nvalid);
            if(p8 == NULL)
            {
                /* not found */
                MT_MSG_log(LOG_DBG_MT_MSG_traffic | LOG_DBG_MT_MSG_raw,
                           pMsg, "Garbage data...\n");
                goto try_again;
            }
    
            /* frame sync must start at zero. */
            if(p8 != pMsg->iobuf)
            {
                /* need to shift data over some */
    
                /* how many bytes to shift? */
                int n;
                n = (int)(&(pMsg->iobuf[pMsg->iobuf_nvalid]) - p8);
                /* shift */
                memmove((void *)(&pMsg->iobuf[0]), (void *)p8, n);
                /* zero what we deleted */
                memset((void *)(&(pMsg->iobuf[n])), 0, pMsg->iobuf_nvalid - n);
                pMsg->iobuf_nvalid = n;
                /* Do we have enough bytes? */
                if(nneed > pMsg->iobuf_nvalid)
                {
                    /* No - we need more, go get more */
                    goto read_more;
                }
            }
            /* DUMMY read of the sync byte */
            MT_MSG_rdU8(pMsg);
        }
    
        /* Found start */
        /* how big is our length? */
        if(pMI->len_2bytes)
        {
            pMsg->expected_len = MT_MSG_rdU16(pMsg);
        }
        else
        {
            pMsg->expected_len = MT_MSG_rdU8(pMsg);
        }
    
        pMsg->cmd0 = MT_MSG_rdU8(pMsg);
        pMsg->cmd1 = MT_MSG_rdU8(pMsg);
    
        nneed += pMsg->expected_len;
    
        /* read the data component */
        r = mt_msg_rx_bytes(pMI, nneed, pMI->intersymbol_timeout_mSecs);
        if(r != nneed)
        {
            /* something is wrong? */
            if(r > 0)
            {
                /* we got some ... but not enough .. */
                LOG_printf(LOG_DBG_MT_MSG_raw,
                    "Short read ... got: %d, want: %d, try again...\n",
                    nneed, r);
                goto read_more;
            }
            MT_MSG_log(LOG_ERROR, pMsg, "%s: expected: %d, got: %d\n",
                pMI->dbg_name, nneed, r);
        dump_recover:
            LOG_printf(LOG_DBG_MT_MSG_traffic, "Flushing RX stream\n");
            /* Dump all incoming data until we find a sync byte */
            STREAM_rdDump(pMI->hndl, pMI->flush_timeout_mSecs);
            goto try_again;
        }
    
        /* Dummy read to the end of the data. */
        /* this puts us at the checksum byte (if present) */
        MT_MSG_rdBuf(pMsg, NULL, pMsg->expected_len);
    
        /* do the checksum */
        if(pMI->include_chksum)
        {
            r = MT_MSG_calc_chksum(pMsg, 'f', pMsg->iobuf_nvalid);
            if(r != 0)
            {
                MT_MSG_log(LOG_ERROR, pMI->pCurRxMsg, "%s: chksum error\n",
                    pMI->dbg_name);
                LOG_hexdump(!LOG_ERROR, 0, pMsg->iobuf, pMsg->iobuf_nvalid);
                goto dump_recover;
            }
            else
            {
                //LOG_printf(LOG_DBG_MT_MSG, "chksum ok, message =\n");
                LOG_hexdump(LOG_DBG_MT_MSG_traffic, 0, pMsg->iobuf, pMsg->iobuf_nvalid);
            }
        }
        /* We have a message */
        MT_MSG_set_type(pMsg, pMsg->pSrcIface);
        /* Set the iobuf_idx to the start of the payload */
    
        /* since we will be parsing the message... */
        /* Set the iobuf_idx to the start of the payload */
        pMsg->iobuf_idx = (
            (pMI->frame_sync ? 1 : 0) +
            (pMI->len_2bytes ? 2 : 1) +
            1 + /* cmd0 */
            1 /* cmd1 */
           );
        /* next time we need to allocate a new message */
        pMI->pCurRxMsg = NULL;
    
        /* return our message */
        return (pMsg);
    }
    

    我也有其他发现,关于损坏数据的来源,但我将添加另一个答复。

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

    另一个发现是、MAC 协处理器肯定存在问题、这会导致消息损坏、有时还会崩溃、甚至在少数情况下覆盖闪存。

    我正在运行一个几乎未修改的收集器。 我已经添加了一个功能来读取可用堆、消息队列的状态等、并且我增加了一些堆栈大小、但除此之外、它是一个普通的 TI 项目。

    在我的测试设置中、我有8个传感器、其中3个传感器以2-10秒的间隔报告、其余5个传感器以100ms 的间隔报告、并发送~60字节的数据包。 以这种方式运行时、协处理器大约每小时会发出一次有缺陷的数据包、至少昨晚在运行大约5个小时后冻结。 由于前面所述的 host_collector 无法正确恢复问题、因此很难辨别出该问题。

    我进行了以下调查:

    1. 在本例中、我使用 UniFlash 读取整个闪存、唯一的变化是用于非易失性存储的区域。 过去、我已经看到闪存的最后一个块被擦除。
    2. 我连接了调试器、但未复位目标。 代码未正常运行、且正在存储器的0x10000000区域中运行代码。 使用 RESET 引脚复位器件不会恢复正常运行。
    3. 使用调试器中的"RESET"(重新启动)按钮的确恢复了正常运行、直到我下次通过 RESET 引脚将器件复位。 这表明启动代码中发生的事情(即调试器在使用 RESET 按钮重新启动应用时会旁路掉)是错误的。
    4. 唯一能够完全恢复正常运行的是电路板的完全断电。 上电后、没有其他变化、只要切换 RESET 线、1352就会正常引导。

    所有这一切表明类似于向预期缓冲区外部的存储器进行通配写入、可能是因为器件中的某个控制寄存器在引脚复位时未完全重新配置。

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

    你好、Joshua:

    您是否可以使用50kbps PHY 进行测试、看看它是否可再现?

    谢谢、

    Marie H.

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

    Marie、通过进一步调查(我在其他问题中已详述)、可能会发现这里的问题与1352与 BeaglePlay 之间的串行链路有关、但不可靠。 特别是、Beagle Play 在从 UART 中删除接收到的字节时会出现问题、预计这与 erratta 相关、很快就会得到解决。 此外,当发生数据丢失时, NPI 解析器无法正确恢复。 我已经解决了这个问题、它几乎消除了重新加入。

    其他帖子:
    https://e2e.ti.com/support/wireless-connectivity/sub-1-ghz-group/sub-1-ghz/f/sub-1-ghz-forum/1468716/cc1352p7-mac-coprocessor-npi-link-loses-packets---beagleplay-with-integrated-cc1352p7-radio/5675554#5675554

    https://e2e.ti.com/support/wireless-connectivity/sub-1-ghz-group/sub-1-ghz/f/sub-1-ghz-forum/1470276/cc1352p7-sub-gig-15-4-co-processor-locks-up---long-interval-between-occurrences-recovery-requires-power-cycle

    我认为我们应该关闭这张票、因为其余问题已在这两张票中解决。