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.

[参考译文] CC2340R5:UART2_WRITE 继续返回 UART2_STATUS_EINUSE

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

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

https://e2e.ti.com/support/wireless-connectivity/bluetooth-group/bluetooth/f/bluetooth-forum/1386965/cc2340r5-uart2_write-keeps-returning-uart2_status_einuse

器件型号:CC2340R5
主题中讨论的其他器件:SysConfig

工具与软件:

我的客户发现使用 UART2_WRITE 以 basic_ble 格式打印扫描报告时出现问题。 Basic_ble 被设置为中心角色、并且在 Central_Scan 357Handler -> Case BLEAPPUTIL_ADV_REPORT 中调用了 UART2_WRITE、以便在更新扫描报告时打印设备信息。 UART 在最初的几分钟内运行正常、但在之后卡住、UART Tx 不再有输出、并且 UART2_WRITE 返回-9 (UART2_STATUS_EINUSE)、该问题在没有复位的情况下无法恢复。


请按如下所示查找重现此问题的工程。 首先自由运行项目、大约3分钟后 UART Tx 将停止输出。 然后、使用"连接到正在运行的目标"方法连接 CC2340、系统会观察到 UART2_STATUS_EINUSE、即 Central_Scan 处理程序中的 UART2_WRITE 的输出-> Case BLEAPPUTIL_ADV_REPORT。

e2e.ti.com/.../scan_5F00_uart_5F00_write.7z

 谢谢、请帮助提供 UART 无法从 UART2_STATUS_EINUSE 情况中恢复的原因。

此致、

