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.

[参考译文] MSP432-RTOS:使用TI-RTOS在UART上出现多字节接收问题

Guru**** 2587365 points
Other Parts Discussed in Thread: CC3200

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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/617497/msp432-rtos-multibyte-receive-issue-on-uart-using-ti-rtos

部件号:MSP432-RTOS
主题中讨论的其他部件:CC3200

大家好,

在我的项目中,我将UART (UARTA2)连接到脉冲装置,以便从脉冲器获取样品。 这是必需的,因为这是此脉冲装置能够从自身传输数据的唯一方式。

发送到脉冲程序的某些命令会发回一个字节的信息。但有几个命令发送到脉冲程序,后者会发回4字节和1024字节的数据。

我已经尝试了一个多星期了,但无法找到问题的解决方案。

当脉冲程序发送1字节信息时,MSP432 UART能够接收,没有任何问题。

但是,当脉冲程序发送4字节或1024字节的数据时,MSP432将无法捕获该数据。

我使用的是"simplelink_msp432_SDK_1_40_00_28"版本,并基于RTOS构建了代码,其中连续调用UART写入,而UART读取则使用读取回调概念基于中断。

如果我尝试将UART读取回调函数中收到的字节复制到数组中,以便释放RXBUF,中断将永远不会发生,而且我以后也不会在接收缓冲区中接收任何内容。

我复制到缓冲区的原因是,当脉冲程序发送超过1字节的数据时,我还会触发溢出标志。

请提供您的指导。

谢谢你

