この記事について
Mastering the FreeRTOS Real Time Kernel-A Hands-On Tutorial Guildの日本語訳
Chapter 1 The FreeRTOS Distribution
1.2 FreeRTOSの理解
FreeRTOS Portの定義
FreeRTOSは約20の異なるコンパイラでビルド可能で、30以上のCPUアーキテクチャ上で動きます。コンパイラとプロセッサの組み合わせを「FreeRTOS port」と定義する。
FreeRTOS ビルド
FreeRTOSはCのソースファイル。port共通のファイルと、port独自のファイルがある。FreeRTOSファイルは自分ののプロジェクトのソースファイルとして加えること。簡単に構築するには各portで準備されているデモアプリケーションがあるので利用すると良い。
デモアプリケーションはすぐ使えるようになっている。
out of the boxは「取り出してすぐ使える」という意味
FreeRTOSConfig.h
FreeRTOSはFreeRTOSConfig.hによってConfigされる。
FreeRTOSConfig.hはアプリケーション固有の設定に使われる。たとえばconfigUSE_PREEMPTIONではco-operative or pre-emptiveどちらにするかを決められる。アプリケーション固有のファイルなので、FreeRTOSConfig.hはFreeRTOSソースコードのディレクトリには含まれない。
デモアプリはすべてのportに提供されていて、FreeRTOSConfig.hも含まれる。そのため一からFreeRTOSConfig.hを作る必要はない。デモの設定で初めて、アプリケーションに合わせて変更していくことをお勧めする。
公式 FreeRTOS Distribution
FreeRTOSはzipで提供される。すべてのportのデモアプリが含まれる。
FreeRTOSのファイルの数にうんざりしないこと!1つのアプリケーションに必要なファイル数は少ない。
FreeRTOS ディレクトリ構成
port共通のFreeRTOSソースファイル
port共通のコアとなるファイルはたった2つとなる。Figure.2に示す、FreeRTOS/Sourceいかに配置される。加えて以下のファイルも配される。
task.c
queue.c
queue.c
queue.cはqueueとsemaphoreを提供する。説明は後述。
timers.c
timers.cはタイマー機能を提供する。説明は後述。
event_groups.c
event_groups.cはグループ機能を提供する。説明は後述。
croutine.c
croutine.cはco-routine機能を提供する。co-routineはとても小さいマイコン用途に使われるが、最近は滅多に使われない。そのため他のFreeRTOS機能のレベルまでメンテされていない。co-routinesはこの本では説明しない。
プロジェクトで同じファイル名を使っていると名前空間が衝突するが、ファイル名を変えると他のFreeRTOSプロジェクトとの互換性に問題が出る。
port特有のFreeRTOSソースファイル
port特有のファイルは FreeRTOS/Source/portable ディレクトリにある。portableディレクトリはFigure 3に示すように、compiler-processor architectureと階層構造になっている。
もし、ある'architecture'と'compiler'でFreeRTOSを動かしたいのであれば、FreeRTOS/Source/portable/[compiler]/[architecture] ディレクトリをビルドする必要がある。
Chapter 2で説明する通り、ヒープメモリ管理はportable layerで考慮される。FreeRTOS V9.0.0 より古い場合はheap memory managerを含む必要がある。v9.0.0からはheap memory managerはconfigSUPPORT_DYNAMIC_ALLOCATIONが1に設定されている、もしくは定義されていない時に必要となる。
FreeRTOSは5つのヒープ割り当てスキームを有する。5つのスキームはheap_1 から heap_5と名付けられ、heap_1.cからheap5.cにそれぞれ実装されている。ヒープアロケーションスキームの例はFreeRTOS/Source/portable/MemMang ディレクトリにある。もし動的なメモリ割り当てをする場合は、5つのうちの1つをビルドする必要がある。自身のアプリで実装する場合はその限りではない。
Inlucde Paths
FreeRTOSは3つのディレクトリをコンパイラのinlucde pathに含める必要がある。
- FreeRTOS/Source/include にあるcore FreeRTOSヘッダーファイル
- FreeRTOS/Source/portable/[compiler]/[architecture] にあるポート特有のファイル
- FreeRTOSConfig.hまでのパス
ヘッダーファイル群
FreeRTOS APIを使うアプリケーションは'FreeRTOS.h'をインクルードする必要がある。
続いてAPIのプロトタイムが宣言されているヘッダ、たとえばtask.h, queue.hなどを記述する。
1.3 デモアプリケーション
各portのFreeRTOSは少なくとも1つのデモアプリケーションを含んでいる。
Linuxユーザー向けのnote:
FreeRTOSはWindowsホストで開発、テスト可能となっている。まれにデモプロジェクトをLinux環境でビルドするとエラーが発生する。
ビルドエラーは大抵、ファイル名の大文字小文字に関連するもの、もしくはファイルパスのスラッシュ/に関連するものです。
このようなエラーを見つけたら http://www.freertos.org/contact までご連絡ください。
デモプロジェクトはいくつかの目的があります。
- 正しいファイルがインクルードされ、コンパイラオプションが設定されたサンプルを提供する
- 前提知識なしですぐに使える最小構成を提供する
- FreeRTOS APIがどのように使われるかのデモを提供する
- 自身のアプリケーションを作るときのベースを提供する
デモプロジェクトはFreeRTOS/Demoディレクトリにあります。サブディレクトリは各portに対応しています。
全てのデモアプリはFreeRTOS.orgに記載されています。このウェブページは以下の情報を含みます
- プロジェクトファイルのFreeRTOSディレクトリ構造配置
- どのハードウェアがコンフィグされているか
- どのようにデモの動作用のハードウェアをセットアップするのか
- どのようにデモをビルドするのか
- 期待動作
全てのデモプロジェクトは共通のタスクのサブセットがあります。実装は FreeRTOS/Demo/Common/Minimal ディレクトリ以下です。
common demoタスクは単純なFreeRTOS API使用方法のデモです。特に有用な機能を含んでいるわけではありません。
さらに最近のデモプロジェクトは'blinky'プロジェクトがビルドできます。'blinky'プロジェクトは2つのタスクと1つのqueueを使う基本的なプロジェクトです。
全てのデモはmain.cを含みます。main()からタスクは生成されます。具体的な情報はmain.cのコメントを読んでください。
ファイル階層はFiugure 4に示します。
1.4 FreeRTOSプロジェクトを作る
デモファイルを流用する
全てのFreeRTOS portは、エラー、ワーニングのない少なくとも1つのデモアプリがあります。これを自身アプリケーションに最適化していくのがおすすめです。正しいファイルがインクルードされ、正しい割り込みハンドラの実装が可能で、コンパイラのオプションも正しくセットされます。
デモプロジェクトから新しいアプリケーションを作るには
- ビルドして実行できるデモプロジェクトを開く
- デモタスクが定義されているファイルを消す。Demo/Common 以下のファイルはすべて消す
- main関数から prvSetupHardWare(), vTaskScheduler()以外の関数は全部消す。Listing 1な感じで。
- この状態でビルド可能か確認する
このステップで正しいFreeRTOSはincludeできていて、何の機能も実装されていないという状態にできる。
1からプロジェクトを作る
既に記載したとおりにデモプロジェクトを流用することがお勧めですが、望ましくない場合には新しいプロジェクトを以下の手順で生成できます。
- ツールチェーンを使って、FreeRTOSソースファイルを含まない新しいプロジェクトを作る
- 新しいプロジェクトでビルドして、ターゲットのハードウェア上で実行できることを確認する
- すでに動作するプロジェクトがある場合には、Table 1のFreeRTOSソースファイルを加える
- デモプロジェクトのFreeRTOSConfig.hを自身のアプリケーションのディレクトリに追加する
- サーチできるpathに以下追加する
FreeRTOS/Source/include
FreeRTOS/Source/portable/[compiler]/[architecture] (自身のportに合う [compiler], [architecture])
The directory containing the FreeRTOSConfig.h header file
- デモプロジェクトからコンパイラ設定をコピーする
- FreeRTOS割り込みハンドラが必要であれば実装する。説明されているwebページを参考にしてください。またデモプロジェクトに各portでの使い方が記載されています。
FreeRTOS V9.0.0より古いプロジェクトは hean_n.cファイルのうち1つを必ずビルドする必要があります。V.9.0.0以降はconfigSUPPORT_DYNAMIC_ALLOCATIONが1もしくは定義されていない時に必要です。ヒープメモリ管理に関してはChapter2で説明します。
1.5 データタイプとコーディングスタイルガイド
データタイプ
各FreeRTOSポートはユニークなportmacro.hを含んでいる。これはポート固有の2つのTickType_t, BaseType_tを定義する。
TickType_t
FreeRTOSはティック割り込みと呼ばれる周期的な割り込みをコンフィグする。
FreeRTOSが開始してから入ったティック割り込みの数を"tick count"呼ぶ。ティックカウントは時間の測定に使われる。
2つのティック割り込みの時間を"tick period"と呼ぶ。時間は2つのtick periodで特定される。
TickType_tはtick countを保持するためのデータタイプである。
TickType_tは configUSE_16_BIT_TICKS(FreeRTOSConfig.h) に依存して、16bit unsgined または 32bit unsginedとなる。
configUSE_16_BIT_TICKS = 1であれば16bit, 0であれば32bitとなる。
16bitは8bit, 16bitアーキテクチャで大きく効率改善することがあるが、特定できる期間がシビアになる。
32bitシステムで16bitを使う理由はない。
BaseType_t
これは、アーキテクチャにとって最も効率の良いデータタイプとなる。
典型的には、32bitアーキテクチャでは32bit, 16bitアーキテクチャでは16bit, 8bitアーキテクチャでは8bitになる。
BaseType_tは変数の上限を取ることができる戻り値として使われたり、pdTRUE, pdFALSE type Booleansとして使われる。
いくつかのコンパイラは符号なしcharをunsigedで、別のコンパイラはsignedで作ることがある。
そのためFreeRTOSではすべてのソースコードに明示的にsigned or unsignedをつけている。ASCIIコードまたは、文字列を指すポインタは例外とする。
ただのintは決して使われない。
変数名
プリフィックス
'c' char
's' int16_t(short)
'l' int32_t(long)
'x' BaseType_t, 他の非標準の型(構造体、タスク、ハンドル、キュー、etc.)
'u' unsgiend
'p' pointer
'uc' uint8_t
'pc' char*
関数名
関数のプリフィックスは戻り値の型となる。例えば、
vTaskPrioritySetはvoidを返す
xQueueRecievedはBaseType_tを返す
pvTimerGetTiemrはvoid*を返す
ファイルスコープであれば
prvがつく(private)
体裁
1tab = 4space
マクロ名
全てのマクロは大文字で書かれる。prefixの小文字はどこのファイルで定義されているかを示す
注意:semaphore APIはほとんどマクロで書かれているが、マクロ名ルールより関数名ルールに従っている
Table4のマクロはFreeRTOSソースコードを通して使われている
行き過ぎたキャストへの根拠
FreeRTOSソースコードは多くの異なるコンパイラ(どのように、いつ、warningを生成するのか異なる)でコンパイルされる。
とりわけ異なるコンパイラがキャストを異なる方法で求めてくる結果としてFreeRTOSソースコードは通常警告が出されるよりも多くのキャストを含んでいる。