沭阳县

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

    大家好、沭阳

    您能否在 SysConfig 中更改环形缓冲区的大小、并报告是否进行了任何更改。

    此外、您可以在关闭并重新打开 UART 后再次发送数据吗?

    您还可以检查在阻塞模式和非阻塞模式下写入时是否存在相同的问题

    此致、
    Tanguy

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

    Tanguy、您好!

    我在 SysConfig 中将环形缓冲区的大小更改为1024、同样的问题将重现。

    出现问题时、我使用 UART2_writeCancel、然后再次发送数据。

    只有在写入 UART2_Mode_callback 时才会出现问题。  

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

    尊敬的 Yunwen:

    感谢您进行测试和提供更多信息。

    根据 UART2 驱动程序文档、在回调模式下、在驱动程序准备好接受另一个写入操作时、将调用用户的回调函数。 我认为您遇到的问题是由于需要写入大量数据、并且 UART 未准备好进行另一个写入操作。

    您能否提供有关用例的更多详细信息? 如果可能、我建议注册 BLEAPPUTIL_SCAN_DISABLED 事件以处理收到的所有广播报告。

    如果要继续在  BLEAPPUTIL_ADV_REPORT 中记录信息、建议使用非阻塞模式或在代码中添加一些逻辑、以便仅在调用用户的回调时发送写入命令。

    尽管如此、我会对这种行为进行进一步调查、因为我不知道是否会发生这种情况。

    我希望这对您有所帮助、
    Tanguy

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

    Tanguy、您好!

    我们已经尝试使用回调模式,然后确定它是否是 alreadyin 传输前发送,但这种现象仍然发生。

    是否预期会出现此问题的行为、是否有任何进度更新?

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

    Tanguy、您好!

    我还在 LaunchPad 上重现了此问题。 我认为这里的关键问题是、即使没有更多数据放入 Tx 缓冲区、UART 也无法从情况中恢复。

    我检查了 UART 驱动程序代码、当 发生 UART2_STATUS_EINUSE 时、未执行实际的 Tx 命令。 理想的行为是 UART 在 UART2_STATUS_EINUSE 购买期间将缓冲区中的左侧数据发送出去、并在 Tx 缓冲区清除后 UART 返回工作。 但 UART 以某种方式停留在 UART2_STATUS_EINUSE 中、并且无法恢复、除非调用 UART2_writeCancel、它查看数据卡在缓冲区中、并停止 UART 以获取新数据。

    沭阳县

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

    您好!

    我设法在我这边重现了问题、UART 专家目前不在办公室、我需要他们的帮助来解决这个问题。 作为临时工作、您可以使用下面的代码片段吗?

    test_status = UART2_write(uart, "BLEAPPUTIL_ADV_REPORT\r\n", strlen("BLEAPPUTIL_ADV_REPORT\r\n"), NULL);
    if (test_status == UART2_STATUS_EINUSE)
    {
        ((UART2_Object *)uart->object)->writeInUse = 0;
    }

    我在 UART 未卡住的情况下运行此代码10分钟、但是、这段代码尚未经过完整测试。

    此致、
    Tanguy

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

    Tanguy、您好!

    通过这种方法、我认为问题不会完全解决。 串行端口有时会少输出一个字节的数据。 这在上电和开始扫描时尤其可能发生。

    在我们的应用程序中、我们需要在 BLEAPPUTIL_ADV_REPORT 事件中打印 MAC 和 RSSI、如下所示:  

    使用上述方法时、串行端口的数据输出有时会出现数据错误

    对此问题是否有合理的解释?为什么向 BLEAPPUTIL_ADV_REPORT 事件添加打印会导致串行端口数据输出出现问题。

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

    您好!

    我认为此问题可能与 DMA 有关。 您是否可以在中为我尝试以下操作${SDK_INSTALL_DIR}\source\ti\drivers\uart2\UART2LPF3.c、找到以下行:

    和替换  UDMA_ARB_4 演示  UDMA_ARB_2 如下所示:

    #define TX_CONTROL_OPTS (UDMA_SIZE_8 | UDMA_SRC_INC_8 | UDMA_DST_INC_NONE | UDMA_ARB_2 | UDMA_MODE_BASIC)

    请告诉我、此解决方法是否适合您。 本周结束时、我将与驾驶员专家讨论、就这一问题提出更多想法和建议。

    此致、
    Tanguy

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

    您好!  

    根据您的说明、我们通过添加或删除前面提到的权变措施修改了 UART2LPF3.c 文件、然后完全重新编译了工程、但问题没有得到改善。

    期待有关该问题的更多主题。

     

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

    尊敬的 Tan:  

    您是否将  UART2LPF3.c 文件复制到您的项目并重新构建了该项目? 需要将文件包含到工程中以应用更改。

    BR、

    沭阳县

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

    大家好、沭阳

    我的道歉,我漏掉了一个步骤。 是的、我必须将 UART2LPF3.c 从 source\ti\drivers\复制到我的项目中才能重建它。

    此致、
    Tanguy

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

    您好!

    我已将 UART2LPF3.c 文件复制到工程目录中并重建了它、但问题仍未解决。

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

    您好!

    回顾一下这个问题、我认为这个问题来自回调模式的使用、如 UART2文档中所述

      在 UART2_Mode_callback 中传递给 UART2_WRITE ()的缓冲区必须保持一致,直到所有字符都发送完毕(即在调用 TX 回调时,字节计数等于传递给 UART2_WRITE ())

    我认为应该对您的代码进行2次修改:

    1. 将 buff 声明为静态
    2. 使用全局变量检查 UART 写入是否已准备就绪

    请看下面的代码片段:

    // in app_main.c
    int writeReady = 1;
    void STTM_uartWriteCallBack(UART2_Handle handle, void *buf, size_t count, void *userArg, int_fast16_t status)
    {
    
        writeReady = 1;
    }
    
    
    
    // In Central_ScanEventHandler
     case BLEAPPUTIL_ADV_REPORT:
            {
                extern int writeReady;
                static char buff[128] = {0};
                if (writeReady)
                {
                    writeReady = 0;
                    snprintf(buff, sizeof(buff), "MAC:%02X%02X%02X%02X%02X%02X,RSSI:%d\n",
                            scanMsg->pBuf->pAdvReport.addr[5],
                            scanMsg->pBuf->pAdvReport.addr[4],
                            scanMsg->pBuf->pAdvReport.addr[3],
                            scanMsg->pBuf->pAdvReport.addr[2],
                            scanMsg->pBuf->pAdvReport.addr[1],
                            scanMsg->pBuf->pAdvReport.addr[0],
                            scanMsg->pBuf->pAdvReport.rssi);
    
                    test_status = UART2_write(uart, buff, strlen(buff), NULL);
                }
                break;

    此致、
    Tanguy

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

    您好!

    我参考了给定的代码、然后修改了我的项目进行测试。 最初测试正常10分钟左右,但当我每隔几分钟重新通电,以这种顺序进行测试时,问题似乎是没有来自串行端口的数据输出。


    通过调试、我发现当问题发生时、writeReady 变量始终为0、并且扫描事件 BLEAPPUTIL_ADV_REPORT 正在连续生成。 这似乎是由于未始终生成 STTM_uartWriteCallBack 函数回调引起的。 下面是我在 STTM_uartWriteCallBack 回调中遇到断点的地方、您可以看到 writeReady 保持为0、而不进入回调函数、最终导致没有串行端口数据输出。

     

    为了确定问题、我再次上传了该代码、以防缺少相关信息

    e2e.ti.com/.../scan_5F00_uart_5F00_write.zip

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

    您好!

    为了进行完整性检查、您 writeReady = 0; 是否可以在 USER_UART_INIT 中的 UART2_WRITE 之前再次进行测试?

    我已尝试使用复位按钮对器件下电上电多次、但无法重现错误、能否详细介绍一下重现故障的步骤:

    • 您多久对其进行一次重新供电?
    • 您如何对其重新供电?
    • 您是否看到 UART 终端中发送了任何消息?

    此致
    Tanguy

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

    你(们)好

    问题没有在您的终端上重现、我怀疑它可能与周围的器件数量有关。 我已经在 USER_UART_init 的 UART2_WRITE 前面添加了 writeReady = 0、这也重现了问题。 在重现问题之前、串行端口会打印所有正常内容、直至发生问题时串行端口发送停止。

    我的测试步骤为:
    1.通过调试烧录程序后、退出仿真、运行复位管脚、在器件上执行硬件复位、然后开始测试。
    2.测试3分钟后、如果问题不再出现、请重新启动设备(硬件重置)。
    3.重复步骤2、直至问题再次出现。 在我的测试环境中、可以重复出现问题大约2-3次。

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

    您好!

    感谢您提供我将尝试重现此问题的信息。

    同时、我注意到我们没有相同的日志、似乎您正在添加时间:

    此信息是否也通过 UART 记录? 它是否是问题的根源? 对于完整性检查、仅当 UART 已准备好发送一些数据时发送该值、方法是测试 writeReady 是否为1并在写入之前将其设置为0。

    此致
    Tanguy

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

    您好!

    我没有在程序中添加时间戳打印、它是由串行终端自动添加的。 串行端口发送函数"UART2_WRITE"仅在串行端口初始化之后以及在 BLEAPPUTIL_ADV_REPORT 事件中调用、如我提供的代码示例所示。 代码确保 writeReady 在发送前为1、并在发送前设置为0。

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

    您好!

    我收到一份关于 UART 驱动程序中可能存在竞态情况的报告、我认为您会遇到这种情况、您能否尝试进行以下更改、并报告此更改是否有任何变化:

    1. 从导入 UART2.c /source/ti/drivers 加载到您的工作区
    2. 从导入 UART2LPF3.c  /source/ti/drivers 加载到您的工作区
    3. 在 UART2_writeTimeoutBlocking 的 UART2.c 中进行以下更改:
    4. 在 UART2LPF3.c 中、找到 UART2Support_dmaStartTx 并添加  UARTClearInt(hwAttrs->baseAddr, UART_INT_EOT); below


    仍需要在发送数据之前检查 writeReady 的值。

    此致
    Tanguy

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

    您好!

    经过长达一个多小时的测试后、目前没有可重现的问题。
    我们将继续进行测试、如果发现任何问题、我们将在此处报告。 为了确保将来没有缺陷、我对 UART 有一些问题?


    1.可以在写回调中使用 UART2_WRITE 来再次启动串行传输吗? 同样、对于读回、我可以在回调中使用 UART2_READ 再次打开接收吗?


    2.是否仍然需要保留前面提到的权变措施。

    #define TX_CONTROL_OPTS (UDMA_SIZE_8 | UDMA_SRC_INC_8 | UDMA_DST_INC_NONE | UDMA_ARB_2 | UDMA_MODE_BASIC)

    它是否仍然需要保持不变。


    3.我可以使用 writeInUse 为变量 writeReady 判断、例如:

    if (!((UART2_Object *)uart->object)->writeInUse )
    {
        snprintf(buff, sizeof(buff), "MAC:%02X%02X%02X%02X%02X%02X,RSSI:%d\n",
                scanMsg->pBuf->pAdvReport.addr[5],
                scanMsg->pBuf->pAdvReport.addr[4],
                scanMsg->pBuf->pAdvReport.addr[3],
                scanMsg->pBuf->pAdvReport.addr[2],
                scanMsg->pBuf->pAdvReport.addr[1],
                scanMsg->pBuf->pAdvReport.addr[0],
                scanMsg->pBuf->pAdvReport.rssi);
    
        test_status = UART2_write(uart, buff, strlen(buff), NULL);
    }

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

    您好!

    很高兴听到这种情况可以解决您的问题、我将与我的团队一起确定此问题的优先级、并在即将推出的 SDK 中修复。

    1.可以、可以在写回调中使用 UART2_WRITE 再次启动串行传输、因为可以在读回调中使用 UART2_READ。

    2.无需保留此变通办法。

    3.为避免将代码迁移到较新的 SDK 版本时可能出现的问题,我建议使用writeReady而不是访问应用代码中的内部字段。

    此致、
    Tanguy