ルネサス統合開発環境上でTOPPERSカーネルを使ってみよう！

（１） TOPPERS/ASPカーネルのHigh-performance Embedded Workshop
対応についてTOPPERSプロジェクト
宮城県産業技術総合センター

今井和彦
2008/11/20©TOPPERSプロジェクト

1

はじめに
• TOPPERS/ASPカーネル– 最新バージョンはGNUツールチェーンを用いて開発• 本発表：他の処理系に移植する際の勘所をご紹介– 移植元：GNUツールチェーン– 移植先：ルネサス High-performance Embedded Workshop（以下、HEWと表記）• 処理系がネックになって、TOPPERSカーネルの採用を見送っていた方は、これを機会にぜひご検討下さい。

2008/11/20©TOPPERSプロジェクト

2

ASPカーネルでサポートしているGNU以外の処理系
・SH2A
・HEW

←今回、ご紹介する例

・M32C
・HEW

・M16C
・HEW
・TM

2008/11/20©TOPPERSプロジェクト3処理系の内訳
GNU開発環境ルネサス開発環境

Cコンパイラ

gcc

shc

アセンブラ

gasasmshリンカ

GNU ldoptlnk全体のビルド管理

GNU makeHEW

2008/11/20©TOPPERSプロジェクト

4移植の際のチェックポイント
１．「処理系の拡張機能（or 方言）」に起因する事項(a) Cコンパイラ• intサイズ• コーリング・コンベンション• インライン・アセンブラ• 最適化問題(b) アセンブラ• プリプロセスの表記方法(c) リンカ

２．「ビルド全体の監理方法」に起因する事項– システム・コンフィギュレーション• プロジェクトの分割• 外部ツールとの連携
2008/11/20©TOPPERSプロジェクト

5

作業内容

時間の都合上、今回は（※）の項目のみ解説します。

・intサイズに関連する定義
・コントロール・レジスタへのアクセス・システム・コンフィギュレーション（※）
・プロジェクト分割
・外部ツールとの連携
・割込みの出入口処理

・オフセットファイルの生成
・アセンブラ・ルーチンからC言語構造体にアクセス

・クリティカル・セクション（※）
・最適化問題・非依存部のインライン関数
・アセンブラ用のインクルードファイル（※）
2008/11/20©TOPPERSプロジェクト6

システム・コンフィギュレーションとは？
（カーネルやシステムサービスが管理する）オブジェクト（例：タスク）のシステム・コンフィギュレーション
ファイル– 生成情報– 初期状態からC言語プリプロセッサ

カーネル（or システムサービス）の– 構成情報
– 初期化情報を含むファイルを生成する作業

ASPカーネルでは、
μITRON4.0仕様からコンフィギュレータの処理モデルを大幅に変更
2008/11/20

カーネルのコンフィギュレータ

カーネル資源の（例：タスク、セマフォ）
・初期化ファイル
・ID自動割り付け定義ファイル©TOPPERSプロジェクト

7

機種依存で生成すべき内容
アプリケーション依存の情報はカーネル内で決め打ちにできない。
・使用する割込み番号
・割込みハンドラ／割込みサービスルーチン（の先頭番地）
・割込みライン属性
・割込み優先度・トリガ方式：エッジトリガ／レベルトリガ

TOPPERS標準
割込み処理モデル
導入前（カーネル）
ターゲット
依存部

2008/11/20

導入後→コンフィギュレーション時にパラメータの値を評価する必要がある。

割込みアーキテクチャ依存©TOPPERSプロジェクト

アプリケーション依存

8

システム・コンフィギュレーションの手順（静的APIの）パラメータの評価結果は処理系に依存（コンパイラ、リンカ）→途中で処理系を呼び出す必要があり、若干、複雑

2008/11/20©TOPPERSプロジェクト

9システム・コンフィギュレーション（２）・パス１– Cコンパイラを用いて、静的APIの整数定数式パラメータの値を決定する。
・オブジェクト番号／属性／サイズ／数
・機能コード・優先度– コンパイル後でないと決定できない値もある（sizeof演算子の評価結果など）– アドレス配置には依存しない。

・パス２
上記の結果を用いて、カーネルの構成・初期化ファイルkernel_cfg.c, kernel_cfg.hを生成→この段階でアプリケーションを含むシステム全体のビルドに必要なソースファイルがそろう。

