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.

[参考译文] RTOS/MSP432-RTOS:当不同任务从不同 UART 读取数据时、数据丢失

Guru**** 2563930 points


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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/598563/rtos-msp432-rtos-data-lost-when-different-tasks-are-reading-data-from-different-uarts

器件型号:MSP432-RTOS

工具/软件:TI-RTOS

 在应用程序调试期间,我们在 TI-RTOS 中遇到了 UART 问题。

有两个任务分配了不同的优先级,高优先级任务(比如任务 A)是从 UART1读取和处理命令,低优先级任务(比如任务 B)是从 UART2读取和解析 GPS 数据。 当任务 B 从 UART2读取数据时、任务 A 无法从 UART1读取任何数据、即使任务 B 已完成读取数据。 当另一个任务从另一个 UART 读取数据时、到达一个 UART 的数据将丢失。

您能不能在这个问题中进行仔细观察?

谢谢、

Tony

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我建议您实现一个循环缓冲器:
    www.simplyembedded.org/.../
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    谢谢 Keith。 这对于了解根本原因并在没有操作系统的情况下实施解决方案非常有帮助。

    我们使用的是 TI-RTOS、我认为操作系统应该已经为 UART 实现了循环缓冲器。  此外、当数据准备好读取时、高优先级任务应该优先于低优先级任务。 但是、在高优先级任务中无法读取任何数据。 这似乎是操作系统的问题。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    这取决于 UART 驱动程序在 RTOS 中的实现方式。
    如果接收代码被执行为

    while (!UART_DataAvailable(UART1_base));

    没有一个 RTOS 能够正确处理这种情况。 在多线程应用中、您应该高度依赖于中断和信标。 因此、如果您使用的是基于中断的接收、则应启用中断并等待信号量、中断处理程序应向信号量发送信号、而 RTOS 调度程序将执行任务预处理。

    另一种实现同步通信的方法是使用 DMA。 您可以通过软件定时器和"传输完成"中断来检查可用数据。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    这两个任务的优先级是什么(请参见 Tools->ROV->Tasks->Detailed 以确认目标)? 为什么您说较高优先级的任务被较低优先级的任务阻止? 您可以在 ROV 中确认这一点、还是看起来就像这样?

    Todd

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

    一般来说、RTOS 仅意味着内核提供多任务处理和任务间通信。 与 Windows 或 Linux 不同、它已经内置了许多"驱动程序"。 在 RTOS 中、驱动程序独立于内核。 所以、不要将它们混在一起。

    TI 提供了一些基于 TI-RTOS 的驱动程序。 但是、您可以(应该?) 设计您自己的驱动器、以实现更高的效率并满足您的用例要求。 要设计器件驱动程序、例如 UART 驱动程序、您应该牢记:在不需要时不要阻止 CPU。 例如、以下情况确实很糟糕:

    while (!isReady); 

    这更好:

    while (!isReady)
    睡眠(10); 

    其中、SLEEP (10)是一个内核 API、用于告知内核此任务在10ms 内不会使用 CPU。 嗯,所有 RTOS 都有自己版本的 SLEE()。 请查阅 TI-RTOS 文档以获取正确的 API 名称。

    以下是最佳选择:

    if (Semaphore_pend (&UART_SEMA、1000){
    //获取数据
    
    }否则{
    // 1000 ms 后进行分度
    } 

    如果您使用信标和中断服务例程(ISR)来设计器件驱动程序、则不会浪费 CPU 时间。 同样、请检查 TI-RTOS 文档以获得正确的信号量 API 名称。

    我不使用 TI-RTOS、因此无法为您提供可立即测试的示例。 但基本概念是相同的。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    Tony、
    只是在这里跟进、看看您是否发现了问题或是否有任何后续问题?
    -Priya