
		TOPPERS/FMP3カーネル
		TOPPERS/FMP3カーネルへのマイグレーションガイド

		対応バージョン: Release 3.1
		最終更新: 2019年3月19日

このドキュメントは，TOPPERS/FMPカーネル Release 1.X（以下，FMPカーネル）
や他のμITRON4.0仕様準拠のカーネル上のアプリケーションを，TOPPERS/FMP3
カーネル（TOPPERS/FMPカーネルRelease 3.X．以下，FMP3カーネル）にポーテ
ィングするための方法（またはヒント）を説明するものである．

----------------------------------------------------------------------
 TOPPERS/FMP Kernel
     Toyohashi Open Platform for Embedded Real-Time Systems/
     Flexible MultiProcessor Kernel

 Copyright (C) 2005-2019 by Embedded and Real-Time Systems Laboratory
             Graduate School of Information Science, Nagoya Univ., JAPAN
 
 上記著作権者は，以下の(1)〜(4)の条件を満たす場合に限り，本ソフトウェ
 ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
 変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
 (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
     権表示，この利用条件および下記の無保証規定が，そのままの形でソー
     スコード中に含まれていること．
 (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
     用できる形で再配布する場合には，再配布に伴うドキュメント（利用
     者マニュアルなど）に，上記の著作権表示，この利用条件および下記
     の無保証規定を掲載すること．
 (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
     用できない形で再配布する場合には，次のいずれかの条件を満たすこ
     と．
   (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
       作権表示，この利用条件および下記の無保証規定を掲載すること．
   (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
       報告すること．
 (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
     害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
     また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
     由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
     免責すること．
 
 本ソフトウェアは，無保証で提供されているものである．上記著作権者お
 よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
 に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
 アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
 の責任を負わない．
 
 $Id: migration.txt 178 2019-10-08 13:55:00Z ertl-honda $
----------------------------------------------------------------------

○目次

・関連ドキュメント
・FMP1カーネルとのアプリケーションの構築環境の違い
	- 構築手順
	- システムコンフィギュレーションファイルに含めるべき内容
	- コンフィギュレーションスクリプトの仕様の違い
	- コンフィギュレータの仕様の違い
・FMP1カーネルとのカーネル仕様の違い
	- 時間の単位
	- 周期ハンドラとアラームハンドラ
	- タスク例外処理
	- メールボックス
	- その他の違い
・μITRON4.0仕様からの移行
	- データ型と定数の変更
	- オブジェクト属性の変更
	- システムコンフィギュレーションファイルの変更
	- オブジェクトIDの自動割付けへの対応
	- ヘッダファイルの変更
	- sta_tskの置き換え
	- 周期ハンドラの非互換性


○関連ドキュメント

FMP3カーネルの仕様の概要を説明したドキュメントとして，「TOPPERS/FMP3カ
ーネルの仕様概要」がある．このドキュメントでは，FMP3カーネルの仕様を，
ASP3カーネルからの変更箇所がわかるように説明している．

FMP3カーネルの詳細な仕様については，「TOPPERS第3世代カーネル（ITRON系）
統合仕様書」で規定している．この仕様書でも，μITRON4.0仕様（JSPカーネル
はこの仕様に準拠）およびTOPPERS新世代カーネル統合仕様（ASP1カーネルはこ
の仕様に準拠）との違いを記載している．


○FMP1カーネルとのアプリケーションの構築環境の違い

この章では，FMP3カーネルの標準のアプリケーションの構築環境が，FMP1カー
ネルからどのように変更されたかについて説明する．

●構築手順

FMP1カーネルのコンフィギュレーションスクリプト（configure）は，デフォル
トではサンプルプログラムをカレントディレクトリにコピーしていたが，FMP3
カーネルではコピーを行わず，サンプルプログラムのディレクトリにあるファ
イルを直接参照する．

FMP1カーネルの標準の構築手順では，「make depend」により依存関係ファイル
を作成してから，「make」によりロードモジュールを生成していたが，FMP3カー
ネルでは依存関係ファイルを自動的に作成するため，「make depend」を実行す
る必要はない．

●システムコンフィギュレーションファイルに含めるべき内容

FMP3カーネルでは，カーネルが必要とするコンフィギュレーション記述を，ア
プリケーションのシステムコンフィギュレーションファイルとは別のファイル
に用意し，標準のMakefileでは，コンフィギュレータのパス1にそれを読み込ま
せている．そのため，FMP1カーネルではシステムコンフィギュレーションファ
イルに記述しなければならなかった以下の行は，FMP3カーネルでは削除しなけ
ればならない．

----------------------------------------
INCLUDE("target_timer.cfg");
----------------------------------------

●コンフィギュレーションスクリプトの仕様の違い

FMP3カーネルのコンフィギュレーションスクリプト（configure.rb）は，FMP1
のもののほぼ上位互換となっているが，以下のオプションが廃止されたため，
使用している場合には変更が必要である．

・テンプレートディレクトリの指定（-t）
	テンプレートディレクトリは，テンプレートMakefileのコピー元としてし
	か使われないため，テンプレートMakefile名の指定（-m）で代用できる．

・実行環境の名称（-d）
	実行環境の名称の指定が必要な場合は，コンパイル時のシンボルの定義に
	よって対応することとしたため，共通シンボル定義オプション（-O）で対
	応する．

・perlのパス名（-p）
	FMP3カーネルではperlを使用していないため廃止した．

なお，FMP3カーネルのコンフィギュレーションスクリプトでは，-tと-dは別の
意味のオプションとなっているため，注意すること．

●コンフィギュレータの仕様の違い

FMP3カーネルのコンフィギュレータ（Ruby版コンフィギュレータ）は，ユーザ
から見た場合にはFMP1のものとほぼ互換になっているが，以下のオプションが
廃止または変更されたため，使用している場合には変更が必要である．

・インクルードディレクトリ名（--include-path）
	オプション名を--include-directoryに変更した．短縮形（-I）を用いてい
	る場合には，影響はない．

・値取得シンボルテーブルファイル名（--cfg1-def-table）
	オプション名を--symval-tableに変更した．また，値取得シンボルテーブ
	ルのフォーマットが変更になっている．

・ロードモジュールのシンボルファイル名（--symbol-table）
	オプション名を--rom-symbolに変更した．

・オブジェクトID番号を保持する変数の生成（--external-id）
	コンパイルオプションに-DUSE_EXTERNAL_IDを指定することで同じ機能を実
	現するようにしたため，このオプションは廃止した．

・パス1の生成ファイル名（--cfg1_out）
	このオプションは廃止した．現時点では，同等の機能は持っていない．こ
	の機能が必要なユースケースが出てきた場合には，コンフィギュレータを
	拡張する（拡張は容易である）．

・コンフィギュレータが置かれているディレクトリ名（--cfg-directory）
	このオプションは不要となったため，廃止した．

・メッセージカタログが置かれているディレクトリ名（--msgcat-directory）
	Ruby版コンフィギュレータでは，メッセージカタログの機能をサポートし
	ていないため，このオプションは廃止した．

他にも廃止されたオプションがあるが，ほとんど使われていないと思われるた
め，ここには記載していない．


○FMP1カーネルとのカーネル仕様の違い

この章では，FMP1カーネル向けに記述されたアプリケーションを，FMP3カーネ
ル上で動作させるために，修正が必要となる主な点について説明する．

●時間の単位

FMP3カーネルでは，システム時刻（SYSTIM型），相対時間（RELTIM型），タイ
ムアウト時間（TMO型）の時間単位を，ミリ秒からマイクロ秒に変更した．その
ため，これらの時間を記述している定数値を，1000倍した値に書き換えること
が必要である．

●周期ハンドラとアラームハンドラ

FMP3カーネルでは，周期ハンドラ機能とアラームハンドラ機能を拡張し，周期
通知機能とアラーム通知機能を実装している．従来の周期／アラームハンドラ
と同等の機能は，タイムイベントハンドラの呼出しによる通知で実現できる．
具体的には，静的APIを以下の例のように書き換えることが必要である．

　＊書き換え前
	CRE_CYC(CYCHDR1, { TA_NULL, 0, cyclic_handler, 2000, 0 });
	CRE_ALM(ALMHDR1, { TA_NULL, 0, alarm_handler });

　＊書き換え後
	CRE_CYC(CYCHDR1, { TA_NULL, { TNFY_HANDLER, 0, cyclic_handler },
														2000000, 0 });
	CRE_ALM(ALMHDR1, { TA_NULL, { TNFY_HANDLER, 0, alarm_handler }});

●タスク例外処理

FMP3カーネルでは，タスク例外処理機能を廃止した．タスク例外処理機能を使
用していた場合には，他の機能を用いて書き換えることが必要である．例えば，
タスク例外処理で実現していた処理は，独立したタスクで実現する方法が有力
である．また，タスク例外処理ルーチンの中でタスクを終了させている場合に
は，タスク終了要求機能を用いて書き換えられる可能性がある．

●メールボックス

FMP3カーネルでは，メールボックスの機能を廃止した．同等の機能は，データ
キューまたは優先度データキューで実現できるため，これらを用いるように修
正する必要がある．

●ローカルタイマ方式とグローバルタイマ方式

FMP1カーネルでは，プロセッサ毎にシステム時刻を持つローカルタイマ方式と，
システム全体で1つのシステム時刻を持つグローバルタイマ方式のどちらかを
用いることとしていたが，FMP3カーネルでは，システム全体で1つのシステム
時刻を持つ．ただし，タイムイベント処理プロセッサを複数設けられることか
ら，FMP1カーネルのグローバルタイマ方式とも異なる．

FMP3カーネルでは，タイムイベントの処理は，ターゲット定義の1つまたは複
数のプロセッサで行う．タイムイベントを処理するプロセッサを，タイムイベ
ント処理プロセッサと呼ぶ．

●タイムマスタプロセッサ

FMP3カーネルでは，システム中の1個のプロセッサをタイムマスタプロセッサ
とする．タイムマスタプロセッサでは，システム時刻の管理と，非タイムイベ
ント処理プロセッサで時間待ちとなったタスクの待ち時間管理を行う．

●その他の違い

その他に，以下の修正が必要になる．

・FMP3カーネルでは，静的API ATT_ISRを廃止した．静的API CRE_ISRを用いた
　記述に修正する必要がある．

・FMP3カーネルでは，性能評価用のサービスコール get_utmを廃止した．性能
　評価目的であれば，高分解能タイマを参照するサービスコール fch_hrtを用
　いて代替できる．

・SIZE型をsize_t型に変更する．

・FMP3カーネルでは，待ち状態に入るすべてのサービスコールから，E_RASTER
　が返る可能性がある．このエラーが返った場合の対策が必要である．


○μITRON4.0仕様からの移行

この章では，JSPカーネルや他のμITRON4.0仕様準拠のカーネルから，FMP3カー
ネルに移行するための方法（またはヒント）を説明する．

●データ型と定数の変更

FMP3カーネルでは，μITRON4.0仕様の次のデータ型を廃止している．対応する
新しいデータ型を用意しているので，単純に置き換えればよい．

	廃止したデータ型		置き換えるデータ型
	------------------------------------------
	B						int8_t
	UB						uint8_t
	VB						uint8_t
	H						int16_t
	UH						uint16_t
	VH						uint16_t
	W						int32_t
	UW						uint32_t
	VW						uint32_t
	D						int64_t
	UD						uint64_t
	VD						uint64_t
	VP						void *
	INT						int_t
	UINT					uint_t
	BOOL					bool_t
	SIZE					size_t
	VP_INT					intptr_t

また，定数についても，次の通り置き換える必要がある．

	廃止した定数			置き換える定数
	------------------------------------------
	TRUE					true
	FALSE					false

なお，μITRON4.0仕様のデータ型と定数を使いたいアプリケーションのために，
μITRON4.0仕様との互換性を保つためのitron.hを用意しているが，使用するこ
とは推奨しない．

●オブジェクト属性の変更

FMP3カーネルでは，次のオブジェクト属性は，デフォルト扱いにして廃止して
いる．

	TA_HLNG					高級言語用インタフェース
	TA_TFIFO				タスクの待ち行列をFIFO順に
	TA_WSGL					待ちタスクは1つのみ

これらのオブジェクト属性を指定している場合には，単純に削除すればよい．
削除したことにより，指定するオブジェクト属性がなくなる場合には，
TA_NULLを指定する．

なお，μITRON4.0仕様のオブジェクト属性を使いたいアプリケーションのため
に，μITRON4.0仕様との互換性を保つためのitron.hを用意しているが，使用す
ることは推奨しない．

●システムコンフィギュレーションファイルの変更

FMP3カーネルでは，システムコンフィギュレーションファイルにおけるC言語プ
リプロセッサのディレクティブの扱いが変更になっているため，システムコン
フィギュレーションファイルの変更が必要になる．

FMP3カーネルでは，システムコンフィギュレーションファイル中に記述できる
ディレクティブが，インクルードディレクティブ（#include）と条件ディレク
ティブ（#if，#ifdefなど）のみとなっている．そのため，システムコンフィギュ
レーションファイルにマクロ定義ディレクティブ（#define）が含まれている場
合には，その記述を削除し，必要であれば，#includeディレクティブでインク
ルードするファイル中に移動する必要がある．

μITRON4.0仕様に準拠して記述されたシステムコンフィギュレーションファイ
ル中の#includeディレクティブは，INCLUDEディレクティブに書き換える必要が
ある．INCLUDEディレクティブでインクルードするファイルは，システムコンフィ
ギュレーションファイルの一部とみなされるため，上記と同じ制限がある．

逆に，μITRON4.0仕様に準拠して記述されたシステムコンフィギュレーション
ファイル中のINCLUDE静的APIは，#includeディレクティブに書き換える必要が
ある．

●オブジェクトIDの自動割付けへの対応

FMP3カーネルでは，オブジェクトのID番号を自動割付けすることが基本となっ
ている．FMP3カーネルを用いる際のID番号の管理方法については，「TOPPERS/
FMP3カーネル ユーザーズマニュアル」の「11.4 オブジェクトIDの管理」の節
に説明があるので，まずはこれを参照すること．

従来，ID番号を手動で割り付けており，手動で割り付けていたID番号を変更し
たくない場合には，コンフィギュレータの持つID番号の割付けをファイルから
取り込む機能（--id-input-fileオプション）を用いることで，手動で割り付け
たID番号を用いることができる．この場合に，手動で割り付けたID番号は，コ
ンフィギュレータが--id-input-fileオプションで取り込むファイル中にのみ記
述し，アプリケーションのソースプログラムからは，kernel_cfg.hを用いるこ
とが望ましい．

●ヘッダファイルの変更

μITRON4.0仕様においては，コンフィギュレータが生成する自動割付け結果ヘッ
ダファイルの名称がkernel_id.hであったが，FMP3カーネルでは，
kernel_cfg.hに変更になっている（kernel_cfg.hの方が含まれる定義が多い）．
kernel_id.hをインクルードしていたアプリケーションは，kernel_cfg.hをイン
クルードするように変更する．

●sta_tskの置き換え

FMP3カーネルでは，タスクを起動するサービスコールとしてact_tskをサポート
しており，sta_tskをサポートしていない．act_tskとsta_tskの機能を比較した
場合，前者はタスク起動のキューイング機能を持つのに対して，後者はタスク
に起動コードを渡す機能を持つ．そのため，sta_tskをact_tskに置き換える場
合に，起動コードを渡す機能をどのように実現するかが問題となる．

起動コードを渡す機能を最も簡単に代用する方法は，起動コードを渡すための
データキューを用意する方法である．タスクを起動する処理単位は，データ
キューに起動コードを送信した後，act_tskによりタスクを起動する．起動され
たタスクは，データキューから起動コードを受信する．

タスク起動のキューイングが起こらないことが保証できる，言い換えると，タ
スクを起動する時には，対象タスクは休止状態にあることが保証できる場合に
は，起動コードをグローバル変数に置いて渡す方法もある．タスクを起動する
処理単位がそのグローバル変数に書くのは，タスクが休止状態の間に限られ，
起動されたタスクがそのグローバル変数を読むのは，タスクが実行できる状態
の間に限られるため，グローバル変数に対する排他制御は必要ない．

●周期ハンドラの非互換性

TA_PHS属性でない周期ハンドラにおいて，sta_cycを呼び出した後，最初に周期
ハンドラが起動される時刻が，μITRON4.0仕様では，sta_cycを呼び出してから
周期ハンドラの起動周期（cyctim）で指定した相対時間後となっていたが，
FMP3カーネルでは，起動位相（cycphs）で指定した相対時間後となっている．

CRE_CYCにおいて，TA_STA属性を指定しない場合には，cycphsにcyctimと同じ値
を指定することで，μITRON4.0仕様と同じ振舞いとなる（μITRON4.0仕様では，
TA_STA属性とTA_PHS属性のいずれも指定しない場合には，cycphsは意味を持た
ない）．

TA_STA属性を指定する場合には，カーネルの起動後，最初に周期ハンドラが起
動されるまでの相対時間と，sta_cycを呼び出してから最初に周期ハンドラが起
動されるまでの相対時間が同一でよければ，その時間をcycphsに指定すればよ
い．両者が同一では不都合な場合には，μITRON4.0仕様と同じ振舞いをさせる
ことはできない．代替手段としては，以下の2つが考えられる．

(1) TA_STA属性を使用せず，カーネルの起動後適切なタイミングでsta_cycを呼
び出すことで，周期ハンドラを動作開始する．

(2) 周期ハンドラを2つ用いる．1つをTA_STA属性とし，sta_cycで動作を制御す
るのをもう片方の周期ハンドラとする．

●動的メモリ管理の実現

FMP3カーネルでは，動的メモリ管理は，カーネル内で実現するよりライブラリ
として実現する方が適切と考え，可変長メモリプールをサポートしていない．
しかし，アプリケーションが動的メモリ管理（malloc／free）を用いる場合に，
その実現に可変長メモリプールが用いられることがあり，可変長メモリプール
がサポートされていないことが問題となる場合がある．

そこで，ここでは，アプリケーションが用いるmalloc／freeを，オープンソー
スのメモリ割付けライブラリであるTLSFを用いて実現する方法について述べる．

TLSFは，リアルタイムシステム向けの効率的なメモリ割付けライブラリである．
TLSFのライセンス条件は，GPLとLGPLのデュアルライセンスであるが，TLSFを通
常のライブラリとして用いて実装されたプログラムは，TLSFの派生物とは見な
されず，GPLが適用されないことが明記されている．

TLSFは，以下のウェブサイトからダウンロードすることができる．

	http://www.gii.upv.es/tlsf/

TLSF（動作確認は，Version 2.4.6）のアーカイブの中から，tlsf.hとtlsf.cを，
アプリケーションまたはライブラリのソースファイルの置かれたディレクトリ
にコピーする．

tlsf.hは動的メモリ管理を用いるアプリケーションからインクルードすべきヘッ
ダファイル，tlsf.cは動的メモリ管理ライブラリの本体である．tlsf.cには以
下のようなパッチをあてる．

----------------------------------------
*** tlsf.c.orig	Wed Sep 16 16:40:39 2009
--- tlsf.c	Wed Sep 16 16:45:10 2009
***************
*** 76,82 ****
  
  
  #if TLSF_USE_LOCKS
! #include "target.h"
  #else
  #define TLSF_CREATE_LOCK(_unused_)   do{}while(0)
  #define TLSF_DESTROY_LOCK(_unused_)  do{}while(0) 
--- 76,88 ----
  
  
  #if TLSF_USE_LOCKS
! #include "kernel.h"
! #include "kernel_cfg.h"
! #define TLSF_MLOCK_T ID
! #define TLSF_CREATE_LOCK(lock)   (*lock = TLSF_MTX)
! #define TLSF_DESTROY_LOCK(lock)  ini_mtx(*lock)
! #define TLSF_ACQUIRE_LOCK(lock)  loc_mtx(*lock)
! #define TLSF_RELEASE_LOCK(lock)  unl_mtx(*lock)
  #else
  #define TLSF_CREATE_LOCK(_unused_)   do{}while(0)
  #define TLSF_DESTROY_LOCK(_unused_)  do{}while(0) 
***************
*** 169,176 ****
  
  #ifdef USE_PRINTF
  #include <stdio.h>
! # define PRINT_MSG(fmt, args...) printf(fmt, ## args)
! # define ERROR_MSG(fmt, args...) printf(fmt, ## args)
  #else
  # if !defined(PRINT_MSG)
  #  define PRINT_MSG(fmt, args...)
--- 175,184 ----
  
  #ifdef USE_PRINTF
  #include <stdio.h>
! #include <t_stddef.h>
! #include <t_syslog.h>
! # define PRINT_MSG(fmt, args...) syslog(LOG_ERROR, fmt, ## args)
! # define ERROR_MSG(fmt, args...) syslog(LOG_ERROR, fmt, ## args)
  #else
  # if !defined(PRINT_MSG)
  #  define PRINT_MSG(fmt, args...)
----------------------------------------
  
このパッチは，tlsf.cに以下の修正を加えている．

・PRINT_MSGおよびERROR_MSGを，syslogを用いるように変更する．
・タスク間の排他を，ミューテックスを用いて行う．

malloc／freeを複数のタスクから呼び出す場合には，コンパイルオプションに
-DTLSF_USE_LOCKSを追加し，システムコンフィギュレーションファイルに次の
ような記述を追加する（ミューテックスの属性は変更してもよい）．

----------------------------------------
CRE_MTX(TLSF_MTX, { TA_TPRI, 0 });
----------------------------------------

TLSFを使用するプログラムでは，メモリプールの領域を配列として確保する
（下の例は，メモリプールのために10KBの領域を確保している）．

----------------------------------------
#define MEMORY_POOL_SIZE	(TOPPERS_ROUND_SZ(10*1024, sizeof(intptr_t))
							/* 10*1024の部分は，適切なサイズに変更する */
intptr_t memory_pool[MEMORY_POOL_SIZE / sizeof(intptr_t)];
----------------------------------------

次にメモリプールの初期化を行う．

----------------------------------------
	init_memory_pool(MEMORY_POOL_SIZE, memory_pool);
----------------------------------------

以上により，tlsf_malloc／tlsf_freeで，malloc／freeが実現できる．

なお，TLSFは，複数のメモリプールを用いる機能や，メモリプールのサイズを
拡張する機能を持つ．詳しくは，TLSFのアーカイブ中のREADMEを参照すること．

以上
