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.

[参考译文] LP-EM-CC2340R5:是否可以在同一任务中使用 UART2_WRITE 和 UART2_READ?

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

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

https://e2e.ti.com/support/wireless-connectivity/bluetooth-group/bluetooth/f/bluetooth-forum/1405164/lp-em-cc2340r5-can-uart2_write-and-uart2_read-not-be-used-in-the-same-task

器件型号:LP-EM-CC2340R5
主题中讨论的其他器件:CC2340R5

工具与软件:

您好!

我有一个接收 UART 数据并需要恢复任务的应用程序。 处理完数据后、它需要回复用户数据是否正确、然后暂停任务。 为什么 UART2_WRITE 和 UART2_READ 不能在同一个任务中一起使用?

我已经尝试集成 user_uart2callback 示例、但似乎也不起作用。

完整代码

/*
 * 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.
 */

/*
 *  ======== uart2callback.c ========
 */

/* POSIX Header files */
#include <pthread.h>

/* For usleep() */
#include <unistd.h>

#include <stdint.h>
#include <stddef.h>
#include <string.h>
/* POSIX Header files */
#include <semaphore.h>

/* Driver Header files */
#include <ti/drivers/GPIO.h>
#include <ti/drivers/UART2.h>

/* Driver configuration */
#include "ti_drivers_config.h"

/* RTOS header files */
#include <FreeRTOS.h>
#include <task.h>
//#include <inc_task.h>
//INC_TASK_H

#define USER_STACK_SIZE  1024

#define UART_MAX_READ_SIZE 250

static sem_t sem;
static volatile size_t numBytesRead, UART_status = 0;


UART2_Handle uart;
UART2_Params uartParams;

TaskHandle_t user_xHandle;

pthread_mutex_t LEDBlink_mutex;//pthread_mutex_lock ,pthread_mutex_unlock

uint8_t uartReadBuffer[250] = {0};

void callbackFxn(UART2_Handle handle, void *buffer, size_t count, void *userArg, int_fast16_t status);

void Open_UART_FUN()
{
    char input;
    const char echoPrompt[] = "Echoing characters:\r\n";

    uint32_t status = UART2_STATUS_SUCCESS;


    /* Create a UART in CALLBACK read mode */
    UART2_Params_init(&uartParams);

    uartParams.readMode     = UART2_Mode_CALLBACK;
    uartParams.readCallback = callbackFxn;
    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);

    /* Pass NULL for bytesWritten since it's not used in this example */
    UART2_write(uart, echoPrompt, sizeof(echoPrompt), NULL);
    UART2_read(uart, uartReadBuffer, UART_MAX_READ_SIZE, NULL);


}

/*******************************************************************************
 */

/* Task to be created. */
void vTaskCode( void * pvParameters )
{
    /* The parameter value is expected to be 1 as 1 is passed in the
       pvParameters value in the call to xTaskCreate() below. */

    for( ;; )
    {
        /* Task code goes here. */
          GPIO_toggle(CONFIG_GPIO_LED_0);

//          UART2_write(uart, (char*)"OK\r\n", strlen("OK\r\n"), NULL);
          UART2_read(uart, uartReadBuffer, UART_MAX_READ_SIZE, NULL);

          vTaskSuspend(NULL);


    }
}

/* Function that creates a task. */
void vOtherFunction( void )
{
    BaseType_t xReturned;

    /* Configure the LED pin */
    GPIO_setConfig(CONFIG_GPIO_LED_0, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);
    /* Turn on user LED to indicate successful initialization */
    GPIO_write(CONFIG_GPIO_LED_0, CONFIG_GPIO_LED_ON);

    /* Create the task, storing the handle. */
    xReturned = xTaskCreate(
                    vTaskCode,       /* Function that implements the task. */
                    "user_app",          /* Text name for the task. */
                    USER_STACK_SIZE,      /* Stack size in words, not bytes. */
                    ( void * ) 1,    /* Parameter passed into the task. */
                    tskIDLE_PRIORITY,/* Priority at which the task is created. */
                    &user_xHandle );      /* Used to pass out the created task's handle. */
}

