freeRTOS:如何在任务之间传递数据?

use*_*538 2 c microcontroller stm32 freertos

我正在寻找一个示例,它提供了在任务之间传递数据的正确方法:

假设我有一个显示器、键盘和一些传感器,例如。内部 ADC。我想在显示屏上显示所有传感器的值。按下按钮后,更改视图并呈现一些文本。按另一个后,返回值。

我会使用全局变量,但到处都将其描述为一个坏主意。另一方面,如果我使用队列(xQueueCreate、xQueueReceive、xQueueSend),我就不会有所有数据来显示它,并且我相信在接收它们后创建副本只会丢失内存。

小智 5

您已经提到了一些可能的解决方案,但是说您因为复制数据而丢失了内存,如果您想保护这些数据不被从两个不同的地方写入,那么情况总是如此,无论如何,只要使用 FreeRTOS,您就已经决定丢失内存大量内存用于上下文切换、任务处理以及 FreeRTOS 使用的所有其他资源。可能的解决方案是:

  1. 全局变量 - 这就是为什么它是一个坏主意的原因,因为理想情况下你想限制对变量(范围)的访问。同样很难保证它的安全,因为在任务切换期间,其他任务可能会写入同一变量,并可能损坏您的数据。但是,如果您正确保护它,即使用某种标志锁定变量,这是完美的解决方案,并使用即信号量或队列来通知显示任务数据已填充。

  2. 队列 - 您可以从多个任务发送,正如您所说,保留显示任务变量的副本,这是更安全的选择,并且不必丢失内存,因为您不必将其存储在任何其他地方,您可以只读取传感器,然后将其放入队列中,然后当您在显示任务中收到它时,您可以更改之前的值。因此,假设 ADC 读取数据的任务不需要在读取之间存储数据。

  3. 队列 - 但与您提议的有点不同,如果您在系统中获得直接流,那么我们首先检查键盘,然后检查传感器,然后您可以使用 TASK1 -> TASK2 -> TASK3 -> ... 的结构发送队列。 TASKX -> DISPLAY_TASK 这种方式变量将具有一定的流程,并且您将确保您始终将所有数据集中在一处。
  4. 您可以在所有结构中使用相同的参数(taskCreation 中的 pvParameters),因此您将指向相同的结构,在这种情况下,为了保护数据,您可以在写入变量期间使用互斥体(因此您知道一次只有 1 个任务可以访问到这个变量)。您也可以在全局变量选项中使用互斥体。