Synchronization 如何使多个FreeRTOS任务等待另一个任务完成初始化

Synchronization 如何使多个FreeRTOS任务等待另一个任务完成初始化,synchronization,task,semaphore,freertos,rtos,Synchronization,Task,Semaphore,Freertos,Rtos,我有一个init任务和几个worker任务。在某些时候,工人必须等待init完成一些设置。我试着用一个二进制信号量来做这件事 当调度程序启动时,所有任务都准备好运行。因此,为了保证工人等待,在调度程序启动之前,必须“由inittask获取”信号量。(否则,工人甚至可以在计划init之前获得信号量。) 我该怎么做?或者我应该如何解决这个问题呢?如果您只有一个辅助任务,那么二进制信号量就可以工作。您可以将信号量创建为“unavailable”/“take”,初始化完成后,init任务将激活信号量,通

我有一个
init
任务和几个worker任务。在某些时候,工人必须等待
init
完成一些设置。我试着用一个二进制信号量来做这件事

当调度程序启动时,所有任务都准备好运行。因此,为了保证工人等待,在调度程序启动之前,必须“由
init
task获取”信号量。(否则,工人甚至可以在计划
init
之前获得信号量。)


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

如果您只有一个辅助任务,那么二进制信号量就可以工作。您可以将信号量创建为“unavailable”/“take”,初始化完成后,init任务将激活信号量,通知单个工作任务初始化已完成。但是,当您有多个任务时,其中只有一个任务能够接收/获取信号量

计数信号灯可以工作。信号量的容量应该等于辅助任务的数量,并且应该以空开始。作为系统设计器,您知道init任务被设计为在启动时拥有底层资源,因此init任务不必在第一次初始化时获取信号量。初始化之后,应该为每个工作进程调用一次。如果要重新初始化,请为每个辅助任务调用一次。为了使其工作,工作人员必须定期短暂地“释放”信号量,然后重新获取它


如果只初始化一次,也可以使用。初始化任务可用于指示初始化已完成。您的辅助任务可以用来等待init任务完成。

当多个任务等待信号或事件时,二进制信号量不是正确的机制。对于二进制信号量,一次只能有一个任务接收该信号量,并且在给定二进制信号量时,只有一个任务准备好运行。我想每个等待的任务都可能需要,然后立即将信号量发送给下一个等待的任务,但这似乎很奇怪

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


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

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

启动所有其他线程,让它们在适当的位置等待信号量,如果它们得到一个单元,则在继续之前立即将该单元发回。因为sema没有单元,所以所有组件都必须等待


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

谢谢,我将查看事件位。但对于我最初提出的解决方案,如何“将信号量创建为“不可用”/“已使用”?我只能看到
xSemaphoreCreateBinary(void)并且它没有参数来告诉它最初是可用的还是使用的。啊。。。它似乎总是像FreeRTOS那样被创造出来的。另外,正如我所提到的,二进制信号量不能与多个辅助任务一起工作。@非用户二进制信号量是在空状态下创建的,必须在获取之前给出。Init任务不需要接收信号量。在必要的初始化完成后,Init任务将给出信号量(从未接受它)。把它看作是一个信号。Init任务通过给出信号量来断言/设置信号。其他任务通过接收信号量来等待信号。但二进制信号量的问题是,一次只能有一个等待任务接收二进制信号量。“二进制信号量的问题是,一次只能有一个等待任务接收二进制信号量”-这不是问题。当一个等待的线程获取单元并运行时,它会将该单元发回信号量,以便下一个线程获取:)@MartinJames,这可能会起作用,但如果需要重新初始化(如果有必要的话),您不会知道所有的辅助任务都已停止。但是说得对我想每个等待的任务都可能需要,然后立即将信号量发送给下一个等待的任务“-这并不奇怪,很好:)