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-AM243:UART RX中断

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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1095668/lp-am243-uart-rx-interrupts

部件号:LP-AM243
Thread:sysconfig中讨论的其它部件

回波低延迟传输示例共享一种暂停代码和侦听UART缓冲区上的消息的方法,并在用户键入时回显这些消息。

echo回调代码示例共享了一种暂停整个代码并等待预期消息返回的方法。

对于期望在任何给定时间接收RX消息,同时运行其他流程的实用系统,您有什么建议。 我尝试通过删除信号暂停来调整回调示例,但它似乎从未触发读回调。 我还尝试调整低延迟传输示例,但它存在一个问题,即暂停代码等待某个字符,而不是在中断中接收到该字符时对该字符执行某些操作。

在其他微控制器上,我通过在UART上使用ISR触发器实现了我想要的功能, 在这个函数中,它只是读取接收到的char并根据它执行逻辑,但我仍然经常对FreeRTOS如何与CCS的sysconfig结构结合使用感到困惑。 是否对设置/方法有任何建议? 我基本上只想让ISR告诉我它收到了什么CHAR,而不会妨碍代码。

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

    您好,Dylan,

    使用 UART_ECHO_callback_am243x-evm_r5fss0-0_FreeRTOS_ti-arm-clang可以轻松实现您尝试执行的操作:

    1.更改

    #define main_task_PRI (configMAX_Priorities -1)以 #define main_task_PRI (configMAX_Priorities -2)

    2.添加

    #define OTHER TASK_PRI (配置MAX_PRIORIES-1)

    3.定义以下内容:

    void Other_main (void *args)

      同时(1)

      {

         /*在此处执行其他处理*/

      }

      vTaskDelete(NULL);
    }

    其他任务大小,  

    gOtherTaskStack和  

    gOtherTaskObj  

    4.在main()中增加以下内容:

    gMainTask = xTaskCreateStatic( Other_main,/*指向实现任务的函数的指针。 */
                              "其他_主要",/*任务的文本名称。 这只是为了便于调试。 */
                              Other_task_size,/*堆栈深度(以StackType_t为单位)通常为UINT32_t (在32b CPU上)*/
                              空,/*我们不使用任务参数。 */
                              OTHER TASK_PRI,/* TASK PRIORITY,0为最低优先级,configMAX_PRIORIES-1为最高优先级*/
                              gOtherTaskStack,/*指向堆栈基本*/的指针
                              &gOtherTaskObj);/*指向静态分配的任务对象内存*/的指针
    configASSERT(gOtherTask !=空);

    5,将 APP_UART_receive BUFSIZE从8更改为1

    6.更改 UART_ECHO_READ回调()以处理消息逻辑。

    请记住,每次有UART输入时都会调用UART_ECHO_READ_callback。  在满足消息逻辑之前,您不会调用SemaphoreP_post(&gUartReadDoneSem)。 您可能需要有一个全局UART输入缓冲区,以保存到目前为止收到的所有字符,从而实现消息逻辑。 同时,其他任务- Other_main()将继续并行处理其他内容。 您也可以根据需要将FreeRTOS_main任务更改为无限循环。

    此致,

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

    感谢您的快速回复。 我在为gOtherTask创建变量的同时完成了这些步骤,并且在步骤4中将gMainTask替换为gOtherTask。 只会播放另一个任务。 我在每个任务中都添加了调试打印行。

    此处,"其他任务已启动"将发送到控制台,但任务未启动。

    主要:

    #include <stdlib.h>
    #include <kernel/dpl/DebugP.h>
    #include "ti_drivers_config.h"
    #include "ti_board_config.h"
    #include "FreeRTOS.h"
    #include "task.h"
    
    #define MAIN_TASK_PRI  (configMAX_PRIORITIES-2)
    #define OTHER_TASK_PRI  (configMAX_PRIORITIES-1)
    
    #define MAIN_TASK_SIZE (16384U/sizeof(configSTACK_DEPTH_TYPE))
    StackType_t gMainTaskStack[MAIN_TASK_SIZE] __attribute__((aligned(32)));
    StaticTask_t gMainTaskObj;
    TaskHandle_t gMainTask;
    
    #define OTHER_TASK_SIZE (16384U/sizeof(configSTACK_DEPTH_TYPE))
    StackType_t gOtherTaskStack[OTHER_TASK_SIZE] __attribute__((aligned(32)));
    StaticTask_t gOtherTaskObj;
    TaskHandle_t gOtherTask;
    
    void uart_echo_callback(void *args);
    
    void freertos_main(void *args)
    {
        DebugP_log("Main Task started\r\n");
        uart_echo_callback(NULL);
    
        vTaskDelete(NULL);
    }
    
    void other_main(void *args)
    {
        DebugP_log("Other Task started\r\n");
        int k = 0;
        while (1) {
            k++;
            // Print a statement ~1 per second or so
            if((k%10000000) == 0) {
                DebugP_log("tick\r\n");
            }
        }
    
        vTaskDelete(NULL);
    }
    
    int main()
    {
        /* init SOC specific modules */
        System_init();
        Board_init();
    
        /* This task is created at highest priority, it should create more tasks and then delete itself */
        gMainTask = xTaskCreateStatic( freertos_main,   /* Pointer to the function that implements the task. */
                                      "freertos_main", /* Text name for the task.  This is to facilitate debugging only. */
                                      MAIN_TASK_SIZE,  /* Stack depth in units of StackType_t typically uint32_t on 32b CPUs */
                                      NULL,            /* We are not using the task parameter. */
                                      MAIN_TASK_PRI,   /* task priority, 0 is lowest priority, configMAX_PRIORITIES-1 is highest */
                                      gMainTaskStack,  /* pointer to stack base */
                                      &gMainTaskObj ); /* pointer to statically allocated task object memory */
        configASSERT(gMainTask != NULL);
    
        gOtherTask = xTaskCreateStatic( other_main, /* Pointer to the function that implements the task. */
                                        "other_main", /* Text name for the task. This is to facilitate debugging only. */
                                        OTHER_TASK_SIZE, /* Stack depth in units of StackType_t typically uint32_t on 32b CPUs */
                                        NULL, /* We are not using the task parameter. */
                                        OTHER_TASK_PRI, /* task priority, 0 is lowest priority, configMAX_PRIORITIES-1 is highest */
                                        gOtherTaskStack, /* pointer to stack base */
                                        &gOtherTaskObj ); /* pointer to statically allocated task object memory */
        configASSERT(gOtherTask != NULL);
    
        /* Start the scheduler to start the tasks executing. */
        vTaskStartScheduler();
    
        DebugP_assertNoLog(0);
    
        return 0;
    }
    

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

    您好,Dylan,

    由于Other_main具有较高的优先级,并且它处于while循环(不睡眠)中,因此FreeRTOS_main 永远不会有机会运行。 请在OTHER MAIN的While循环中添加ClockP_SLEEP(10),以便  FreeRTOS_MAIN有机会运行。

    此致,

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

    虽然这样可以在其它任务处于休眠状态时正常运行,但在运行其它任务时不会触发中断。

    例如,如果我将sleep命令添加到OtherTask的开头,我可以在睡眠结束之前输入我的字符,并且可以识别它。

    如果我等到睡眠结束后,程序开始嘀嗒声,除非我在循环过程中再次睡觉,否则它不会读取我的字符。 这并不是代码或其他任务的中断,如果"其他任务"未在最佳时间通过睡眠暂停,则可能导致无法接收消息。

    我正在尝试完成一个相当常见的程序设计,在程序集或C中对MSP430s进行编码时,检测到UART上的中断,运行中断的功能,并且在等待中断时可能发生其他事情。 这些示例都依赖于暂停代码以等待中断,并且似乎没有在其他点找到中断,这可能是由于使用信号等待。

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

    您好,Dylan,

        当UART_READ (gUartHandle[CONFIG_UART_CONSOLE],&TRANS)完成时,UART_ECH_READ_REART()实际上被UART ISR调用。 由于您已将 trans.count设置为1,因此每次 有UART输入时都应接收UART_ECHO_READ_callback(),除非 UART_ECHO_READ_callback()在 UART_ECHO_REARU()之后没有调用UT_READ()。

    您是否在 OTHER MAIN的While循环中添加ClockP_SLEEP (10)? 是否可以共享修改的代码?

    此致,

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

    确定此处是已修改的代码。

    我的问题是如果我必须将ClockP_SLEEP (10)添加到While循环中,这意味着如果我在循环中有代码,我必须休眠/暂停我的代码进程,以便它读取任何字符,这是我尝试避免的。

    主要:

    /*
     *  Copyright (C) 2018-2021 Texas Instruments Incorporated
     *
     *  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.
     */
    
    #include <stdlib.h>
    #include <kernel/dpl/DebugP.h>
    #include "ti_drivers_config.h"
    #include "ti_board_config.h"
    #include "FreeRTOS.h"
    #include "task.h"
    
    #define MAIN_TASK_PRI  (configMAX_PRIORITIES-2)
    #define OTHER_TASK_PRI  (configMAX_PRIORITIES-1)
    
    #define MAIN_TASK_SIZE (16384U/sizeof(configSTACK_DEPTH_TYPE))
    StackType_t gMainTaskStack[MAIN_TASK_SIZE] __attribute__((aligned(32)));
    StaticTask_t gMainTaskObj;
    TaskHandle_t gMainTask;
    
    #define OTHER_TASK_SIZE (16384U/sizeof(configSTACK_DEPTH_TYPE))
    StackType_t gOtherTaskStack[OTHER_TASK_SIZE] __attribute__((aligned(32)));
    StaticTask_t gOtherTaskObj;
    TaskHandle_t gOtherTask;
    
    void uart_echo_callback(void *args);
    
    void freertos_main(void *args)
    {
        DebugP_log("Main Task started\r\n");
        uart_echo_callback(NULL);
    
        vTaskDelete(NULL);
    }
    
    void other_main(void *args)
    {
        ClockP_sleep(10);
        DebugP_log("Other Task started\r\n");
        int k = 0;
        while (1) {
            k++;
            if((k%10000000) == 0) {
                DebugP_log("tick\r\n");
            }
        }
    
        vTaskDelete(NULL);
    }
    
    int main()
    {
        /* init SOC specific modules */
        System_init();
        Board_init();
    
        /* This task is created at highest priority, it should create more tasks and then delete itself */
        gMainTask = xTaskCreateStatic( freertos_main,   /* Pointer to the function that implements the task. */
                                      "freertos_main", /* Text name for the task.  This is to facilitate debugging only. */
                                      MAIN_TASK_SIZE,  /* Stack depth in units of StackType_t typically uint32_t on 32b CPUs */
                                      NULL,            /* We are not using the task parameter. */
                                      MAIN_TASK_PRI,   /* task priority, 0 is lowest priority, configMAX_PRIORITIES-1 is highest */
                                      gMainTaskStack,  /* pointer to stack base */
                                      &gMainTaskObj ); /* pointer to statically allocated task object memory */
        configASSERT(gMainTask != NULL);
    
        gOtherTask = xTaskCreateStatic( other_main, /* Pointer to the function that implements the task. */
                                        "other_main", /* Text name for the task. This is to facilitate debugging only. */
                                        OTHER_TASK_SIZE, /* Stack depth in units of StackType_t typically uint32_t on 32b CPUs */
                                        NULL, /* We are not using the task parameter. */
                                        OTHER_TASK_PRI, /* task priority, 0 is lowest priority, configMAX_PRIORITIES-1 is highest */
                                        gOtherTaskStack, /* pointer to stack base */
                                        &gOtherTaskObj ); /* pointer to statically allocated task object memory */
        configASSERT(gOtherTask != NULL);
    
        /* Start the scheduler to start the tasks executing. */
        vTaskStartScheduler();
    
        /* The following line should never be reached because vTaskStartScheduler()
        will only return if there was not enough FreeRTOS heap memory available to
        create the Idle and (if configured) Timer tasks.  Heap management, and
        techniques for trapping heap exhaustion, are described in the book text. */
        DebugP_assertNoLog(0);
    
        return 0;
    }
    

    UART_ECHO_callback:(未修改,主要是在读取内容(任何内容)时打印调试消息。

    如果没有告诉其他代码休眠,则根本不会触发回调函数。

    #include <string.h>
    #include <kernel/dpl/DebugP.h>
    #include "ti_drivers_config.h"
    #include "ti_drivers_open_close.h"
    #include "ti_board_open_close.h"
    
    #define APP_UART_BUFSIZE              (200U)
    #define APP_UART_RECEIVE_BUFSIZE      (1U)
    
    uint8_t gUartBuffer[APP_UART_BUFSIZE];
    uint8_t gUartReceiveBuffer[APP_UART_RECEIVE_BUFSIZE];
    volatile uint32_t gNumBytesRead = 0U, gNumBytesWritten = 0U;
    
    uint8_t gUartChars[8U];
    
    /* Semaphore to indicate Write/Read completion used in callback api's */
    static SemaphoreP_Object gUartWriteDoneSem;
    static SemaphoreP_Object gUartReadDoneSem;
    
    #define APP_UART_ASSERT_ON_FAILURE(transferOK, transaction) \
        do { \
            if((SystemP_SUCCESS != (transferOK)) || (UART_TRANSFER_STATUS_SUCCESS != transaction.status)) \
            { \
                DebugP_assert(FALSE); /* UART TX/RX failed!! */ \
            } \
        } while(0) \
    
    void uart_echo_callback(void *args)
    {
        int32_t          transferOK, status;
        UART_Transaction trans;
    
        Drivers_open();
        Board_driversOpen();
    
        DebugP_log("[UART] Echo callback example started ...\r\n");
    
        status = SemaphoreP_constructBinary(&gUartWriteDoneSem, 0);
        DebugP_assert(SystemP_SUCCESS == status);
    
        status = SemaphoreP_constructBinary(&gUartReadDoneSem, 0);
        DebugP_assert(SystemP_SUCCESS == status);
    
        UART_Transaction_init(&trans);
    
        /* Send entry string */
        gNumBytesWritten = 0U;
        trans.buf   = &gUartBuffer[0U];
        strncpy(trans.buf,"This is uart echo test callback mode\r\nReceives 8 characters then echo's back. Please input..\r\n", APP_UART_BUFSIZE);
        trans.count = strlen(trans.buf);
        transferOK = UART_write(gUartHandle[CONFIG_UART_CONSOLE], &trans);
        APP_UART_ASSERT_ON_FAILURE(transferOK, trans);
    
        /* Wait for write completion */
        SemaphoreP_pend(&gUartWriteDoneSem, SystemP_WAIT_FOREVER);
        DebugP_assert(gNumBytesWritten == strlen(trans.buf));
    
        /* Read 8 chars */
        gNumBytesRead = 0U;
        trans.buf   = &gUartReceiveBuffer[0U];
        trans.count = APP_UART_RECEIVE_BUFSIZE;
        transferOK = UART_read(gUartHandle[CONFIG_UART_CONSOLE], &trans);
        APP_UART_ASSERT_ON_FAILURE(transferOK, trans);
    
        /* Wait for read completion */
        SemaphoreP_pend(&gUartReadDoneSem, SystemP_WAIT_FOREVER);
        DebugP_assert(gNumBytesRead == APP_UART_RECEIVE_BUFSIZE);
    
        /* Echo chars entered */
        gNumBytesWritten = 0U;
        trans.buf   = &gUartReceiveBuffer[0U];
        trans.count = APP_UART_RECEIVE_BUFSIZE;
        transferOK = UART_write(gUartHandle[CONFIG_UART_CONSOLE], &trans);
        APP_UART_ASSERT_ON_FAILURE(transferOK, trans);
    
        /* Wait for write completion */
        SemaphoreP_pend(&gUartWriteDoneSem, SystemP_WAIT_FOREVER);
        DebugP_assert(gNumBytesWritten == APP_UART_RECEIVE_BUFSIZE);
    
        /* Send exit string */
        gNumBytesWritten = 0U;
        trans.buf   = &gUartBuffer[0U];
        strncpy(trans.buf, "\r\nAll tests have passed!!\r\n", APP_UART_BUFSIZE);
        trans.count = strlen(trans.buf);
        transferOK = UART_write(gUartHandle[CONFIG_UART_CONSOLE], &trans);
        APP_UART_ASSERT_ON_FAILURE(transferOK, trans);
    
        /* Wait for write completion */
        SemaphoreP_pend(&gUartWriteDoneSem, SystemP_WAIT_FOREVER);
        DebugP_assert(gNumBytesWritten == strlen(trans.buf));
    
        SemaphoreP_destruct(&gUartWriteDoneSem);
        SemaphoreP_destruct(&gUartReadDoneSem);
    
        DebugP_log("All tests have passed!!\r\n");
    
        Board_driversClose();
        Drivers_close();
    
        return;
    }
    
    void uart_echo_write_callback(UART_Handle handle, UART_Transaction *trans)
    {
        DebugP_assertNoLog(UART_TRANSFER_STATUS_SUCCESS == trans->status);
        gNumBytesWritten = trans->count;
        SemaphoreP_post(&gUartWriteDoneSem);
    
        return;
    }
    
    int reads = 0;
    void uart_echo_read_callback(UART_Handle handle, UART_Transaction *trans)
    {
        DebugP_assertNoLog(UART_TRANSFER_STATUS_SUCCESS == trans->status);
        gNumBytesRead = trans->count;
        DebugP_log("READ");
        gUartChars[reads] = &gUartBuffer[0U];
        reads++;
    
        SemaphoreP_post(&gUartReadDoneSem);
    
    
        return;
    }
    

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

    您好,Dylan,

    好的,在这种情况下 ,您可以进行以下更改以使两个任务都进行:

    #define main_task_PRI (configMAX_Priorits-1)
    #define OTHER TASK_PRI (配置MAX_PRIORIES-2)

    此致,

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

    谢谢! 这毫无意义。

    如果您或任何其他人对我的解决方案感兴趣,我将UART设置为主要优先级,实际上我仍然对每个字符使用信号。 我只是循环红色请求,然后等待。

    在我刚才输入的Read语句处的ECHO_callback内部:

    uint8_t GPSMessage[64U];
    int gpsIndex = 0;
    while(1) {
            /* Read 8 chars */
            gNumBytesRead = 0U;
            trans.buf   = &gUartReceiveBuffer[0U];
            trans.count = APP_UART_RECEIVE_BUFSIZE;
            transferOK = UART_read(gUartHandle[CONFIG_UART_CONSOLE], &trans);
            //APP_UART_ASSERT_ON_FAILURE(transferOK, trans);
    
            /* Wait for read completion */
            SemaphoreP_pend(&gUartReadDoneSem, SystemP_WAIT_FOREVER);
            //DebugP_assert(gNumBytesRead == APP_UART_RECEIVE_BUFSIZE);
    
            char c = gUartReceiveBuffer[0U];
            if(c == '$') {
                gpsIndex = 0;
                DebugP_log(&GPSMessage);
                DebugP_log("\r\n");
    
                for(int i = 0; i < 64; i++) {
                    GPSMessage[i] = 0;
                }
            } else {
                GPSMessage[gpsIndex++] = c;
            }
        }

    在这里,它读取GPS,同时执行一些表示正在运行的其他任务的"勾号"。 显然,由于波特率为9600,它将无法对其他任务执行太多操作,因此发送调试消息需要很长时间,但在正常操作中,您不会打印此类内容。