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.

[参考译文] CC1312R:在 TI RTOS 中运行 rfPacketTx 示例、了解如何实现更高的传输速率

Guru**** 2555260 points
Other Parts Discussed in Thread: SYSCONFIG

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

https://e2e.ti.com/support/wireless-connectivity/sub-1-ghz-group/sub-1-ghz/f/sub-1-ghz-forum/1041717/cc1312r-running-rfpackettx-example-in-ti-rtos-how-to-achieve-higher-transmit-rate

器件型号:CC1312R
Thread 中讨论的其他器件:SysConfig

您好:

  我在一个 CC1312上运行修改后的 rfPacketTx、在另一个 CC1312上运行 rfPacketRx。

我已经更改了示例代码、以以1Mbps 的速率背靠背传输8字节数据包

350 KHz 偏差2 GFSK 2.2 MHz PHY 类型。  我使用 RF_runCmd 来调度传输

和接收。  在 接收时、我只能实现大约13KB = 104kbps/秒的速率。  理论上、

我应该能够以更高的速率进行传输和接收。  请注意、我确实会采集数据包

发送端的 UART 接口发送、但这不是瓶颈。  我有大缓冲器  

在发送端、我调用 RF_runCmd、以在我采集时尽快调度传输

数据。 我尝试了各种代码更改、以及提高吞吐量的唯一方法

似乎每次传输都使用较大的数据包。  因此、数据速率似乎出现瓶颈

每秒可运行的实际传输数。  有人知道吗

限制是(由硬件或 TI RTOS 调度程序控制?)  所有传输示例代码中都有一个

可以看到、每次调用 RF_runCmd 之间都有一个传输间隔。  在 SmartRF 上为默认值

间隔设置为10毫秒、可设置的最小值为1毫秒。  在 rfPacketTx 示例中、

默认间隔为500毫秒。  我在代码中删除了这些间隔并背靠背调用 RF_runCmd、

在我的情况下、我没有看到任何数据包损坏或丢放在接收端。  是传输

时间间隔是必要的、为什么示例具有如此大的时间间隔?  请注意、之后我不会调用 RF_Yield

从而使无线电始终运行。

最重要的是、我需要找到一种方法来使用小数据包(<= 8字节)实现更高的吞吐量。

我是否可以使用 rf_runCmd 属性或 TI RTOS 调度程序执行某些操作?

谢谢、

