migration.txt

page 1

TOPPERS新世代カーネルへのマイグレーションガイド
最終更新: 2010年2月22日（作成中）
このドキュメントは，従来のTOPPERSカーネルや他のμITRON4.0仕様準拠のカーネルから，TOPPERS新世代カーネルに移行するための方法（またはヒント）を説明するものである．
なお，μITRON4.0仕様とTOPPERS新世代カーネル仕様の違いについては，
TOPPERS新世代カーネル統合仕様書の中に【μITRON4.0仕様との関係】として記載してある．必要に応じてそちらも参照すること．
‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑
Migration Guide to TOPPERS New Generation Kernels
Copyright (C) 2005‑2010 by Embedded and Real‑Time Systems Laboratory
Graduate School of Information Science, Nagoya Univ., JAPAN上記著作権者は，以下の (1)〜(3) の条件を満たす場合に限り，本ドキュメント（本ドキュメントを改変したものを含む．以下同じ）を使用・複製・改変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
(1) 本ドキュメントを利用する場合には，上記の著作権表示，この利用条件および下記の無保証規定が，そのままの形でドキュメント中に含まれていること．
(2) 本ドキュメントを改変する場合には，ドキュメントを改変した旨の記述を，改変後のドキュメント中に含めること．ただし，改変後のドキュメントが，TOPPERSプロジェクト指定の開発成果物である場合には，この限りではない．
(3) 本ドキュメントの利用により直接的または間接的に生じるいかなる損害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．また，本ドキュメントのユーザまたはエンドユーザからのいかなる理由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
本ドキュメントは，無保証で提供されているものである．上記著作権者およびTOPPERSプロジェクトは，本ドキュメントに関して，特定の使用目的に対する適合性も含めて，いかなる保証も行わない．また，本ドキュメントの利用により直接的または間接的に生じたいかなる損害に関しても，その責任を負わない．
‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑○目次
・データ型と定数の変更
・オブジェクト属性の変更
・システムコンフィギュレーションファイルの変更
・オブジェクトIDの自動割付けへの対応
・ヘッダファイルの変更
・sta̲tskの置き換え
・set̲timの置き換え
・48ビットのシステム時刻
・周期ハンドラの非互換性
・可変長メモリプールの置き換え○データ型と定数の変更
TOPPERS新世代カーネル仕様では，ITRON仕様の次のデータ型を廃止している．

migration.txt

page 2対応する新しいデータ型を用意しているので，単純に置き換えればよい．
廃止したデータ型
置き換えるデータ型‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑
B
int8̲tUBuint8̲t
VB
uint8̲tH
int16̲tUH
uint16̲t
VH
uint16̲tW
int32̲t
UW
uint32̲t
VW
uint32̲tD
int64̲tUD
uint64̲t
VD
uint64̲t
VP
void *
INT
int̲t
UINT
uint̲tBOOL
bool̲tVP̲INT
intptr̲t
また，定数についても，次の通り置き換える必要がある．
廃止した定数置き換える定数‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑
TRUE
true
FALSE
false
なお，ITRON仕様のデータ型と定数を使いたいアプリケーションのために，ITRON仕様との互換性を保つためのitron.hを用意しているが，使用することは推奨しない．

○オブジェクト属性の変更
TOPPERS新世代カーネル仕様では，次のオブジェクト属性は，デフォルト扱いにして廃止している．
TA̲HLNGTA̲TFIFO
TA̲MFIFO
TA̲WSGL

高級言語用インタフェース
タスクの待ち行列をFIFO順にメッセージキューをFIFO順に待ちタスクは1つのみ

これらのオブジェクト属性を指定している場合には，単純に削除すればよい．
削除したことにより，指定するオブジェクト属性がなくなる場合には，TA̲NULLを指定する．
なお，ITRON仕様のオブジェクト属性を使いたいアプリケーションのために，ITRON仕様との互換性を保つためのitron.hを用意しているが，使用することは推奨しない．

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

migration.txt

page 3

TOPPERS新世代カーネル仕様では，システムコンフィギュレーションファイル中に記述できるディレクティブが，インクルードディレクティブ（#include）と条件ディレクティブ（#if，#ifdefなど）のみとなっている．そのため，システ
ムコンフィギュレーションファイルにマクロ定義ディレクティブ（#define）が含まれている場合には，その記述を削除し，必要であれば，#includeディレク
ティブでインクルードするファイル中に移動する必要がある．
μITRON4.0仕様に準拠して記述されたシステムコンフィギュレーションファイ
ル中の#includeディレクティブは，INCLUDEディレクティブに書き換える必要がある．INCLUDEディレクティブでインクルードするファイルは，システムコンフィギュレーションファイルの一部とみなされるため，上記と同じ制限がある．
逆に，μITRON4.0仕様に準拠して記述されたシステムコンフィギュレーション
ファイル中のINCLUDE静的APIは，#includeディレクティブに書き換える必要がある．

