就我对 FreeRTOS 的记忆而言,如果您确实创建了具有相同优先级的所有线程,那么如果您不定义 USE_TIME_SLICING 或定义它并将其设置为“1”,那么您只会获得您想要的平等共享。
当涉及到多个线程竞争对硬件资源(或共享内存资源)的访问时,您总是希望以某种方式控制对它的访问。在这种情况下,最简单(虽然不是最快)的选项是使用互斥锁,FreeRTOS 也有二进制信号量,可以完成同样的事情,而且速度可能会稍微快一些。通常,尽管互斥锁和二进制信号量是可以互换的。对于两者的详细信息,我会去阅读关于它们的 FreeRTOS 文档,它应该可以解决问题。
如果你原谅伪代码,你希望每个线程都按照以下方式做一些事情
createMutex(UART_Lock)
void task1
{
while(1)
{
if(GetLockOnMutex(UART_Lock))
{
PrintToUART();
ReleaseMutex();
}
}
}
void task2
{
while(1)
{
if(GetLockOnMutex(UART_Lock))
{
PrintToUART();
ReleaseMutex();
}
}
}
void task3
{
while(1)
{
if(GetLockOnMutex(UART_Lock))
{
PrintToUART();
ReleaseMutex();
}
}
}
因此,当每个线程进入上下文时,它会尝试锁定互斥锁,该互斥锁用于限制对 UART 的访问。如果成功,那么它将发送一些东西,并且只有当打印函数返回时(可能超过多个时间片),它才会释放 UART 上的锁,以便另一个线程尝试获取。如果一个线程无法获得锁,那么它会再次尝试,直到它的时间片结束。您可能有一个无法获得锁的线程让自己重新进入睡眠状态,直到它下一次进入上下文,但这只有在您的 CPU 非常繁忙并且您必须考虑您的任务是否真的可以调度时才真正重要。
基本上,如果您不控制对 UART 的访问,并且无法保证在给定时间片内线程完成对 UART 的访问,那么调度程序可以抢占未完成的线程,其他人可以尝试使用UART。
假设 UART 发送缓冲区可能会在您的情况下对其进行排序是合乎逻辑的,但您真的不想依赖它,因为它只有这么大,没有什么可以阻止一个线程完全填满它。