・パス３– 最終的な実行ファイルに対して、静的APIの一般定数式パラメータの妥当性をチェックする。
・アドレスを指定する可能性のあるパラメータ→リンク後でないと値が決まらない。
・処理単位のエントリ番地
・メモリ領域の先頭番地
・拡張情報など
2008/11/20©TOPPERSプロジェクト10システム・コンフィギュレーションに関連して必要な修正（１） プロジェクト分割– カスタム・フェーズ（２） 外部ツールとの連携（３） 割込みの出入口処理– インライン・アセンブラとシンボル参照

2008/11/20©TOPPERSプロジェクト11

システム・コンフィギュレーションに関連して必要な修正（１）

プロジェクト１
ファイルを生成する箇所でプロジェクト
分割・プロジェクト分割– HEWでは、プロジェクトのビルドに先立 プロジェクト２
ち、（インクルードファイルを含む）ソースファイルがすべてそろっているかチェックする。
（ソースファイルがそろっていなければ、即ビルドエラー）– HEWでは、カスタムフェーズでソースファイルを自動生成 プロジェクト３する処理は、別プロジェクトとして分割する必要がある。

2008/11/20©TOPPERSプロジェクト

12

システム・コンフィギュレーションに関連して必要な修正（２）−１
・外部ツールとの連携
・コンフィギュレータ本体
・シンボルテーブルの変換shc_map_nm.exe
パス２でシンボルテーブルをGNU nmコマンド互換の形式に変換する。

・相対パス問題ワークスペース・ディレクトリ以下にない外部ツールを相対パスで指定できない。
→絶対パスでは、他のディレクトリ／パソコンに移すとビルドが通らない。

