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.

[参考译文] CC1352P:UART2驱动程序可以不能实时接收字节?

Guru**** 2455360 points


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

https://e2e.ti.com/support/wireless-connectivity/other-wireless-group/other-wireless/f/other-wireless-technologies-forum/1073368/cc1352p-uart2-driver-can-t-receive-bytes-in-real-time

部件号:CC1352P

我目前正在使用 CC1352上的 UART2驱动 程序,似乎该驱动程序无法以1毫秒的轮询间隔正确返回接收到的数据。 以下是我在 ti_drivers_config.c 中的配置:

static const UART2CC26X2_HWAttrs uart2CC26X2HWAttrs[CONFIG_UART2_COUNT] = {
  {
    .baseAddr           = UART0_BASE,
    .intNum             = INT_UART0_COMB,
    .intPriority        = 0xc0,
    .rxPin              = IOID_12,
    .txPin              = IOID_13,
    .ctsPin             = PIN_UNASSIGNED,
    .rtsPin             = PIN_UNASSIGNED,
    .flowControl        = UART2_FLOWCTRL_NONE,
    .rxBufPtr           = uart2RxRingBuffer1,
    .rxBufSize          = sizeof(uart2RxRingBuffer1),
    .txBufPtr           = uart2TxRingBuffer1,
    .txBufSize          = sizeof(uart2TxRingBuffer1),
    .rxChannelMask      = 1 << UDMA_CHAN_UART0_RX,
    .txChannelMask      = 1 << UDMA_CHAN_UART0_TX,
    .txIntFifoThr       = UART2CC26X2_FIFO_THRESHOLD_1_8,
    .rxIntFifoThr       = UART2CC26X2_FIFO_THRESHOLD_1_8
  },
};

和传递给 UART2_Open()的参数:

    UART2_Params rs485UARTParams = {
            /*!< Mode for all read calls */
            UART2_Mode_NONBLOCKING,
            /*!< Mode for all write calls */
            UART2_Mode_NONBLOCKING,
            /*!< Pointer to read callback function for callback mode. */
            NULL,
            /*!< Pointer to write callback function for callback mode. */
            NULL,
            /*!< Pointer to event callback function. */
            _RS485_eventCb,
            /*!< mask of events that the application is interested in */
            UART2_EVENT_OVERRUN | UART2_EVENT_BREAK | UART2_EVENT_PARITY
            | UART2_EVENT_FRAMING | UART2_EVENT_TX_BEGIN
            | UART2_EVENT_TX_FINISHED,
            /*!< Receive return mode */
            UART2_ReadReturnMode_FULL,
            /*!< Baud rate for UART */
            baud,
            /*!< Data length for UART */
            UART2_DataLen_8,
            /*!< Stop bits for UART */
            nStopBits,
            /*!< Parity bit type for UART */
            parity,
            /*!< User supplied argument for callback functions */
            NULL
    };

我有 一个计时器配置为连续回叫模式,工作频率为1000 Hz (1 ms)。 回叫功能只需每隔1毫秒返回所有接收到的 UART 数据:

static UART2_Handle m_uart;

static void _1msPeriodicTimerCb(Timer_Handle handle, int_fast16_t status)
{
    size_t nBytesRead;
    uint8_t byte;

    do
    {
        // Read 1 byte at a time.
        UART2_read(m_uart, &byte, 1, &nBytesRead);
        
        if(nBytesRead > 0)
            // Pass byte to application.
            getByte(byte);
    } while(nBytesRead > 0);
}

以19200波特,偶校验和1个停止位运行,每字节传输需要11/19200 =0.57 ms。 由于最小中断级别为32级 FIFO 的1/8,我只看到以4字节 块返回的数据。 当我向 外围设备传输8个连续的 UART 数据字节时,需要对上述回调进行4次迭代才能返回所有数据,这是有意义的,因为4个字节的物理传输需要4 * 0.58 = 2.3 ms。

  • 时间 t0 + 0 ms:4字节
  • 时间 t0 + 1 ms:0字节
  • 时间 t0 + 2 ms:0字节
  • 时间 t0 + 3 ms:4字节

但是,驱动程序似乎定期检查 FIFO,查看 UART2_READ()呼叫之外的数据。 如果我只传输1字节,回调函数最终将返回1字节。 但我没有测量延迟是什么。 在这种情况下,驱动程序如何刷新 FIFO?