TW

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

    尊敬的德克:

    无需传输间隔、您可以在没有传输间隔的情况下运行。  

    听起来、当器件等待来自 UART 的数据时、您会看到延迟。 为了了解发生了什么、您能否使用逻辑分析仪查看 UART 引脚以及 RF 引脚?

    您可以在此处找到有关调试射频输出的说明:

    https://dev.ti.com/tirex/content/simplelink_cc13x2_26x2_sdk_5_20_00_52/docs/proprietary-rf/proprietary-rf-users-guide/proprietary-rf-guide/debugging-index.html#debugging-rf-output

    谢谢、

    玛丽·H.

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

    玛丽:

      感谢您的快速响应。   我将 UART 线速设置为460800、可以看到 CC1312无延迟地读取数据。

    我还尝试不使用 UART 来获取数据。  相反,我对数据使用静态缓冲区,并运行 RF_runCmd()以发送相同的数据

    一遍又一遍。  在接收端、我使用标准 rfPacketRX 代码连续接收。

    我看到的是、我在无延迟运行 RF_runCmd ()时、经过一段时间后、接收端将停止接收。  如果我输入延迟、可能

    usleep (100)、接收端将继续接收。  如果我使传输数据包变大、吞吐量也相应地提高。

    在我看来、对讲机可以在每个时间段传输一定数量的数据包。  这可能与调度程序或驱动程序有关?

    我尝试运行 NO_RTOS 代码、但没有看到任何改进。  我正在设置一个测试台来测量时序。  但您有没有

    是否有使用 RF_runCmd ()获得高吞吐量的示例?

    谢谢、此致、

    TW

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

    玛丽:

      您对 UART 所说的内容让我思考。  我认为在发送端没有问题、但我在接收端进行了双次检查、可以看到一些潜在的问题。  我正在将接收到的数据包从通过 UART 接收的 CC1312推送到 Raspberry PI。  Raspberry 上没有问题。  但是、在 CC1312上、我在回调上下文中调用 UART_write()。  使用 TI_RTOS 执行该操作是否存在问题?  我知道我需要使用 no_RTOS 为 UART_MODE_CALLACK 配置 UART_WRITE。  我还注意到、如果 I UART_WRITE 超过12个字节、CC1312将挂起。  正如您告诉我的那样、我将尝试调试 UART 接口。  我将告诉您这是否能解决我的问题。

    谢谢、

    TW

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

    玛丽:

       很抱歉告诉您修复接收器中的 UART 接口不能提高吞吐量、尽管将其配置为 UART_MODE_CALLING 允许通过 UART 进行更大的传输。  接收端的数据速率保持不变。  如果您可以向我展示一些使用 RF_runCmd 实现高数据速率的示例、那将会非常有帮助。

    谢谢、

    TW

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

    尊敬的德克:  

    使用 CMD_PROP_TX_ADV 命令进行传输可能会让您受益。 这允许您传输长度不受限制的数据包。  

    请查看 技术参考手册的第25.10.5.3.2节。 此外、此 e2e 线程可能会作为起点有所帮助。  

    https://e2e.ti.com/support/wireless-connectivity/sub-1-ghz-group/sub-1-ghz/f/sub-1-ghz-forum/594277/cc1310-cmd_prop_tx_adv-example

    此致、

    Siddanth

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

    您好 Siddanth 和 Marie:

       非常感谢您对我的问题的回答。  我确实尝试使用了您建议的命令、我更深入地研究了 RF_runCmd、RF_postCmd 和 RF_pendCmd 的源代码。  因此、要传输的数据包被放入命令队列中。  RF_PendCmd 等待直到无线电空闲并传输挂起的数据包。  此操作模型将不适用于我的设计。  我希望能够在发出命令后的100 μ s 内将数据包发送到空中。  我将传输多达32个背对背数据包、每个数据包在100 us 内、然后等待一毫秒、然后再次传输32个数据包。  在我发出发送命令后、每个数据包必须在100 μ s 内发出。  是否有更低级、更原始的驱动程序可帮助我执行此操作?  RF_runCmd 支持 absTime 进行传输、但以毫秒为单位。  我的程序将从一个源传输、并且不会运行任何其他进程。  如果您可以向我介绍一些有关如何实现基元驱动程序的参考代码或文档、我将不胜感激。

    此致、

    TW

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

    我发现 RF_cmdPropTX 的配置有一个外部触发器选项。  我将尝试连接一个 GPIO 信号、并查看我是否可以将传输与该信号对齐。

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

    尊敬的德克:

    100us 听起来很高。 如果可以将数据包预装载到缓冲区中、可能会有所帮助。

    让我知道、好了。

    谢谢、

    玛丽·H.

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

    如果您需要在数据包 n 的最后一个字节和数据包的第一个字节(n+1)之间连续传输数据包、则需要使用无限数据包长度模式、并在一次传输中发送所有数据包(您需要手动插入前导码/同步、CRC 等)。 以下是如何实现这一目标的示例:

    https://e2e.ti.com/support/wireless-connectivity/sub-1-ghz-group/sub-1-ghz/f/sub-1-ghz-forum/594277/cc1310-cmd_prop_tx_adv-example/2184712#2184712

    如果您希望一个接一个地传输数据包、并让射频内核负责生成前导码、同步、CRC 等)、即使您使用命令链接、数据包之间也会有大约150us 的延迟。

    BR

    Siri

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

    Marie 和 Siri:

      感谢您的建议。  我已经尝试过外部触发器选项。  我想这就是我想要的。  但是、信号之间的间隔大于我需要的间隔。  我已经了解了 Siri 的示例、这可能会提供解决方案。  我想确保我理解这一点。  如果我需要3字节前导码、4字节同步字和6字节有效负载、txSyncPacket 应该与此类似?

    静态 uint8_t txSyncPacket[]={

                                /********* /

                                0x55、0x55、0x55 //前导码

                                0x91、0xD3、0x91、0xD3、//同步字

                                0x06 //长度字节

                                0xAA、0xBB、0xCC、0xDD、0xEE、 0xFF // 6字节有效载荷

                                /********* /

                            };

    在下面的示例中、实际同步字之前有11 0x55。  不确定我是否理解同步字之前的0x55

    如果我不需要 CRC、我应该在 RFC_CMD_PROP_TX_ADV 结构中将其关闭?

    静态 uint8_t txSyncPacket[]={  

                              /********* /

                              0x55、0x55、0x55、0x55、//前导码

                              0x55、0x55、0x55、0x55、0x55、 0x55、0x55、0x55、0x55、0x55、 0x55、0x91、0xD3、0x91、0xD3、 //同步字

                              0x01、//长度字节

                              0x01 //虚拟字节有效载荷  

                              /********* /};

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

    关于 CRC、您需要关闭 TX API 中的 CRC (否则、它将在您发送的所有数据包(包括前导码、同步等)上生成 CRC

    如果要使用 CRC、需要在 SW 中计算此值并手动将其写入数据包。

    我创建这个示例已经很长时间了、因此我不记得为什么我发送这么多字节的前导码。 我猜是我使用了正常的 rfPacketRX 示例作为接收器、它可能会很快地接收数据包、因此我在 TX 端添加了额外的前导码、以便在数据包之间添加一些"延迟"。

    如果您发送的数据包不多且不长、则可能可以使用正常的 TX 命令和固定数据包长度模式、然后将所有数据包写入您发送的一个数据包中:

    下面的3个数据包可以使用固定的数据包长度发送、并将长度设置为51

    txPacket[51] = {
                    // Packet 1
                    0x55, 0x55, 0x55, 0x55,
                    0x91, 0xD3, 0x91, 0xD3,
                    0x06,
                    0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 
                    CRC, CRC, // Optional
                    // Packet 2
                    0x55, 0x55, 0x55, 0x55,
                    0x91, 0xD3, 0x91, 0xD3,
                    0x06,
                    0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 
                    CRC, CRC, // Optional
                    // Packet 3
                    0x55, 0x55, 0x55, 0x55,
                    0x91, 0xD3, 0x91, 0xD3,
                    0x06,
                    0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 
                    CRC, CRC, // Optional
                }

    Siri

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

    SIRI:

      感谢您的回复。  是的、这种方法可能是我想要的。  我已将 rfPacketTx 驱动程序更改为不使用 CRC。  我想我理解您在上面使用3个数据包的新示例。  我将尝试它。  但是、如何在 rfPacketTx.syscfg 中关闭前导码和同步字?  我使用的是1Mbps 协议。  PHY 配置需要选择前导码长度和同步字。  在配置或 RF_CMD_PROP_TX_t 结构中、似乎无法关闭它们。  对于 CRC、我可以在该结构中将 UseCrc 位设置为0。  我想我的目标已经接近了。  我将告诉您您您的示例是否可以解决我的问题。  另一个问题: 如果我插入我自己的前导码和同步字-例如3字节前导码和4字节同步字、并且接收器在 rfPacketRx.syscfg 中进行配置、那么我仍然可以使用同一接收器而不更改代码中的任何内容、对吧?

    谢谢、此致。

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

    在 SysConfig 中、您可以将前导码设置为1位、将同步字设置为0x55 (在 TX 中)。 然后,在开始发送 TX 数据包中的内容之前,将发送9个“前导码”位。

    我执行了一个快速测试、在该测试中、我刚刚使用了正常的 TX 功能和固定的数据包长度、并发送以下3个数据包:

    数据包1:  0x05、0x01、0x02、0x03、0x04、 0x05

    数据包2:  0x05、0xA1、0xA2、0xA3、0xA4、 0xA5

    数据包3:   0xB5、0xB1、0xB2、0xB3、0xB4、 0xB5

    数据包完成数据包如下所示:

    static uint8_t txPackets[] = {
        0x55, 0x55, 0x55,		        // Preamble (9 bits sent automatically)
        0x93, 0x0B, 0x51, 0xDE,         // Sync Word
        0x05,                           // Length byte
        0x01, 0x02, 0x03, 0x04, 0x05,   // Payload
        0xA8, 0x84,                     // CRC
    
        0x55, 0x55, 0x55, 0x55, 0x55, 0x55, // Preamble
        0x93, 0x0B, 0x51, 0xDE,         	// Sync Word
        0x05,                               // Length byte
        0xA1, 0xA2, 0xA3, 0xA4, 0xA5,       // Payload
        0x50, 0xFD,                         // CRC
    
        0x55, 0x55, 0x55, 0x55, 0x55, 0x55, // Preamble
        0x93, 0x0B, 0x51, 0xDE,             // Sync Word
        0x05,                               // Length byte
        0xB1, 0xB2, 0xB3, 0xB4, 0xB5,       // Payload
        0x76, 0x5B                          // CRC
    };
    

    我将正常 rfPacketRX 示例用作接收器(使用前导码和同步的正常设置)

    如果我没有在数据包1和2以及2和3之间发送2个额外的前导码字节、那么我将只能为我的循环的每次迭代(每个 txPacets 被发送)接收数据包1和3。

    我认为这是因为接收到数据包后、接收器需要重新启动同步搜索等、 即使您使用重复模式、这也需要一些时间、因此如果发送器仅传输4个字节的前导码、您可能仅在这些字节的2到3之间接收、这不是能够可靠地检测同步字的要求。

    我的代码如下:

    /***** Includes *****/
    /* Standard C Libraries */
    #include <stdlib.h>
    #include <unistd.h>
    
    /* TI Drivers */
    #include <ti/drivers/rf/RF.h>
    #include <ti/drivers/PIN.h>
    #include <ti/drivers/pin/PINCC26XX.h>
    
    /* Driverlib Header files */
    #include DeviceFamily_constructPath(driverlib/rf_prop_mailbox.h)
    
    /* Board Header files */
    #include "ti_drivers_config.h"
    #include <ti_radio_config.h>
    
    #include "RFQueue.h"
    
    /***** Defines *****/
    
    /* Packet TX Configuration */
    #define PACKET_INTERVAL     50000  /* Set packet interval to 50000 us or 50 ms */
    
    
    /***** Prototypes *****/
    
    /***** Variable declarations *****/
    static RF_Object rfObject;
    static RF_Handle rfHandle;
    
    /* Pin driver handle */
    static PIN_Handle ledPinHandle;
    static PIN_State ledPinState;
    
    /*
     * Application LED pin configuration table:
     *   - All LEDs board LEDs are off.
     */
    PIN_Config pinTable[] =
    {
        CONFIG_PIN_GLED | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL | PIN_DRVSTR_MAX,
        PIN_TERMINATE
    };
    
    /* The buffer below contains a packet that is sent back-to-back TX_BUFFERS_TO_SEND every PACKET_INTERVAL. */
    static uint8_t txPackets[] = {
    
                                    0x55, 0x55, 0x55,               // Preamble (8 bits sync word (0x55) cound as the first preamble byte
                                    0x93, 0x0B, 0x51, 0xDE,         // Sync Word
                                    0x05,                           // Length byte
                                    0x01, 0x02, 0x03, 0x04, 0x05,   // Payload
                                    0xA8, 0x84,                     // CRC
    
                                    0x55, 0x55, 0x55, 0x55, 0x55, 0x55, // Preamble
                                    0x93, 0x0B, 0x51, 0xDE,         // Sync Word
                                    0x05,                           // Length byte
                                    0xA1, 0xA2, 0xA3, 0xA4, 0xA5,   // Payload
                                    0x50, 0xFD,                     // CRC
    
                                    0x55, 0x55, 0x55, 0x55, 0x55, 0x55, // Preamble
                                    0x93, 0x0B, 0x51, 0xDE,         // Sync Word
                                    0x05,                           // Length byte
                                    0xB1, 0xB2, 0xB3, 0xB4, 0xB5,   // Payload
                                    0x76, 0x5B                      // CRC
    };
    
    static uint8_t packetCounter = 0;
    
    void *mainThread(void *arg0)
    {
        RF_Params rfParams;
        RF_Params_init(&rfParams);
    
        /* Open LED pins */
        ledPinHandle = PIN_open(&ledPinState, pinTable);
        if (ledPinHandle == NULL)
        {
            while(1);
        }
    
        RF_cmdPropTx.pktLen = sizeof(txPackets);
        RF_cmdPropTx.pktConf.bVarLen = 0;
        RF_cmdPropTx.pPkt = txPackets;
        RF_cmdPropTx.startTrigger.triggerType = TRIG_NOW;
        RF_cmdPropTx.pktConf.bUseCrc = 0;
    
        /* Request access to the radio */
        rfHandle = RF_open(&rfObject, &RF_prop, (RF_RadioSetup*)&RF_cmdPropRadioDivSetup, &rfParams);
    
        /* Set the frequency */
        RF_postCmd(rfHandle, (RF_Op*)&RF_cmdFs, RF_PriorityNormal, NULL, 0);
    
        while(packetCounter++ < 10)
        {
            /* Send packet */
            RF_runCmd(rfHandle, (RF_Op*)&RF_cmdPropTx, RF_PriorityNormal, NULL, 0);
    
            PIN_setOutputValue(ledPinHandle, CONFIG_PIN_GLED,!PIN_getOutputValue(CONFIG_PIN_GLED));
    
            /* Power down the radio */
            RF_yield(rfHandle);
    
            /* Sleep for PACKET_INTERVAL us */
            usleep(PACKET_INTERVAL);
        }
        while(1);
    }

    BR

    Siri

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

    感谢 Marie H、Siddanth_N 和 Siri。  您将信息和示例结合在一起、帮助我解决了我以更高的速率传输数据的问题。

    此致、

    TW