4

私は、a) FreeRTOS の taskGetTickCount() 関数が機能する方法を誤解しているか、b) 私たちの移植で何かが正しくないかのいずれかだと思います。

xTaskGetCount() の出力を表示しているデバッグがあります。vTaskDelayUntil() を実行するたびに、更新されて最新のように見えます。しかし、スピン待機を行って、それが増加するのを待っていると、決して増加しません。割り込みが発生したと思い、その値をインクリメントしました。しかし、私は現時点で 1 つのタスクしか実行していないので、再スケジュールをチェックせず、tickCount が更新されないのは賢明でしょうか? FreeRTOS のティック カウントがどのように機能するかを教えてくれる人なら誰でも、私は大いに感謝します。

編集:サンプルフラグメント:

void someTask(void * _)
{
    portTickType now = xTaskGetTickCount();
    for( ; xTaskGetTickCount() - now < 25; )
    {
        debug("%u", xTaskGetTickCount();
    }
} 

これは、ティック = 1 ミリ秒のときに暗示された 25 ミリ秒をはるかに超えて、永遠にスピンします。出力には、同じ値が何度も何度もリストされます。ただし、ループの最後に vTaskDelay() を追加すると、正常に増加し、最終的にドロップアウトします。

4

2 に答える 2

3

使用しているポートはわかりません。基本的に、コードに問題はありませんが、そのようなことを行うのは珍しいことです。ループがブロックされることはないため、実行時間の優先度の低いすべてのタスクが不足し、同じ優先度のタスクでタイムスライスされます。

ここにいくつかのメモがあります:

この問題に対するより良い解決策は次のとおりです。

while( whatever )
{
    vTaskDelay( 25 );
    DoSomething();
}

debug()はFreeRTOSステートメントではなく、どのように実装されているのかわかりません。ある種のセミホスティングを使用している場合は、debug()を呼び出すと、プロセッサの実行が長期間停止している可能性があります(どちらかはわかりません)。

于 2012-12-22T08:41:57.560 に答える
0

vTaskDelay( 25 );

さて、あなたは何を提案しましたか?! これは解決策ではありません。VTaskDelay() は、vTaskDelay() の呼び出し時からカウントされる期間、タスクをロック状態に変換する関数です。

VTaskDelayUntil () - この関数は、指定された期間で周期的な実行を提供します。

ループはブロックされないため、実行時間のすべての優先度のタスクが不足し、同じ優先度のタスクでタイム スライスされます。

vTaskDelayUntil () 関数を使用して、特にこれを回避してください。たとえば、コードの重要な領域のため、vTaskDelay () 関数でこの松葉杖を置くことができず、xTaskGetTickCount () 関数は常に 0 を返します。そして、この問題を解決することはできません ((

数時間の拷問の後:

void StartTask01(void const * argument)
{
  portTickType xLastWakeTime;
  xLastWakeTime = xTaskGetTickCount();
  const portTickType xPeriod = pdMS_TO_TICKS(100);

  while(1)
  {
    canInterviewMC_100();                       // Interview CAN Message
    vTaskDelayUntil(&xLastWakeTime, xPeriod);
  }
}

その結果、このコードは 100ms ごとに実行されます。同時に、最も優先度が高くなりますが、このタスクは 100ms に 1 回しか実行されないため、優先度の低いタスクの CPU 時間を消費しません。

于 2017-07-20T12:53:37.253 に答える