私の FreeRTOS の記憶によると、すべてのスレッドを同じ優先度で作成した場合、USE_TIME_SLICING を定義しないか、それを定義して「1」に設定した場合にのみ、希望する均等な共有が得られます。
複数のスレッドがハードウェア リソース (または共有メモリ リソース) へのアクセスをめぐって競合する場合、何らかの方法でアクセスを制御する必要があります。この場合、最も簡単な (ただし最速ではありませんが) オプションは、mutex を使用することです。一般に、mutex とバイナリ セマフォは交換可能です。2 つの詳細については、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。
あなたの場合、UARTs送信バッファがそれを整理するかもしれないと仮定するのは論理的ですが、それは非常に大きく、1つのスレッドが完全にいっぱいになるのを止めるものは何もないので、実際にはそれに依存したくありません.