如何让许多 FreeRTOS 任务等待彼此完成初始化

How to make many FreeRTOS tasks wait for one other to complete initialization

我有一个 init 任务和几个工作任务。在某些时候,工作人员必须等待 init 才能完成一些设置。我正在尝试使用二进制信号量来执行此操作。

当调度程序启动时,所有任务都准备就绪 运行。因此,为了保证工作人员等待,信号量必须在调度程序启动之前为 "taken by the init task"。 (否则工作人员甚至可以在 init 被安排之前获得信号量。)

我该怎么做?或者我应该如何解决这个问题?

如果你只有一个工作任务,二进制信号量就可以工作。您可以将信号量创建为 "unavailable" / "taken",初始化任务将在初始化完成时 xSemaphoreGive 信号量,通知单个工作任务初始化已完成。但是,当您有多个任务时,那么只有其中一个能够 take/acquire 信号量。

计数信号量可以工作。信号量的容量应该等于工作任务的数量,并且它应该以空开始。作为系统设计者,您知道 init-task 被设计为在启动时拥有底层资源,因此 init-task 不必在第一次初始化时获取信号量。初始化后,您应该为每个工人调用一次 xSemaphoreGive。 When/if 你想重新初始化,为每个工作任务调用一次 xSemaphoreTake。为此,工作人员必须定期 "release" 信号量,然后重新获取它。

一个 Event Group could also be used if you'll only initialize once. Your init-task can use xEventGroupSetBits to indicate that initialization is complete. Your worker tasks can use xEventGroupWaitBits 等待初始化任务完成。

当您有多个任务在等待信号或事件时,二进制信号量不是正确的机制。使用二进制信号量,一次只有一个任务可以获取信号量,并且当给出二进制信号量时,只有一个任务将准备好 运行。我想每个等待任务都可以接受,然后立即将信号量交给下一个等待任务,但这看起来很奇怪。

你能不能简单地让 Init 任务成为最高优先级的任务,直到它完成必要的初始化。由于优先级较低,其他任务在初始化完成之前不会 运行。初始化完成后,您可以删除 Init 任务或降低其优先级。

如果优先级不是一个选项,那么您应该使用事件位(事件标志)。对于您的用例,事件位是比二进制信号量更好的机制,因为当 Init 任务发出事件信号时,多个等待任务可以准备好 运行。

二进制信号量就可以了。将其初始化为 0 个单位。

启动所有其他线程并让它们在适当的时间点等待信号量,如果它们获得一个单元,立即 post 在继续之前再次返回该单元。 sema没有单位,大家还得等等。

根据需要继续进行初始化,然后向信号量发出信号。然后所有等待的线程将 运行 打开,一个接一个地获取单元,然后 post 再次返回。