○オブジェクトIDの自動割付けへの対応
TOPPERS新世代カーネルでは，オブジェクトのID番号を自動割付けすることが基本となっている．TOPPERS新世代カーネルを用いる際のID番号の管理方法については，「TOPPERS/ASPカーネル ユーザーズマニュアル」の「11.3 オブジェクトIDの管理」の節に説明があるので，まずはこれを参照すること．
従来，ID番号を手動で割り付けており，手動で割り付けていたID番号を変更したくない場合には，コンフィギュレータの持つID番号の割付けをファイルから取り込む機能（‑‑id‑input‑fileオプション）を用いることで，手動で割り付けたID番号を用いることができる．この場合に，手動で割り付けたID番号は，コンフィギュレータが‑‑id‑input‑fileオプションで取り込むファイル中にのみ記
述し，アプリケーションのソースプログラムからは，kernel̲cfg.hを用いることが望ましい．

○ヘッダファイルの変更
μITRON4.0仕様においては，コンフィギュレータが生成する自動割付け結果ヘッダファイルの名称がkernel̲id.hであったが，TOPPERS新世代カーネル仕様では，kernel̲cfg.hに変更になっている（kernel̲cfg.hの方が含まれる定義が多い）．
kernel̲id.hをインクルードしていたアプリケーションは，kernel̲cfg.hをインクルードするように変更する．
TOPPERS/JSPカーネルで，アプリケーションが用いる標準的なヘッダファイルとして用意していたt̲services.hとs̲services.hは，TOPPERS新世代カーネルでは用意されていない．
t̲services.hをインクルードしていたアプリケーションは，それに代えて，kernel.hをインクルードするように変更する．また，必要に応じて，t̲syslog.h，t̲stdlib.h，syssvc/syslog.h，syssvc/serial.hをインクルードする．ただし，t̲services.hに含まれているsyscallマクロと̲syscallマクロは，アプリケーションによって適切なエラー処理方法は異なることから，TOPPERS新世代カーネルでは用意されていない．使用する場合には，アプリケーションで用意する必要がある．
s̲services.hをインクルードしていたアプリケーションは，それに代えて，sil.hをインクルードするように変更する．また，必要に応じて，t̲syslog.hとターゲットのハードウェア資源の定義を含むヘッダファイルをインクルードする．

migration.txt

page 4○sta̲tskの置き換え
TOPPERS新世代カーネルでは，タスクを起動するサービスコールとしてact̲tskをサポートしており，sta̲tskをサポートしていない．act̲tskとsta̲tskの機能を比較した場合，前者はタスク起動のキューイング機能を持つのに対して，後者はタスクに起動コードを渡す機能を持つ．そのため，sta̲tskをact̲tskに置き換える場合に，起動コードを渡す機能をどのように実現するかが問題となる．
起動コードを渡す機能を最も簡単に代用する方法は，起動コードを渡すためのデータキューを用意する方法である．タスクを起動する処理単位は，データキューに起動コードを送信した後，act̲tskによりタスクを起動する．起動されたタスクは，データキューから起動コードを受信する．
タスク起動のキューイングが起こらないことが保証できる，言い換えると，タスクを起動する時には，対象タスクは休止状態にあることが保証できる場合には，起動コードをグローバル変数に置いて渡す方法もある．タスクを起動する
処理単位がそのグローバル変数に書くのは，タスクが休止状態の間に限られ，起動されたタスクがそのグローバル変数を読むのは，タスクが実行できる状態の間に限られるため，グローバル変数に対する排他制御は必要ない．

○set̲timの置き換え
TOPPERS新世代カーネルでは，システム時刻を設定するサービスコールである
set̲timが使用されることは稀であると考え，サポートしないこととした．
ITRON仕様と互換のset̲timとget̲timが必要な場合には，下に示すコードのitron̲set̲timとitron̲get̲timで代用することができる（下のコードでは，エラー処理は省略している）．
‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑
static SYSTIM
systim̲offset = 0U;
voiditron̲set̲tim(const SYSTIM *p̲systim){
SYSTIM current̲time;
get̲tim(&current̲time);
systim̲offset = *p̲systim ‑ current̲time;}void
itron̲get̲tim(SYSTIM *p̲systim){
SYSTIM current̲time;
get̲tim(&current̲time);*p̲systim = systim̲offset + current̲time;}‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑○48ビットのシステム時刻
ITRON仕様準拠のカーネルでは，μITRON3.0仕様でシステム時刻を48ビットとすmigration.txt