解決策：
ワークスペース配下にバッチファイル(xxx.bat）を用意し、このバッチファイルから外部ツールを呼び出す。

統合環境
2008/11/20

バッチファイル
xxx.bat
呼び出し©TOPPERSプロジェクト

呼び出し

外部ツール
cfg.exe
13

システム・コンフィギュレーションに関連して必要な修正（２）−２
エラー検出問題
外部ツール（コンフィギュレータ）でエラーが発生しても、HEWでそれを認識できない場合がある。（素通りして、後のビルドフェーズでエラーが顕在化）

解決策：
外部ツールでエラーが発生したら、前述のバッチファイルにより１．ユーザーにビルドを手動で停止させるようメッセージを表示
２．ビルドが先に進まないように、バッチファイル内で無限ループ
HEWのアウトプット
ウィンドウでの表示例

2008/11/20©TOPPERSプロジェクト14システム・コンフィギュレーションに関連して必要な修正（３）−１
カーネルの初期化・構成ファイルkernel_cfg.cのターゲット依存部
１．割込みの出入口処理
グローバルシンボルの参照が必要
・ユーザー定義の割込み処理ルーチン
・カーネル内での割込みの共通処理への分岐
割込み要因に拠らない部分

２．ベクタテーブル
出入口処理をラベルとして参照しているので、同様シンボルのエクスポート（別ファイルの場合）

ベクタテーブル

割込みの出入口処理•割込み処理ルーチン（ユーザー定義）

シンボル参照•カーネル内での割込みの共通処理
外部シンボル参照

2008/11/20©TOPPERSプロジェクト15システム・コンフィギュレーションに関連して必要な修正（３）−２ （タイマ割込みの例）
GNU開発環境版（kernel_cfg.c）asm(".text¥n".section .vector_entry,¥"xa¥""¥n"" .global __kernel_target_timer_handler_140¥n"" .align 2¥n""__kernel_target_timer_handler_140:
¥n"
（中略）
"

シンボルのエクスポート

ルネサス開発環境版（kernel_cfg_asm.src）.SECTION vector_entry, CODE, ALIGN=4.IMPORT _target_timer_handler.GLOBAL __kernel_target_timer_handler_140__kernel_target_timer_handler_140:（中略）; C言語ルーチンの先頭アドレス_c_routine_target_timer_handler_140:.DATA.L _target_timer_handler; prc_support.src内の分岐先アドレス_common_routine_target_timer_handler_140:.DATA.L __kernel_int_entry_inhno_target_timer_handler_140:; 割込み番号.DATA.L 140.align 2¥n"/* 割込み禁止用マスク */"_mask_ipm_target_timer_handler_140:¥n"/* ipm以外のビットはゼロで良い */".long __kernel_asm_mask_ipm¥n""_c_routine_target_timer_handler_140:¥n"/* C言語ルーチンの先頭アドレス */".long _target_timer_handler¥n"/* cpu_support.S内の分岐先アドレス */"_common_routine_target_timer_handler_140: n"".long __kernel_int_entry ¥n"/* 割込み番号*/"_inhno_target_timer_handler_140: ¥n"
2008/11/20©TOPPERSプロジェクト".long 140 ¥n"

外部シンボルの参照

16

システム・コンフィギュレーションに関連して必要な修正（３）−３
・割込みの出入口処理
割込みの出入口処理では、外部とのシンボルのインポート／エクスポートが必要になる。
・ユーザー記述部分 と・コンフィギュレーション時の自動生成ファイルの結合GNU版では、インライン・アセンブラを用いて記述しているが、shcではインライン・アセンブラ内で外部シンボルを用いることができない。
→割込みの出入口処理を、アセンブラ・ソースファイルとして分離
テンプレートファイルにて、コンフィギュレータの出力先をCソースファイル
kernel_cfg.cからアセンブラ・ファイルkernel_cfg_asm.srcに変更

コンフィギュレータ

2008/11/20

生成

C言語：kernel_cfg.c/h

生成

アセンブラ言語：kernel_cfg_asm.src©TOPPERSプロジェクト

17クリティカル・セクション
・最適化問題
入口処理（CPUロック）

クリティカル・セクション
出口処理（CPUロック解除）•gcc

コンパイラの最適化により、クリティカル・セクションの出入口処理をまたいで、処理の順番が交換される場合がある！

gccでは、Asm(“”:::“memory”)）;を挿入するなどの処置が必要•shc
shcでは、組み込み関数（具体的にはset_sr())をまたいで、処理の順番を入れ替えるような最適化は行わないため、このような心配はない。
※詳細は、ポーティングガイドasp/doc/porting.txt「1.6 クリティカルセクションの出入処理の実現に関する制約」を参照
2008/11/20©TOPPERSプロジェクト

18

アセンブラ用のインクルードファイル
GNU開発環境では、Cソースファイルとアセンブラ・ソースファイルでプリプロセッサのディレクティブが共通なので、インクルードファイルを共有できる。
ルネサス開発環境では、インクルードファイルを共有できないので、アセンブラ用のインクルードファイルを別途、用意する。
・レジスタ定義
・クロック周波数の定義
・シンボル・リネーム xxxx_rename.h
例：kernel_rename.hの代替_dispatch:.DEFINE

C言語用
インクルードファイル"__kernel_dispatch"

C言語ソースファイル xxx.c
アセンブラ言語ソースファイル xxx.src

インクルードできない
2008/11/20©TOPPERSプロジェクト

19

その他
・アセンブラ・ソースコード– 外部シンボルのインポートを明示的に記述する。
– 例：asp/arch/sh12a_shc/prc_support.src.IMPORT _p_runtsk

・文字コード／改行コード– GNU開発環境：EUC＋LF– ルネサス開発環境：SJIS＋CR/LF
処理系自体はEUCコードにも対応しているが、ユーザーの利便性を考慮して、SJISコードを使用

・ディレクトリ構成– ソースツリー全体がワークスペース配下にある方が扱いやすい。
– 配布パッケージ（簡易パッケージ）は、そのようにディレクトリを構成

2008/11/20©TOPPERSプロジェクト

20

付録

2008/11/20©TOPPERSプロジェクト

21

Cコンパイラの比較（１）
ルネサス shc

GNU gcc

ASPカーネルとの関係

intサイズ

両者とも同じ（３２ビット）

コーリング・
コンベンション

両者とも同じ–r0〜r7を呼び出し側で保存–引数： r4〜r7–戻り値：r0

ディスパッチャの構造はそのままでOK

インライン関数__inline__ void func(void){......
}

C99のinlineキー
ワード相当を想定

2008/11/20#pragma inline func

©TOPPERSプロジェクト

inline voidfunc(void) {......}
22

Cコンパイラの比較（２）ルネサス shc

GNU gcc
インライン・アセンブラ__asm__ (“stc sr,%0” :#pragma inline_asm
func"=r"(sr));•関数単位で記述•行単位で記述可能•C言語の変数とレジスタの •インライン・アセン
ブラ関数内部から対応を指定できる。
・外部シンボルの参照も可 は外部シンボルを参照不可

呼出し元へリターンしない
関数属性__attribute__((__noreturn__))2008/11/20

なし©TOPPERSプロジェクト

ASPカーネルとの関係
GNU版では、割込
みの出入口処理をインライン・アセンブ
ラで記述→外部シンボルを参照している

NoReturnマクロとして、ext_ker()でから呼び出される
target_exit()で使用
23

アセンブラの比較（１）
GNU gasプリプロセッサ
ディレクティブ

ルネサス
asmsh

C言語のプリプロセッサ
ディレクティブと共通–コメント/* コメント */; コメント–マクロ定義#define N 10

N: .DEFINE "10"

–条件付取り込み#ifdef DEBUG#else#endif.AIFDEF DEBUG.AELSE.AENDI

１６進表記
2008/11/20

ASPカーネルとの関係

0xff（C言語と同様） H’FF
©TOPPERSプロジェクト

24アセンブラの比較（２）GNU gasルネサス asmsh ASPカーネ
ルとの関係

データ定義

.long 0x10

.DATA.L H’10

グローバル・シンボル（外部への公開）.global _dispatch.GLOBAL _dispatch

外部シンボルのインポート

省略可.IMPORT _p_runtsk

セクション名.text（.data, .bss）.SECTION P, CODE,ALIGN=4（P, C, D, R, B）

2008/11/20©TOPPERSプロジェクト25リンカの比較GNU ldルネサス
optlink

PROVIDE(_foo = 0); -change=w=2310オプ
未定義のシンボ
ルの扱い
シンボル_fooが未定 ションで、左記の（weak definition） 義であれば、値として、 PROVIDE機能相当を実現0を設定する。

ASPカーネルとの関係
下記参照

ASPカーネルでは、下記の３つのシンボルで使用•_hardware_init_hook：ターゲットシステム依存の初期化•_software_init_hook：開発環境（特にライブラリ）に依存して必要な初期化処理•_software_term_hook：開発環境（特にライブラリ）に依存して必要な終了処理

2008/11/20©TOPPERSプロジェクト

26

intサイズに関連する定義
C99互換の整数型を定義する。
– gccもshcも基本データ型（char/short/int/long）のビット幅が同じなので、gcc版の定義をそのまま流用できる。

asp/arch/shc/tool_stddef.h ←処理系依存（SH1〜SH4まで共通に使える）
typedef signed chartypedef unsigned char

int8_t; /* 符号付き8ビット整数 */uint8_t; /* 符号無し8ビット整数 */（中略）
typedef long
typedef unsigned long

2008/11/20

intptr_t; /* ポインタを格納できる符号付き整数 */uintptr_t; /* ポインタを格納できる符号無し整数 */©TOPPERSプロジェクト

27

コントロール・レジスタへのアクセス
コントロール・レジスタ：プロセッサ内部のSR, VBRなど処理系が提供する組み込み関数（set_sr()など）で対応できる。

2008/11/20©TOPPERSプロジェクト

28

オフセットファイルの生成
アセンブラ・ルーチンからTCB構造体のメンバにアクセスするためのオフセット定義
現状、offset.inc内で決め打ちにしている。
TCB_p_tinib:
TCB_texptn:
TCB_sp:
TCB_pc:TINIB_exinf:
TINIB_task:.DEFINE "(8)".DEFINE "(H'14)".DEFINE "(H'1c)".DEFINE "(H'20)".DEFINE "(4)".DEFINE "(8)"; バイトアクセス
TCB_enatex:
TCB_enatex_bit:
TCB_enatex_mask:.DEFINE "(H'11)".DEFINE "(5)".DEFINE "(1 << TCB_enatex_bit)"2008/11/20©TOPPERSプロジェクト29非依存部のインライン関数•gcc__inline__ void func(void){}•shc#pragma inline func
ASPカーネルでは、C99のinlineキーワード相当の機能を想定している。
例えば、非依存部のt_syslog.hで定義されているインライン関数に対して、ターゲット依存部のみの修正で#pragma inlineを挿入する術がない。

2008/11/20

例：asp/include/t_syslog.h 142行目
Inline void ←#pragma inlineを挿入できない。
_syslog_0(uint_t prio, uint_t type){
SYSLOG syslog;
syslog.logtype = type;(void) syslog_wri_log(prio, &syslog);}©TOPPERSプロジェクト

30要望
プロジェクトファイルをプロセッサ依存部とボード依存部に分離できると便利（それぞれを順不同に編集したい）
・ビルド・オプション
・インクルード・ファイルへのサーチパス

GNU makeの場合
ボード依存のMakefileからプロセッサ依存Makefileをインクルード

2008/11/20

ボードAのMakefile.target

インクルードボードBのMakefile.target

インクルード©TOPPERSプロジェクト

プロセッサ依存部
Makefile.prc

31