/*
 *  ======== callbackFxn ========
 */
void callbackFxn(UART2_Handle handle, void *buffer, size_t count, void *userArg, int_fast16_t status)
{
    if (status != UART2_STATUS_SUCCESS)
    {
        /* RX error occured in UART2_read() */
        while (1) {}
    }

    numBytesRead = count;

   //thread_mutex_lock(&LEDBlink_mutex);
    UART_status = 1;
    //hread_mutex_unlock(&LEDBlink_mutex);

    memcpy(uartReadBuffer,buffer,numBytesRead);

    BaseType_t xYieldRequired; //xYieldRequired
    // Resume the suspended task.
    xYieldRequired = xTaskResumeFromISR(user_xHandle);

    // We should switch context so the ISR returns to a different task.
    // NOTE:  How this is done depends on the port you are using.  Check
    // the documentation and examples for your port.
    portYIELD_FROM_ISR(xYieldRequired);
}

UART2 LED 成功

void vTaskCode( void * pvParameters )
{
    /* The parameter value is expected to be 1 as 1 is passed in the
       pvParameters value in the call to xTaskCreate() below. */

    for( ;; )
    {
        /* Task code goes here. */
          GPIO_toggle(CONFIG_GPIO_LED_0);

//          UART2_write(uart, (char*)"OK\r\n", strlen("OK\r\n"), NULL);
          UART2_read(uart, uartReadBuffer, UART_MAX_READ_SIZE, NULL);

          vTaskSuspend(NULL);


    }
}

UART2 LED  失败