page 5ることを推奨していたため（μITRON4.0仕様では推奨を定めていない），シス
テム時刻が48ビットとなっているものがある．
int型，long型ともに32ビットの環境で，システム時刻を48ビットに拡張するには，カーネルを改造する方法も考えられるが，get̲timのみが必要な場合には，周期ハンドラを使って上位桁を求めておく方法がある．
具体的には，まず，上位桁を求める周期ハンドラを登録するために，システムコンフィギュレーションファイルに次の記述を含める．
‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑
CRE̲CYC(CYCHDR̲SYSTIM48, { TA̲STA, 0, cychdr̲systim48, 1 << 30, 1 << 30 });‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑
周期ハンドラ本体およびそれを用いた48ビット版のget̲timは，次のように実現することができる．
‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑
typedef {uint̲16utime;/* システム時刻の上位16ビット */uint̲32ltime;/* システム時刻の下位32ビット */} SYSTIM48;
static SYSTIM

systim̲upper = 0U;

void
cychdr̲systim48(intptr̲t exinf){
systim̲upper += 1;}
voiditron̲get̲tim48(SYSTIM48 *p̲systim48){SYSTIM systim;get̲tim(&systim);if (((systim >> 30) & 0x3U) == (systim̲upper & 0x3U) {p̲systim48‑>utime = (uint̲16)(systim̲upper >> 2);}else {
p̲systim48‑>utime = (uint̲16)((systim̲upper >> 2) + 1);}p̲systim48‑>ltime = (uint̲32) systim;}‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑
int型が16ビットの環境では，周期ハンドラの周期として(1 << 30)を使用することができないため，周期ハンドラの登録と周期ハンドラ本体を，次のように修正する必要がある．
‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑
CRE̲CYC(CYCHDR̲SYSTIM48, { TA̲STA, 0, cychdr̲systim48, 1 << 15, 1 << 15 });‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑
static SYSTIM
systim̲upper = 0U;
static SYSTIM
systim̲medium = 0U;
voidmigration.txt

page 6cychdr̲systim48(intptr̲t exinf){
systim̲medium += 1;
if (systim̲medium == 0U) {systim̲upper += 1;}}‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑○周期ハンドラの非互換性
TA̲PHS属性でない周期ハンドラにおいて，sta̲cycを呼び出した後，最初に周期ハンドラが起動される時刻が，μITRON4.0仕様では，sta̲cycを呼び出してから周期ハンドラの起動周期（cyctim）で指定した相対時間後となっていたが，TOPPERS新世代カーネルでは，起動位相（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で動作を制御するのをもう片方の周期ハンドラとする．

○可変長メモリプールの置き換え
アプリケーションが動的メモリ管理を用いる場合に，malloc/freeの実現に可変長メモリプールが用いられることがあり，可変長メモリプールがサポートされていないことが問題となる場合がある．TOPPERS新世代カーネル仕様で可変長メモリプールをサポートしないこととしたのは，動的メモリ管理をカーネル内で実現するより，ライブラリとして実現する方が適切と考えたためである．
そこで，ここでは，アプリケーションが用いるmalloc/freeを，オープンソースのメモリ割付けライブラリであるTLSFを用いて実現する方法について述べる．
TLSFは，リアルタイムシステム向けの効率的なメモリ割付けライブラリである．
TLSFのライセンス条件は，GPLとLGPLのデュアルライセンスであるが，TLSFを通常のライブラリとして用いて実装されたプログラムは，TLSFの派生物とは見なされず，GPLが適用されないことが明記されている．
TLSFは，以下のウェブサイトからダウンロードすることができる．
http://rtportal.upv.es/rtmalloc/
TLSF（動作確認は，Version 2.4.6）のアーカイブの中から，tlsf.hとtlsf.cを，アプリケーションまたはライブラリのソースファイルの置かれたディレクトリにコピーする．

migration.txt

page 7

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̲SEM)! #define TLSF̲DESTROY̲LOCK(lock) ini̲sem(*lock)! #define TLSF̲ACQUIRE̲LOCK(lock) wai̲sem(*lock)! #define TLSF̲RELEASE̲LOCK(lock) sig̲sem(*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を用いるように変更する．
・タスク間の排他を，セマフォを用いて行う．

migration.txt

page 8malloc/freeを複数のタスクから呼び出す場合には，tslf.cを‑DTLSF̲USE̲LOCKS
オプションをつけてコンパイルし，システムコンフィギュレーションファイルに次の記述を追加する．
‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑
CRE̲SEM(TLSF̲SEM, { TA̲TPRI, 1, 1 });‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑
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を参照すること．
以上