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:调用 sleep ()然后调用 UART2_open ()无法打开 UART

Guru**** 2594660 points
Other Parts Discussed in Thread: CC2340R5

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

https://e2e.ti.com/support/wireless-connectivity/bluetooth-group/bluetooth/f/bluetooth-forum/1357699/cc2340r5-call-sleep-then-call-uart2_open-can-not-open-uart

器件型号:CC2340R5

CCS 版本:12.7.0

ARM 编译器版本:3.2.LTS

SYSCFG 版本: 1.20.0


我在 SDK 的 basic_ble 工程中每分钟测试一次 UART 函数:7.40.00.64。 当我第一次打开 UART 时,它是正常的,然后我也调用 UART2_CLOSE ()来关闭它,但只要我叫 sleep ()或 usleep ()。 因此,我对 UART2_OPEN()的第二次调用失败。 我使用调试模式检查并发现在 UART2_OPEN()中的 object->state.opened 设置为 true,结果返回 NULL,但我确定调用 UART2_CLOSE()后,object->state.opened 设置为 false,但调用 sleep()后将设置为 true。

我将相同的代码编写到了 SDK:7.10.00.35、但事实并非如此。

调用 UART2_CLOSE()和调用 sleep()在不同的线程中。 是因为它先进入 sleep(),所以 UART2_close()实际上没有成功执行吗?

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

    您好!

    调用 UART2_close()和调用 sleep()是在不同的线程中。 是因为它先进入 sleep(),所以 UART2_close()实际上没有成功执行吗?

    否、调用睡眠模式只会在没有其他已准备好运行的线程的情况下使器件进入低功耗模式。 在本例中、似乎 UART 线程已准备好运行。

    当调用 UART2_OPEN 时、UART 驱动程序将通知电源驱动程序 UART 正在使用中、因此电源驱动程序将确保维持所需的电源模式以确保 UART 正常运行。 调用 UART2_Close 时、UART 驱动程序会通知电源驱动器不再依赖于 UART 的功耗。

    Unknown 说:
    CCS 版本:12.7.0

    我已经注意到 至少一个其他 E2E 帖子、其中使用 CCS 12.7导致了异常行为: https://e2e.ti.com/support/wireless-connectivity/bluetooth-group/bluetooth/f/bluetooth-forum/1357887/cc2652r7-consecutive-builds-without-code-change-results-in-different-hex-files

    您能否尝试这些测试并分享结果:

    1. 运行基于 SDK 7.10和 CCS 12.7构建的相同代码
    2. 运行由 SDK 7.40和早期 CCS (最初用于 SDK 7.10)构建的相同代码\

    谢谢。
    托比

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

    您好、Toby:

    关于您提到的测试:

    (1)本文中描述的7.10.00.35版本使用 CSS 12.7.0进行调试,但这不会发生。


    (2)我之前使用的是 SDK 7.10版本、而我使用的 CCS 版本是12.2版本。 但是、当我使用 CCS 12.2执行 SDK 7.40时、它会固定在 while (1) About RCL 中。 当时、我在论坛上提出了相关问题、工程师给我的回复是更新 CCS 版本、然后我将 CCS 更新为12.7、因此我无法提供 SDK 7.40和 CCS 12.2的测试结果。

    此外、我在测试过程中发现、当我调用 sleep (1)时会发生上述情况、但如果我将其更改为 usleep (50000)、则会在我第二次打开 UART2_open 后成功、然后我尝试将其更改为 usleep (100000)。 仍然无法打开

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

    感谢您确认并提供更多详细信息。

    这个问题似乎 与 SDK 版本相关。

    您能否共享一些有关如何设置这两个线程的代码片段(1.调用 UART2_open/close 的线程;2. 线程调用睡眠)?

    问题是否 100%出现? 或者 UART2_Close --> UART2_open 是否在某些情况下正常工作?

    谢谢。
    托比

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

    (1)我在 app.main.c 的 App_Stack itDoneHandler()中调用 sleep(1),并为 UART 专门创建了一个单独的线程。

    (2)每次都要发生

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

    明白了。

    我将对此进行了解、并在3个工作日内在此处进行更新。

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

    好的, 我也在这里找到了一些线索

    我发现这种情况也可以在 UART 自身的线程中发现。 它似乎并不一定发生,当一个不同的线程调用 sleep()时,我测试了这种情况会发生,只要设置超过 usleep(16000),但我有其他设置 sleep(1)本地不会影响它,这是相当奇怪的。 在 UART2_OPEN()无法打开之前,它可能会被触发或达到某些条件,我使用单步 UART2_OPEN()来查看函数内部。 ,原因似乎是 UART 确定 object->state.opened == 1

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

    您好、Ryan、

    我对此进行了更深入的研究、但无法重现问题。

    我也使用7.40 SDK。

    /*
     * Copyright (c) 2020, Texas Instruments Incorporated
     * All rights reserved.
     *
     * Redistribution and use in source and binary forms, with or without
     * modification, are permitted provided that the following conditions
     * are met:
     *
     * *  Redistributions of source code must retain the above copyright
     *    notice, this list of conditions and the following disclaimer.
     *
     * *  Redistributions in binary form must reproduce the above copyright
     *    notice, this list of conditions and the following disclaimer in the
     *    documentation and/or other materials provided with the distribution.
     *
     * *  Neither the name of Texas Instruments Incorporated nor the names of
     *    its contributors may be used to endorse or promote products derived
     *    from this software without specific prior written permission.
     *
     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
     * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
     * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
     * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     */
    
    /*
     *  ======== uart2echo.c ========
     */
    #include <stdint.h>
    #include <stddef.h>
    
    /* Driver Header files */
    #include <ti/drivers/GPIO.h>
    #include <ti/drivers/UART2.h>
    
    /* Driver configuration */
    #include "ti_drivers_config.h"
    
    /*
     *  ======== mainThread ========
     */
    void *mainThread(void *arg0)
    {
        char input;
        const char echoPrompt[] = "Echoing characters:\r\n";
        UART2_Handle uart;
        UART2_Params uartParams;
        size_t bytesRead;
        size_t bytesWritten = 0;
        uint32_t status     = UART2_STATUS_SUCCESS;
    
        /* Call driver init functions */
        GPIO_init();
    
        /* Configure the LED pin */
        GPIO_setConfig(CONFIG_GPIO_LED_0, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);
    
        /* Create a UART where the default read and write mode is BLOCKING */
        UART2_Params_init(&uartParams);
        uartParams.baudRate = 115200;
    
        uart = UART2_open(CONFIG_UART2_0, &uartParams);
    
        if (uart == NULL)
        {
            /* UART2_open() failed */
            while (1) {}
        }
    
        /* Turn on user LED to indicate successful initialization */
        GPIO_write(CONFIG_GPIO_LED_0, CONFIG_GPIO_LED_ON);
    
        UART2_write(uart, echoPrompt, sizeof(echoPrompt), &bytesWritten);
    
        /* Loop forever echoing */
        while (1)
        {
            bytesRead = 0;
            while (bytesRead == 0)
            {
                status = UART2_read(uart, &input, 1, &bytesRead);
    
                if (status != UART2_STATUS_SUCCESS)
                {
                    /* UART2_read() failed */
                    while (1) {}
                }
            }
    
            bytesWritten = 0;
            while (bytesWritten == 0)
            {
                status = UART2_write(uart, &input, 1, &bytesWritten);
    
                if (status != UART2_STATUS_SUCCESS)
                {
                    /* UART2_write() failed */
                    while (1) {}
                }
            }
    
            UART2_close(uart);
    
    //        usleep(16000); // working ok
    //        usleep(17000); // working ok
    //        usleep(30000);
            sleep(1);   // working ok
    
            uart = UART2_open(CONFIG_UART2_0, &uartParams);
            if (uart == 0)
            {
                while (1);
            }
        }
    }
    

    ^我在默认 uartecho 示例中使用了上述代码(C:\ti\simplelink_lowpower_f3_sdk_7_40_00_64\examples\rtos\LP_EM_CC2340R5\drivers\uart2echo)

    您能否在最后尝试此操作以查看是否可以重现我的结果? (成功、重复执行 UART2_OPEN 和 UART2_CLOSE)。

    谢谢。
    托比

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

    尊敬的 Toby:


    我使用 uart2echo 并添加您提供的代码并对其进行轻微修改(因为我使用 QFN-24的 CC2340R5)、UART2_open ()可以成功运行、但我当前使用的工程使用 basic_ble_lp 作为基本工程

    但正如我前面提到的,似乎并不是每个 sleep()都会影响 UART2_open(),因为我在很多地方都使用 sleep(1),但它不会影响 UART2_open()。

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

    您的 UART 线程是如何工作的?

    是否存在 UART2_OPEN 被连续调用两次的可能性?

    一种可能的调试步骤:

    1. 引入两个计数器:openCount 和 closeCount。 对这些计数器的任何访问都必须处于临界区中。
    2. 调用 UART2_OPEN 后、使 openCount 递增。
    3. 调用 UART2_Close 后、以使 closeCount 递增。
    4. 发生问题时、比较 openCount 和 closeCount 的值。
    5. 在理想情况下、在任何 UART2_Close 之后、我们希望 openCount == closeCount。 如果存在差异、这可能表示对 UART2_OPEN 进行了两次调用
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我在上面已经描述了我的 UART 线程是如何创建的以及它是如何工作的、

    写在我的 uartthread 的代码只是图片,所以没有其他地方可以打开 UART2_OPEN(),如果根据您的假设,有其他地方可以重复打开 UART2_OPEN(),那么如何解释使用 usleep(16000 )它是否可以正常工作? 这没有道理

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

    "mainThreadUart"是什么样子的?

    您是否仅使用 UART 一次、然后将其关闭? (在应用程序初始化过程中 App_Stack、如"schilditDoneHandler"所示)  
    或者是否 多次调用 App_Stack itDoneHandler?

    我的假设是 mainThreadUart 会访问 UART (打开后读取/写入)、然后在完成后关闭 UART。
    这会发生多次。