void vTaskCode( void * pvParameters )
{
    /* The parameter value is expected to be 1 as 1 is passed in the
       pvParameters value in the call to xTaskCreate() below. */

    for( ;; )
    {
        /* Task code goes here. */
          GPIO_toggle(CONFIG_GPIO_LED_0);

          UART2_write(uart, (char*)"OK\r\n", strlen("OK\r\n"), NULL);
          UART2_read(uart, uartReadBuffer, UART_MAX_READ_SIZE, NULL);

          vTaskSuspend(NULL);


    }
}

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

    Anthony、您好!

    感谢您的咨询。

    UART2 LED  发生故障时到底发生了什么? 它只闪烁一次吗? 您如何配置 UART 写入模式?

    BR、

    David。

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

    尊敬的 David:

    您是对的;LED 只亮起一次。 我没有专门配置 UART 写入。 我应该如何在这里设置它?

    void Open_UART_FUN()
    {
        char input;
        const char echoPrompt[] = "Echoing characters:\r\n";
    
        uint32_t status = UART2_STATUS_SUCCESS;
    
    
        /* Create a UART in CALLBACK read mode */
        UART2_Params_init(&uartParams);
    
        uartParams.readMode     = UART2_Mode_CALLBACK;
        uartParams.readCallback = callbackFxn;
        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);
    
        /* Pass NULL for bytesWritten since it's not used in this example */
        UART2_write(uart, echoPrompt, sizeof(echoPrompt), NULL);
        UART2_read(uart, uartReadBuffer, UART_MAX_READ_SIZE, NULL);
    
    
    }

    此致、
    Anthony

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

    尊敬的 David:

    我参考了 e2e.ti.com/.../4684705上的信息 并修改了 SYSCFG UART2 TX 环缓冲区大小 . 我还添加了几行代码、从而解决了我的问题。

        uartParams.readMode     = UART2_Mode_CALLBACK;
        uartParams.writeMode     = UART2_Mode_NONBLOCKING; // UART2_Mode_NONBLOCKING
        uartParams.readCallback = callbackFxn;
        uartParams.writeCallback = NULL;//NULL
    

     

    此致、
    Anthony

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

    Anthony、您好!

    很高兴听到它在工作。 您是否成功地写入所有信息? 我假设所发生的情况是、如果没有进行其他配置、UART2驱动程序默认为阻塞模式。 最后一种模式是在数据发送到 TX 引脚时使用信标进行阻止。 但是、我本来期望它在第一次写入之前挂起? 发生了吗?

    BR、

    David。

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

    尊敬的 David:

    最初、我没有设置 uartParams.writeMode。 多次尝试后、我稍后将 writeMode 设置为 UART2_Mode_nonblocking。 我遇到了 UART Tx 传输不完整的问题。 在将默认 syscfg UART2 TX 环缓冲区大小从32更改为100后、我的 Tx 数据完全被发送。 我可能还没有完全了解使用信标进行阻止的实际操作。 下面是我的规范;也许有些领域是我需要讨论的问题。

    /*
     * 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.
     */
    
    /*
     *  ======== uart2callback.c ========
     */
    
    /* POSIX Header files */
    #include <pthread.h>
    
    /* For usleep() */
    #include <unistd.h>
    
    #include <stdint.h>
    #include <stddef.h>
    #include <string.h>
    /* POSIX Header files */
    #include <semaphore.h>
    
    /* Driver Header files */
    #include <ti/drivers/GPIO.h>
    #include <ti/drivers/UART2.h>
    
    /* Driver configuration */
    #include "ti_drivers_config.h"
    
    /* RTOS header files */
    #include <FreeRTOS.h>
    #include <task.h>
    //INC_TASK_H
    
    #define USER_STACK_SIZE  1024
    
    #define UART_MAX_READ_SIZE 250
    
    static sem_t sem;
    static volatile size_t numBytesRead;
    
    
    UART2_Handle uart;
    UART2_Params uartParams;
    
    TaskHandle_t user_xHandle;
    
    pthread_mutex_t LEDBlink_mutex;//pthread_mutex_lock ,pthread_mutex_unlock
    
    
    uint8_t uartReadBuffer[250] = {0};
    
    void callbackFxn(UART2_Handle handle, void *buffer, size_t count, void *userArg, int_fast16_t status);
    
    
    void Open_UART_FUN()
    {
        char input;
        const char echoPrompt[] = "EMS BLE Peripheral start!!\r\n";
    
        uint32_t status = UART2_STATUS_SUCCESS;
    
    
        /* Create a UART in CALLBACK read mode */
        UART2_Params_init(&uartParams);
    
        uartParams.readMode     = UART2_Mode_CALLBACK;
        uartParams.writeMode     = UART2_Mode_NONBLOCKING; // UART2_Mode_NONBLOCKING
        uartParams.readCallback = callbackFxn;
        uartParams.writeCallback = NULL;//NULL
    
        uartParams.baudRate     = 115200;
    
        uart = UART2_open(CONFIG_DISPLAY_UART, &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);
    
        /* Pass NULL for bytesWritten since it's not used in this example */
        UART2_write(uart, echoPrompt, sizeof(echoPrompt), NULL);
        UART2_read(uart, uartReadBuffer, UART_MAX_READ_SIZE, NULL);
    
    
    }
    
    /*******************************************************************************
     */
    
    /* Task to be created. */
    void vTaskCode( void * pvParameters )
    {
        /* The parameter value is expected to be 1 as 1 is passed in the
           pvParameters value in the call to xTaskCreate() below. */
    
        // Block for 500ms.
    //    const TickType_t xDelay = 20 / portTICK_PERIOD_MS;
    
        for( ;; )
        {
            /* Task code goes here. */
           if(strstr((char*)uartReadBuffer,(char*)"\r\n") != 0)
           {
               GPIO_toggle(CONFIG_GPIO_LED_RED);
               UART2_write(uart, (char*)uartReadBuffer, numBytesRead, NULL);
               UART2_write(uart, (char*)"OK\r\n", strlen("OK\r\n"), NULL);
           }
           else
           {
               UART2_write(uart, (char*)"fail_", strlen((char*)"fail_") , NULL);//fail_fjrifjrifjirfjrifjrijfrofjrofjrof
               UART2_write(uart, (char*)"OK\r\n", strlen("OK\r\n"), NULL);
           }
    
           memset(uartReadBuffer, 0, numBytesRead);
    
           UART2_read(uart, uartReadBuffer, UART_MAX_READ_SIZE, NULL);
    
    //       vTaskDelay( xDelay );
    
           vTaskSuspend(NULL);
        }
    }
    
    /* Function that creates a task. */
    void vOtherFunction( void )
    {
        BaseType_t xReturned;
    
        /* Configure the LED pin */
        GPIO_setConfig(CONFIG_GPIO_LED_RED, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);
        /* Turn on user LED to indicate successful initialization */
        GPIO_write(CONFIG_GPIO_LED_RED, CONFIG_GPIO_LED_OFF);
    
        /* Create the task, storing the handle. */
        xReturned = xTaskCreate(
                        vTaskCode,       /* Function that implements the task. */
                        "user_app",          /* Text name for the task. */
                        USER_STACK_SIZE,      /* Stack size in words, not bytes. */
                        ( void * ) 1,    /* Parameter passed into the task. */
                        tskIDLE_PRIORITY,/* Priority at which the task is created. */
                        &user_xHandle );      /* Used to pass out the created task's handle. */
    
        vTaskSuspend(user_xHandle);
    }
    
    /*
     *  ======== callbackFxn ========
     */
    void callbackFxn(UART2_Handle handle, void *buffer, size_t count, void *userArg, int_fast16_t status)
    {
        if (status != UART2_STATUS_SUCCESS)
        {
            /* RX error occured in UART2_read() */
            while (1) {}
        }
    
        numBytesRead = count;
    
    
        memcpy(&uartReadBuffer,buffer,numBytesRead);
    
        BaseType_t xYieldRequired; //xYieldRequired
        // Resume the suspended task.
        xYieldRequired = xTaskResumeFromISR(user_xHandle);
    
        // We should switch context so the ISR returns to a different task.
        // NOTE:  How this is done depends on the port you are using.  Check
        // the documentation and examples for your port.
        portYIELD_FROM_ISR(xYieldRequired);
    
    
    }
    


    此致、
    Anthony

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

    Anthony、您好!

    当使用 UART2_WRITE( Mode_Nonblocking )函数时,UART_WRITE ()函数会将尽可能多的数据复制到传输缓冲区中,以便解释为什么需要增加缓冲区大小。 当您使用 UART 时、默认情况下将其设置为阻塞机制、如果在调试模式下运行、程序会在代码中停留在何处?

    BR、

    David。

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

    尊敬的 David:

    UART 默认设置为阻塞;屏幕截图如下所示。


    如果我们回到原始有关阻塞模式的问题、有没有正确的方法使用它? 无论我如何配置它、都无法使它正常工作。 也许您可以提供一个示例供参考。

    此致、
    Anthony

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

    Anthony、您好!

    我将举一个例子并简单分享。

    BR、

    David。

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

    尊敬的 David:

    非常感谢、这对我很有帮助。

    此致、
    Anthony

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

    尊敬的 David:

    我也遇到了类似的问题,希望继续跟进

    我的 UART 配置为 uartParams.readMode = UART2_Mode_callback;uartParams.readCallback = callbackFxn;写入模式是默认模式

    我的开发环境版本:

    SDK 版本:simplelink_lowpower_f3_sdk_7_40_00_64

    CCS 版本:12.7.0.00007.

    示例项目:basic_ble_LP_EM_CC2340R5_freertos_ticlang

    此致、

    Ryan

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

    Ryan、您好!

    您能否提供有关此问题的更多详细信息? 是否通过修改 UART 写入模式来解决该问题?

    BR、

    David。

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

    尊敬的 David:

    我已经解决了这个问题

    谢谢!

    此致、

    Ryan

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

    尊敬的 David:
    非常感谢您的帮助。 这次我真的发现了这个问题。 我将任务的优先级设定得太低、并且通过添加 SEM_post 和 SEM_WAIT、现在运转良好。




    可使用 TX 阻塞模式。





    此致、
    Anthony