使用 UART2驱动程序的另一种方法是否允许我们以1 ms 的间隔正确接收数据?

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

    您好 Derrick,

    有几个问题。

    1.您使用的是哪个 SDK 版本?

    2.我猜有一个主机发送数据。 您如何同步主机和 CC1352?

    3.使用 UART2_Mode_nonblocking 是否有特殊原因? 据我所知,在该模式下,UART2_READ()将从接收缓冲区复制尽可能多的数据。 因此,如果同步存在一些问题,这将是个问题。

    [引用 userid="411118" url="~ë/support/wireless-connectivity / other-wireless-group/other-wireless/f/other-wireless-technologies -forume/1073368/cc1352p-uart2-driver-can-t-receive-bytes 实时]但是,驱动程序似乎定期检查数据以获取外部的 FIFO 数据[

    我认为这可能是因为 UART2_Read()调用了 UART2_rxEnable(),但在读取操作完成后它没有调用 UART2_rxDisable()。 读取所需数据后,可以尝试使用 UART2_rxDisable()禁用 UART,以避免在调用 UART2_Read()时检查 FIFO 数据。

    巴西,
    安德烈斯

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    1. 我们目前使用的是 v5.20.0.52,但我确实看到了一些新版本,最高可达 v5.40.0.40。 我尝试了该版本,遇到了一整套无法编译的新问题。 我在一个单独的主题中发布了一个关于这个问题的问题: e2e.ti.com/.../cc1352p-upgrade-from-simplelink-cc13x2-26x2-sdk_5-20-00-52-to-simplelink-cc13xx-cc26xx-sdk_5-40-00-40
    2. 我正在使用 LabVIEW Modbus 程序从主机 PC 使用 USB 到 RS-485收发器进行通信,然后该收发器连接到 目标硬件板上的 RS-485收发器。 我用  逻辑分析器探测了该收发器 IC 和 CC1352之间的 UART 引脚,并已验证来自主机 PC 的数据是否已正确发送(8个连续字节,不会因我之前的帖子而延迟)。

    3. 是的,我的理解与您的理解相同:UART2_READ()应该复制尽可能多的数据,只要这些数据是可以立即获得的,但它不是基于我上面的示例。 在 返回任何数据之前,它一直在等待4个字节的接收,否则,在返回初始4个字节后,我的上述示例将不会返回0个字节。 我在非阻塞模式下使用它,因为我只需要每  毫秒将数据从 UART2驱动程序传送到第三方 Modbus 软件堆栈一次。 这是软件堆栈的具体设计方式。 如果有另一种方法可以使用不同的方式来实现这一目标,我愿意提出一些想法。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好 Derrick,

    您使用的 SDK 已相当更新,因此我不认为需要更新到新版本。

    [  引用 userid="411118" url="~ë/support/wireless-connection/other-wireless-group/other-wireless/f/other-wireless-technologies -forum/1073368/cc1352p-uart2-driver-can-t-receive-bytes 实时/3973145#3973145"]我已从主机和 UART/Uart 上一次收发器中正确发送了 CC1352字节的数据,并且没有连接上一个收发器的接线(来自上一个电路)。

    如果要发送8个连续字节,为什么每次读取一个字节? 简单地设置缓冲区并执行诸如 UART2_Read (uartHandle,缓冲区,BUFSIZE,bytesRead)之类的操作是否更好?

    此外,使用流控制更好地同步设备是否是个好主意?

    巴西,
    安德烈斯

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

    我发布的示例只是为了证明 UART2驱动程序中的缺陷。 我们正在使用此工具 来实现 Modbus RTU 和 BACnet MS/TP,两者都是异步的。  我们正在使用的 Modbus 软件堆栈要求能够以1毫秒的间隔正确检测接收到的字节,以便根据官方标准正确实施帧划分。

    我提出了一个变通办法,似乎正在通过一些有限的压力测试。 是否有更安全的方法来实施这种方法? 这里有什么缺陷吗?

    uint32_t RS485_rx(void *pDst, uint32_t nBytes)
    {
        UInt key;
        size_t nBytesRead;
    
        // Read from the rx buffer without blocking.
        UART2_read(m_uart, pDst, nBytes, &nBytesRead);
    
        if(nBytesRead == 0)
        {
            //  Begin critical section.
            key = Hwi_disable();
    
            // Check rx FIFO directly for more data.
            while((nBytes > 0) &&
                    !(HWREG(RS485_UART_BASE + UART_O_FR) & UART_FR_RXFE))
            {
                // Get byte.
                ((uint8_t *) pDst)[nBytesRead] =
                        HWREG(RS485_UART_BASE + UART_O_DR);
                // Increment indexes.
                nBytesRead++;
                nBytes--;
            }
    
            // End critical section.
            Hwi_restore(key);
        }
    
        return nBytesRead;
    }

    此外,我们是否同意 UART2驱动程序被操纵/未按预期工作?  驱动程序文档似乎意味着它应该返回收到的所有数据:

    UART2_Mode_nonblocking 不会阻止等待发送或接收数据。 UART2_WRTE()和 UART2_READ()将在传输的数据量与驱动程序可以立即接受或可用的数据量相同时立即返回。 如果无法接受或接收数据,则 UART2_WRTE()和 UART2_READ()返回 UART2_STATUS_EAGAIN.

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

    您好 Derrick,

    如果没有额外的硬件,您是否可以重现问题?

    我的主要问题是,我不知道如何将 CC1352与主机同步,以便 UART2_READ()调用成功。 我认为这可能是一个问题,因为 UART2_Read()的文档中提到了以下内容:

    UART2_Mode_nonblocking 中,UART2_Read()将返回 RX 循环缓冲区中的最小大小字节和字节数。 在此模式下,应用程序应检查 bytesRead 参数中返回的字节数。 即使未读取所有请求的字节,也将返回成功状态,除非没有可用数据或发生错误。 如果没有可用数据,则返回 UART2_STATUS_EAGAIN 的状态。

    如果您可以为我提供重现该问题的方法(代码片段),我可以检查该问题并将其升级到研发部门(如果驱动程序确实无法按预期工作)。

    巴西,
    安德烈斯