2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

FreeRTOS概要

Last updated at Posted at 2024-09-09

FreeRTOSを仕事で使う機会がありましたので、使用方法・OSの振る舞いの概要をここにまとめておこうかと思います。
コンフィグや各API、タスクの状態監視の説明は下記の別記事にて説明いたします。

FreeRTOS( https://www.freertos.org/ )とは

複数のマイクロコントローラに対応した、オープンソースのRTOS。各マイクロコントローラごとにサンプルが用意されているため、導入は難しくない。

ライセンス

バージョン9までは例外条項付きGPLの下で配布されていた。 例外条項は、カーネルそのものがオープンソースである場合にはユーザのコードをクローズドソースにしておくことができるという内容である。Amazon.comに買収された後のバージョン10からはMITライセンスを採用している。
(wikipediaより引用)

用語

用語 意味
アイドルタスク アイドルタスクとは優先度が最小値で設定されている。
常時実行可能な状態のタスクのことを示す。
実行するタスクが無い場合、このタスクが動く。アイドルタスクはOSの処理で定義されている(コルーチンを使う場合は一部ユーザで手を入れる)。
タスクトレース 作成されたタスク情報を出力する機能。OSの設定方法によっては使用可能
コルーチン コルーチンはタスクと違い、スタックを共有する小さなタスクのことを示す。主に低スペックなCPUでのマルチタスク動作がしたい場合に用いる

タスクステート

タスクの状態に関して説明する。タスクは生成された時点ではreadyステートになり、4つのステートどれかに設定されている。以下のリンクを参照のこと

タスク状態図

引用元:https://www.freertos.org/RTOS-task-states.html

Running

実行状態であることを示す。現在実行されているタスクがRunningステートとなる

Ready

実行可能状態であることを示す。現在実行されているタスクより優先度が低く、Blockedステート・SuspendedステートではないタスクがReadyステートとなる

Blocked

別タスク・もしくは割込みからのOSのシステムコール(イベントフラグ・メッセージボックス・データキュー等)を待っている際になるステート

Suspended

vTaskSuspend()を呼び出した際になるステート。Blockedステートとは厳密には違う状態として扱う
(ただし、ソースコードを見る限りではBlockedステートと同じ扱いをしている)

スケジューリング

FreeRTOSのスケジューラは「FreeRTOSConfig.h」の「configUSE_PREEMPTION」の値を1と定義するとプリエンプティブになる。「configUSE_PREEMPTION」の値を0とした際は協調的スケジューリングとなる

プリエンプティブスケジューリング

基本的なスケジューリングは、Itron系OS等と同等なスケジューリングを行う。ただし、同じ優先度のタスクにおいては「FreeRTOSConfig.h」の「configUSE_TIME_SLICING」の値を1にしていると、同じ優先度のタスク同士でタイムスライスを行い、交互にそれぞれのタスクが動く。また、タスクの切り替えのタイミングは以下の3つである

  • OS用のタイマ割込み

    • タイマ割込みの頻度はFreeRTOSConfig.h内のconfigTICK_RATE_HZの値で調節可能。1秒間の間にconfigTICK_RATE_HZで指定した値の回数分だけが呼ばれる。ただし、内ではOSで使用するタイマのカウントも行うため、タスクを1ms刻みでwait,delayする際にはconfigTICK_RATE_HZの値を1000にしておく必要がある。(configTICK_RATE_HZの値は1000で固定を推奨)
  • RunningステートのタスクがBlockedステートorSuspendedステートに切り替わった時

  • OSのシステムコールにより、BlockedステートorSuspendedステートのタスクがreadyステートに切り替わった時

協調的スケジューリング

「configUSE_PREEMPTION」の値を0に設定し、「configUSE_TIME_SLICING」の値を1にすると、
全てのタスクが均等に実行される設定となる。

「configUSE_PREEMPTION」の値を0に設定し、「configUSE_TIME_SLICING」の値を0にすると、
優先度低のタスクであろうと、実行中であれば、他のタスクへスイッチしなくなる。Delayなどで自身のタスクを待ち状態にしないといけなくなるので注意。

コルーチン

  • タスクとは異なる、複数の関数(コルーチン)を平行して実行させる仕組み。メモリの制約上、タスクを大量に作ることが困難な場合など、小規模なシステムで使用されることを想定している

  • タスクとコルーチンではタスクの方が優先され、アイドルタスクが実行されるタイミングでコルーチンは動作する

  • コルーチンも、ステートと優先度が存在し、優先度が高く実行可能な状態(Ready状態)のコルーチンから実行される(Running状態となる)

引用元:https://www.freertos.org/media/2018/crstate.gif
引用元:https://www.freertos.org/media/2018/crstate.gif

タスクとの共存方法

アイドルタスク(vApplicationIdleHook())内でコルーチンを作動させるための関数「vCoRoutineSchedule()」を呼び出すことでタスクと共存させて、動作させる。

FreeRTOSのコード例

一つ以上のタスクを生成し、「vTaskStartScheduler()」を呼び出すことによりOSのスケジューリングが開始される。

以下にFreeRTOSを使用した際のmain.cのコード例を示す。以下の例では優先度2、スタックサイズ1024のタスク(mainTask)を作成し、動作させている

コード例:

/* FreeRTOS用モジュール */
#include "FreeRTOS.h"
#include "task.h"

#define THREAD_NAME  "THREAD1"
#define THREAD_PRIORITY  (2)
#define SAMPLE_STACKSIZE  (1024)

TaskHandle_t task1;
static int task_delay = 1000;
static void mainTask( void *pvParameters );

int main()
{
  if (pdTRUE != xTaskCreate(mainTask, THREAD_NAME, SAMPLE_STACKSIZE, &task_delay, THREAD_PRIORITY, &task1))
  {
    return;
  }

  /* RTOSの動作開始。中で無限ループしている。エラーがかかった場合のみリターンされる */
  vTaskStartScheduler();

  while(1);
}

static void mainTask( void *pvParameters )
{
  const TickType_t xTicksToDelay = 1000 / portTICK_PERIOD_MS;

  while(1) {
      vTaskDelay( xTicksToDelay );
  }
}
2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?