0

AVR 用の単純なタスク システムを作成しようとしました。このコードはこちらです。(残念ながら、これは MWE でもあります。)

システムの背後にある基本的な考え方は、定期的なタイマー割り込みがフラグを設定し、メイン アプリケーション ループがそれをチェックしてタスクを実行するというものです。タスク処理関数は再入可能であるため、保留中のタスクごとに反復ごとに 1 回だけ実行されます。

while (1) {
    if (flTask) {
        flTask = task_process_next();
    }

    // Do other awesome stuff in the loop
}

設計をシンプルに保つために、定期的に実行したいタスクはそれ自体を再投稿する必要があります。

したがって、単純なハートビート タスクは次のように追加できます。

task_add(heartbeat_task, 0);

そのコードは次のようになります。

void heartbeat_task(void)
{
    task_add(heartbeat_task, 10000); // Re-post task

    led_toggle(LEDGreen);
    xbee_send_heartbeat(BASE_STATION_ID);
}

私の問題は次のとおりです。各定期タスクは正確に 2 回実行されます。

task_add各タスクの最初の実行と繰り返しの実行中にメソッドが呼び出されることを、ピンを切り替えることで確認しました (リンク先のコードで確認できます) 。

ただし、明らかにタスクを 2 回目に追加したにもかかわらず、実行されません。

さらに、コードをtask_process_next大幅に簡素化しようとしました (1 回の呼び出しですべてのタスクを処理するループを追加したり、実行条件を変更してオーバーフローを無視したりするなど)。これらの変更はどちらも成功しませんでした。


私の質問は次のとおりです。再投稿されたタスクが無視される可能性があるリンクリスト実装の詳細を台無しにしましたか?

特に、リスト内のノードが評価または実行されずにスキップされるように誤って作成したのでしょうか?

ハードウェアで実行せずにこの種の問題をデバッグするのは難しいことは理解していますが、私が見逃していたことを別の人が見てくれることを願っています。

追加情報を提供したり、必要なテストを行ったりできれば幸いです。

4

1 に答える 1

0

最後のタスクが削除されたときに、キューが破損していました:

    if (prev) {
        prev->next = task->next;
    } else {
        tasks.head = task->next;
    }

    // Adding these lines fixed the problem
    if (task == tasks.tail) {
        tasks.tail = prev;
    }
于 2013-09-09T12:52:28.243 に答える