Vikram

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好Vikram:
    您是否可以减慢UART的速度以查看这是否解决了问题?

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

    您好,Chris:

    波特率是我所保存的最低波特率,它是9600。

    不可能低于此。

    谢谢你

    Vikram

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    然后,代码中的某些内容似乎被编程为错误的方式-波特率为9600,如果您不以几乎直流时钟频率运行处理器,MSP432应该会被视为地狱(我猜它将是几MHz,不是吗?) 或者,如果其它较高优先级的中断不会阻止您的系统。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    e2e.ti.com/.../Pulser-to-MSP432-RTOS-based-wokrking.zipYou可能是正确的Dennis,他说某些内容的编程不正确,但这并不一定是优先问题。 因为我的UART任务以最高优先级运行,而另一个任务的优先级低于UART任务。

    我正在附加项目,如果您有时间,请查看并建议我可能出错的地方。

    此代码工作正常,但如果我在UART Read回调函数中添加一个语句,该函数是“uartReceiveFinished”,用于收集在RXBUF中接收的数据,则中断永远不会发生,并且执行不会进入该代码段。

    在这个代码中,当接收到的数据超过1个字节时,我总是得到一个溢出错误标志。

    感谢您的反馈。

    Vikram

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

    您好,Chris:

    我已经设法解决了我发布的问题,这与我处理已读回拨的方式有关,并且总是在接收活动时插入中断点来中断。

    我现在面临的另一个挑战是,对于我发送到脉冲程序单元的每个命令,接收字节都不同。 它们不会保持不变。

    对于某些命令,我收到1字节,大约2字节,大约4字节,其中一个命令返回1024字节的信息。

    如何处理这种可变的信息长度,因为UART_READ函数需要具有要接收的字节数。

    我要附上我编写的代码。

    请提供您的意见。

    #include <stdint.h>
    #include <stddef.h>/*
    
    Driver Header files */
    #include <ti/drivers/UART.h>
    
    #include <ti/drivers/DPL/SemaphoreP.h>
    #include <xDC/Header/System.h>
    #include<string.h>
    
    
    #include <string.h/stimu/strole
    
    
    
    
    
    = 1u/stu/stueh/stueh/stueh/fue_beer = zh <zh <zh
    
    
    
    = 1u/stim/stim/stue_beh/stue.1ue_beh = zh = zh <xim/zh = zh = zh = zh = zh = zh <ximb = zh /zh = zh = zh = zh = zh = zh = zh = zh = zh = zh = zh =
    125
    #define SIGAVGVALUE 31
    #define RGD0VALUE 0x00
    #define RGD1VALUE 0x02
    
    /* prototype */
    static void uartReceiveFinished (UART_Handle Handle,void *UART_rxBuffer,Size_t count);
    int ReadCount =4;
    
    /*
    === mainThread =========
    */
    void *mainThread (void *arg0)
    {
    字符 输入;
    unsigned char命令Buffer[20];
    无符号字符countNum =0;
    UART_HANDLE UART;
    UART_Params uartParams;
    /*调用驱动程序初始化函数*/
    GPIO初始化();
    UART_INIT();
    
    /*打开用户LED */
    GPIO写入(Board_GPIO _LED0,Board_GPIO _LED_ON);
    
    /*创建数据处理关闭的UART。 */
    UART_PARAM_INIT (&uartParams);
    uartParams.writeDataMode = UART_DATA_TEXT;
    uartParams.readMode = UART_MODE_callback;
    uartParams.readDataMode = UART_DATA_TEXT;
    uartParams.readReturnMode = UART_RETURE_FULL;
    uartParams.readEcho = UART_ECHO_OFF;
    uartParams.readCallback = uartReceiveFinished;
    uartParams.baudrate = 9600;
    UART = UART_OPEN (Board_UART1,&uartParams);
    IF (UART ==空)
    {
    system_abort("打开UART"时出错";
    }
    
    GPIO写入(Board_GPIO _LED0,Board_GPIO _LED_Off);
    GPIO写入(Board_GPIO _LED1,Board_GPIO LED关闭);
    
    GPIO写入(Fogwise_LDO1,Fogwise_LDO1_ON);
    /*循环永久回声*/
    而(1){
    交换机(命令计数器)
    {
    案例0:
    命令Buffer[countNum+]= probe_STX;
    命令Buffer[countNum+]= probe_set_bit_time;
    命令Buffer[countNum+]= probe_STX;
    命令缓冲区[countNum+]=0x01;
    命令Buffer[countNum+]= BITTIMEVALUE;
    命令Buffer[countNum+]= probe_EOT;
    命令Buffer[countNum+]='\0';
    UART_READ (UART,输入和2);
    GPIO切换(板_GPIO _LED2);
    中断;
    
    案例1:
    命令Buffer[countNum+]= probe_STX;
    命令Buffer[countNum+]= probe_Get_Baud;
    命令Buffer[countNum+]='\0';
    UART_READ (UART,输入和4);
    中断;
    
    案例2:
    命令Buffer[countNum+]= probe_STX;
    命令Buffer[countNum+]= probe_set_衰减;
    命令Buffer[countNum+]= probe_STX;
    命令缓冲区[countNum+]=0x01;
    命令Buffer[countNum+]= ATTVALUE;
    命令Buffer[countNum+]= probe_EOT;
    命令Buffer[countNum+]= probe_STX;
    命令缓冲区[countNum+]= probe_set_SIG_AVG;
    命令Buffer[countNum+]= probe_STX;
    命令缓冲区[countNum+]=0x01;
    命令Buffer[countNum+]= SIGAVGVALUE;
    命令Buffer[countNum+]= probe_EOT;
    命令Buffer[countNum+]='\0';
    UART_READ (UART,输入和4);
    GPIO切换(板_GPIO _LED1);
    中断;
    
    案例3:
    命令Buffer[countNum+]= probe_STX;
    命令Buffer[countNum+]= probe_set_baud;
    命令Buffer[countNum+]= probe_STX;
    命令缓冲区[countNum+]=0x01;
    命令Buffer[countNum+]= probe_baud _9600_code;
    命令Buffer[countNum+]='\0';
    UART_READ (UART,输入和1);
    GPIO切换(板_GPIO _LED3);
    中断;
    
    默认:
    命令计数器=0;
    中断;
    }
    命令Counter++;
    countNum =0;
    UART写入(UART,&commandBuffer, strlen((void*)commandBuffer));
    }
    }
    
    静态void uartReceiveFinished (UART_Handle Handle,void *UART_rxBuffer,size_t count)
    {
    命令=(uint8_t*)UART_rxBuffer;
    memcpy((char*)pcBuffer,(const char*)UART_rxBuffer, 4);
    GPIO切换(Board_GPIO _LED0);
    }
    

    此外,即使示波器上显示的信息是正确的,但UART_rxBuffer所指位置上显示的值对于某些命令来说也会有所不同,从而使其不一致。

    我在示波器上探测了UART RX线路以查看信息。

    请提供一些建议。

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

    请提供一些建议。
    我甚至尝试在驱动程序级别访问环形缓冲区,但无法找到方法从环形缓冲区中获取值,因为每当我检查XBUF获取多个字节的数据时,我总是收到溢出错误和 在XBUF中观察到最后一个字节。
    如何在RTOS UART接收返回函数中访问此缓冲区。

    Vikram
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    Vikram,
    我在关注您提供的内容时遇到了一些问题。 在前面的线程中附加的示例中,我看到了一个1024的环状缓冲区定义,但我仍然看到在HW属性中,环状缓冲区仍然是32。 UART_READ将从此环形缓冲区中提取。 您可能需要检查UART_READ返回的值,以查看该函数当前是否繁忙。 请注意,如果环形缓冲区没有足够的信息用于读取功能,则它将使用ISR来填充缓冲区。 在连续读取之间可能存在超限,但考虑到速度,我怀疑这种情况是否可能。

    您使用的是TI-RTOS还是TIDrivers? 我正在查看TIDrivers (v1_30_00_40),但我相信它们是相似的。

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

    感谢Chris的回复。

    我在关注您提供的内容时遇到了一些问题。 在前面的线程中附加的示例中,我看到了一个1024的环状缓冲区定义,但我仍然看到在HW属性中,环状缓冲区仍然是32。

    在我在早期线程中附加的示例中,我尝试一次从脉冲程序(对于由MSP432发送的特定命令)返回1024字节的数据,因此环形缓冲区定义为1024。 但我在后来附加的示例中改变了这一点,因为我想从脉冲器和MSP432之间的简单命令通信开始。

    UART_READ将从此环形缓冲区中提取。 您可能需要检查UART_READ返回的值,以查看该函数当前是否繁忙。

    问题是执行时有时会进入读取回调函数,有时则不会。无法理解原因。 因此,每当它进入 uartReceiveFinished函数(回调函数)时,我就可以查看缓冲区。 如果该功能没有进入,我们如何检查它当前是否处于繁忙状态?

    请注意,如果环形缓冲区没有足够的信息用于读取功能,则它将使用ISR来填充缓冲区。

    这是我不理解它在UARTMSP432.c驱动程序文件中的描述。

    "

    /*
    *========= readTaskCallback ==========
    *此函数第一次被UART_READ任务调用并尝试
    *获取它可以从ringBuffer获取的所有数据。 如果完成,将会
    *执行用户提供的回叫。 如果未能完成,ISR必须处理
    *剩余数据。 通过设置draByISR标志,UART_READ函数
    *将获取剩余数据的责任移交给ISR。
    */

    此处指的是ISR。 是我们必须创建单独的ISR例程,还是回调本身就是ISR?

    在连续读取之间可能存在超限,但考虑到速度,我怀疑这种情况是否可能。

    您使用 的是TI-RTOS 还是TIDrivers? 我正在查看TIDrivers (v1_30_00_40),但我相信它们是相似的。

    我正在使用TI-RTOS "SimpleLink MSP432 SDK"

    我希望这能更好地了解我所面临的问题。

    Vikram

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    /*
    ========= uartecha.c =========
    */
    #include <stdint.h>
    #include <stddef.h>/*
    
    
    BIOS module Headers */
    #include <ti/SysBIOS/BIOS.h>/*
    Driver Header files */
    #include <ti/drivers/GPI.h>
    #include <ti/drivers/char.h>/<string/spot/<strat/fut>
    
    
    
    
    
    
    
    
    
    
    
    
    int getLen =0;
    uint8_t pcBuffer[1028];
    #define BITTIMEVALUE 0x03
    #define ATTALUE 125
    #define SIGAVGVALUE 31
    #define RGD0VALUE 0x00
    #define RGD1VALUE 0x02
    
    UART_HANDLE UART;
    
    /* prototype */
    void probeByte (uint8_t字节);
    静态void uartReceiveFinished (UART_HANDLE句柄,void *UART_rxBuffer,size_t count);
    int ReadCount =4;/Send*==
    
    
    = mainThread =========
    */
    void *mainThread (void *arg0)
    {
    字符 输入[257];
    UART_Params uartParams;
    /*调用驱动程序初始化函数*/
    GPIO初始化();
    UART_INIT();
    
    /*打开用户LED */
    GPIO写入(Board_GPIO _LED0,Board_GPIO _LED_ON);
    
    /*创建数据处理关闭的UART。 */
    UART_PARAM_INIT (&uartParams);
    uartParams.writeDataMode = UART_DATA_TEXT;
    uartParams.readMode = UART_MODE_callback;
    uartParams.readDataMode = UART_DATA_TEXT;
    uartParams.readReturnMode = UART_RETURE_FULL;
    uartParams.readEcho = UART_ECHO_OFF;
    uartParams.readCallback = uartReceiveFinished;
    uartParams.baudrate = 9600;
    UART = UART_OPEN (Board_UART1,&uartParams);
    IF (UART ==空)
    {
    system_abort("打开UART"时出错";
    }
    
    GPIO写入(Board_GPIO _LED0,Board_GPIO _LED_Off);
    GPIO写入(Board_GPIO _LED1,Board_GPIO LED关闭);
    
    GPIO写入(Fogwise_LDO1,Fogwise_LDO1_ON);
    /*循环永久回声*/
    而(1){
    交换机(命令计数器)
    {
    // 案例0:
    // probeSendByte (probe_STX);//commandBuffer[countNum+]= probe_STX;
    // probeSendByte (probe_set_bit_time);//commandBuffer[countNum+]= probe_set_bit_time;
    // probeSendByte (probe_STX);//commandBuffer[countNum+]= probe_STX;
    // probeSendByte(0x01);//commandBuffer[countNum+]= 0x01;
    // probeSendByte (BITTIMEVALUE);//commandBuffer[countNum+]= BITTIMEVALUE;
    // probeSendByte (probe_EOT);//commandBuffer[countNum+]= probe_EOT;
    // UART_READ (UART,输入,大小(输入));
    // GPIO切换(Board_GPIO _LED2);
    // 中断;
    
    // 案例0:
    // probeSendByte (probe_STX);//commandBuffer[countNum+]= probe_STX;
    // probeSendByte (probe_Get_Baud);//commandBuffer[countNum+]= probe_Get_Baud;
    // UART_READ (UART,输入,大小(输入));
    // 命令计数器=0;//
    中断;
    
    // 案例0:
    // probeSendByte (probe_STX);//commandBuffer[countNum+]= probe_STX;
    // probeSendByte (probe_set_attenuation);//commandBuffer[countNum+]= probe_set_attenuation;
    // probeSendByte (probe_STX);//commandBuffer[countNum+]= probe_STX;
    // probeSendByte(0x01);//commandBuffer[countNum+]= 0x01;
    // probeSendByte(ATTVALUE);//commandBuffer[countNum+]= ATTVALUE;
    // probeSendByte (probe_EOT);//commandBuffer[countNum+]= probe_EOT;
    // probeSendByte (probe_STX);//commandBuffer[countNum+]= probe_STX;
    // probeSendByte (probe_set_SIG_AVG);//commandBuffer[countNum+]= probe_set_SIG_AVG;
    // probeSendByte (probe_STX);//commandBuffer[countNum+]= probe_STX;
    // probeSendByte(0x01);//commandBuffer[countNum+]= 0x01;
    // probeSendByte(SIGAVGVALUE);//commandBuffer[countNum+]= SIGAVGVALUE;
    // probeSendByte (probe_EOT);//commandBuffer[countNum+]= probe_EOT;
    // UART_READ (UART,输入,大小(输入));
    // GPIO切换(Board_GPIO _LED1);
    // 命令计数器=0;//
    中断;
    
    // 案例0:
    // probeSendByte (probe_STX);//commandBuffer[countNum+]= probe_STX;
    // probeSendByte (probe_set_range_gate_DELAY0);//commandBuffer[countNum+]= probe_set_衰减;
    // probeSendByte (probe_STX);//commandBuffer[countNum+]= probe_STX;
    // probeSendByte(0x01);//commandBuffer[countNum+]= 0x01;
    // probeSendByte(RGD0VALUE);//commandBuffer[countNum+]= ATTVALUE;
    // probeSendByte (probe_EOT);//commandBuffer[countNum+]= probe_EOT;
    // probeSendByte (probe_STX);//commandBuffer[countNum+]= probe_STX;
    // probeSendByte (probe_set_range_gate_DELAY1);//commandBuffer[countNum+]= probe_set_SIG_AVG;
    // probeSendByte (probe_STX);//commandBuffer[countNum+]= probe_STX;
    // probeSendByte(0x01);//commandBuffer[countNum+]= 0x01;
    // probeSendByte(RGD1VALUE);//commandBuffer[countNum+]= SIGAVGVALUE;
    // probeSendByte (probe_EOT);//commandBuffer[countNum+]= probe_EOT;
    // UART_READ (UART,输入,大小(输入));
    // GPIO切换(Board_GPIO _LED1);
    // 命令计数器=0;//
    中断;
    
    // 案例0:
    // 命令Buffer[countNum+]= probe_STX;
    // probeSendByte (probe_STX);
    // 命令Buffer[countNum+]= probe_set_baud;
    // probeSendByte (probe_set_baud);
    // 命令Buffer[countNum+]= probe_STX;
    // probeSendByte (probe_STX);
    // 命令Buffer[countNum+]= probe_STX;
    // probeSendByte (probe_STX);
    // 命令Buffer[countNum+]= probe_9600_code;//
    probeSendByte (probe_baud _9600_code);
    // 命令Buffer[countNum+]='\0';
    // UART_READ (UART,输入,大小(输入));
    // GPIO切换(Board_GPIO _LED3);
    // 命令计数器=0;//
    中断;
    
    案例0:
    IF (getLen == 1028)
    {
    GPIO切换(板_GPIO _LED3);
    getLen = 0;
    }
    probeSendByte (probe_STX);//commandBuffer[countNum+]= probe_STX;
    probeSendByte (probe_start);//commandBuffer[countNum+]= probe_get波特;
    UART_READ (UART,输入,大小(输入));
    命令计数器=0;
    中断;
    
    默认:
    命令计数器=0;
    中断;
    }
    }
    静态
    
    void uartReceiveFinished(UART_Handle Handle, void *UART_rxBuffer, size_t count)
    {
    命令= uartMSP432Objects[1].ringBuffer.buffer;
    命令=(uint8_t*)UART_rxBuffer;
    memcpy((char*)(pcBuffer + getLen),(const char*)UART_rxBuffer, 257);
    getLen = getLen + 257;
    GPIO切换(Board_GPIO _LED0);
    }
    
    void probeSendByte(uint8_t byte){
    
    UART_WRITE (UART,字节,1);
    }
    
    

    您好,Chris:

    我已设法解决了该问题,并且以前在执行所有具有相同大小缓冲区的命令时,从脉冲程序读取响应时,就会出现该问题。

    但是,当我在switch语句中仅执行一个命令,并将读取缓冲区大小定义为应返回的数据大小时,我没有遇到任何问题。

    我还曾将命令作为字符串发送,末尾带有'\0'字符,但脉冲程序未识别该字符串,因为在其协议定义中不可接受。

    现在,这将留下一个查询。

    因为在我的应用程序中,我有一组命令需要发送到脉冲程序,并且需要从脉冲程序返回响应。

    由于所有命令都应该接收不同的字节计数,因此在运行时如何更改缓冲区大小,以便每当我收到给定命令的全部数据时,都执行uartReceiveFinished函数。

    我知道当我们使用CC3200时,它有一个UART_RETURE_PARTIAL选项,当我们不知道要接收的数据的大小,但我看不到MSP432的此选项。

    我要附上修改后的代码,以便您查看并了解我的查询。

    在代码中,我对我不想运行的案例进行注释,并在任何给定时间仅运行一个案例。

    此外,char input[size]的大小也始终根据对脉冲程序的期望而更改。

    提前感谢您的参与。

    Vikram