代码之家  ›  专栏  ›  技术社区  ›  not-a-user

如何使多个freertos任务等待对方完成初始化

  •  1
  • not-a-user  · 技术社区  · 6 年前

    我有一个 init 任务和几个工人任务。在某种程度上,工人们必须等待 初始化 完成一些设置。我正试图用二进制信号量来实现这一点。

    当调度程序启动时,所有任务都准备好运行。因此,为了保证工作人员等待,信号灯必须由 初始化 任务“在调度程序启动之前。(否则,工作人员可以在 初始化 甚至预定了。)

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

    3 回复  |  直到 6 年前
        1
  •  1
  •   Pinetwig    6 年前

    如果您只有一个工作任务,那么二进制信号量就可以工作。您将创建信号量为“unavailable”/“taken”,而init任务将 xSemaphoreGive 初始化完成时的信号量,通知单个工作进程初始化已完成。但是,当您有多个任务时,它们中只有一个能够接受/获取信号量。

    计数信号灯可以工作。信号量的容量应该等于工作任务的数量,并且应该以空的形式开始。作为系统设计器,您知道init任务设计为在启动时拥有基础资源,因此init任务不必在第一次初始化时获取信号量。初始化之后,您应该调用 XSemaphoregive 每个工人一次。当/如果要重新初始化,请调用 xSemaphoreTake 每个工人任务一次。为了实现这一点,工作人员必须定期“短暂地释放”信号量,然后重新获取它。

    Event Group 如果只初始化一次,也可以使用。您的初始化任务可以使用 xEventGroupSetBits 指示初始化完成。您的工作任务可以使用 xEventGroupWaitBits 等待初始化任务完成。

        2
  •  2
  •   kkrambo    6 年前

    当有多个任务在等待信号或事件时,二进制信号量是不正确的机制。使用二进制信号量时,一次只能有一个任务接收信号量,当给定二进制信号量时,只有一个任务可以运行。我想每一个等待的任务都可以接受这个信号,然后立即将它发送给下一个等待的任务,但这似乎很奇怪。

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

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

        3
  •  2
  •   Martin James    6 年前

    二元信号量就可以了。初始化为0个单位。

    启动所有其他线程,让它们在适当的点等待信号量,如果它们得到了一个单元,那么在继续之前,请立即将该单元发回。所有的都必须等待,因为SEMA没有单元。

    根据需要进行初始化,然后发出信号灯。然后,所有等待的线程都将运行,一个接一个地获取单元,然后重新发布。