TOPPERS/ASP3カーネル ターゲット依存部 ポーティングガイド 対応バージョン: Release 3.B.0 最終更新: 2016年1月12日 このドキュメントは,TOPPERS/ASP3カーネルを,未サポートのターゲットシス テムにポーティングするために必要となるターゲット依存部の実装方法を説明 するものである. ---------------------------------------------------------------------- TOPPERS/ASP Kernel Toyohashi Open Platform for Embedded Real-Time Systems/ Advanced Standard Profile Kernel Copyright (C) 2005-2016 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: porting.txt 507 2016-01-12 01:58:33Z ertl-hiro $ ---------------------------------------------------------------------- ○目次 1.共通事項 1.1 ターゲット依存部の構成 1.1.1 ターゲット略称とターゲット依存部ディレクトリ 1.1.2 開発環境依存部ディレクトリ 1.1.3 プロセッサコア依存部ディレクトリ 1.1.4 チップ依存部ディレクトリ 1.2 名前の衝突の防止 1.3 ヘッダファイルの記述ルール 1.3.1 ヘッダファイルの自己完結 1.3.2 多重インクルードへの対応 1.3.3 アセンブリ言語とのヘッダファイルの共用 1.4 インクルード記述の方法 1.5 クリティカルセクションの出入処理の実現に関する制約 2.システム構築環境のターゲット依存部 2.1 システム略称・開発環境略称等の設定 2.2 依存部ディレクトリの設定 2.3 コマンド名の設定 2.4 コンパイルオプションとオブジェクトファイルの設定 2.5 オフセットファイルの生成方法 2.6 リンク方法の設定 2.7 依存関係の定義 2.8 その他の設定 3.TOPPERS共通定義のターゲット依存部 3.1 ターゲット識別マクロ 3.2 整数型の最大値・最小値・ビット数 3.3 サイズの指定された整数型,その最大値・最小値,整数定数を作るマクロ 3.4 サイズの指定された浮動小数点型,その最大値・最小値のマクロ 3.5 コンパイラの拡張機能のためのマクロ定義 3.6 標準的な定義の上書き 3.7 アサーションのための定義 4.システムインタフェースレイヤ(SIL)のターゲット依存部 4.1 全割込みロック状態の管理 4.2 微少時間待ち 4.3 プロセッサのエンディアン 4.4 メモリ空間アクセス関数 4.5 I/O空間アクセス関数 5.カーネルAPIのターゲット依存部 5.1 ターゲット定義でサポートする機能 5.2 割込み優先度の範囲 5.3 高分解能タイマのタイマ周期とカウント値の進み幅 5.4 メモリ領域確保のための型定義 5.5 ビットパターンのビット数 5.6 メモリ領域確保のためのマクロ 5.7 オーバランハンドラ機能拡張のための定義(オプション) 6.カーネル実装のターゲット依存部 6.1 カーネル実装のターゲット依存部の共通事項 6.2 トレースログ機能への対応 6.3 システム状態の管理 6.3.1 全割込みロック状態の管理 6.3.2 コンテキストの管理 6.3.3 CPUロック状態の管理 6.4 割込みに関連するシステム状態の管理 6.4.1 割込み優先度マスクの管理 6.4.2 割込み要求禁止フラグの管理 6.4.3 割込み要求のクリア 6.4.4 割込み要求のプローブ 6.5 タスクディスパッチャ 6.5.1 タスクコンテキストブロックとタスク初期化コンテキストブロック 6.5.2 ディスパッチャ本体 6.5.3 自発的なディスパッチ 6.5.4 ディスパッチャの動作開始 6.5.5 現在のコンテキストを捨ててディスパッチ 6.5.6 タスクの起動準備 6.6 割込みハンドラ 6.6.1 割込みハンドラの出入口処理 6.6.2 割込みハンドラ毎の出入口処理の生成 6.6.3 割込みハンドラの設定 6.6.4 割込み要求ラインの属性の設定 6.6.5 割込み管理機能の初期化処理の変更 6.6.6 デフォルトの割込みハンドラ 6.6.7 カーネル管理外の割込み 6.6.8 割込みサービスルーチンの生成 6.7 CPU例外ハンドラとCPU例外発生時のシステム状態の参照 6.7.1 CPU例外ハンドラの出入口処理 6.7.2 CPU例外ハンドラの出入口処理の生成 6.7.3 CPU例外ハンドラの設定 6.7.4 CPU例外管理機能の初期化処理の変更 6.7.5 デフォルトのCPU例外ハンドラ 6.7.6 CPU例外発生時のシステム状態の参照 6.8 カーネルの起動・終了とスタック領域など 6.9 カーネル内部のチューニング 6.9.1 ビットマップサーチ 6.9.2 ビットフィールド 6.10 カーネル実装に関するその他の定義 6.10.1 オブジェクト属性の拡張 6.10.2 エラーチェック方法の指定 6.10.3 非タスクコンテキスト用のスタック領域 6.10.4 空ラベルの定義 6.11 トレースログ機能に関する設定 6.11.1 取得できるトレースログの種類とマクロ 6.11.2 トレースログ記録のサンプルコード 6.12 カーネル実装のターゲット依存部のためのリネーム記述 6.13 高分解能タイマドライバ 6.13.1 高分解能タイマドライバのファイル構成 6.13.2 高分解能タイマの操作と割込み処理 6.13.3 高分解能タイマドライバの実装アプローチ 6.13.4 タイムティックを用いたタイマドライバの実装 6.14 オーバランタイマドライバ(オプション) 6.14.1 オーバランタイマドライバのファイル構成 6.14.2 オーバランタイマの操作と割込み処理 6.15 動的メモリ管理(オプション) 6.15.1 TLSFを用いたメモリ管理モジュールの例 7.コンフィギュレータ設定ファイルのターゲット依存部 7.1 設定ファイルとターゲット依存部の位置付け 7.2 パス2のテンプレートファイルのターゲット依存部 7.2.1 ターゲット非依存部をインクルードする前に定義すべき変数 7.2.2 ターゲット非依存部で定義される変数 7.3 パス3のテンプレートファイルのターゲット依存部 7.3.1 ターゲット非依存部をインクルードする前に定義すべき変数 7.3.2 ターゲット依存部で行うべきエラーチェック 7.4 cfg1_out.cのリンクに必要なスタブの定義ファイル 8.システムサービス等のターゲット依存部 8.0 システムサービスのターゲット依存部 8.1 システムログ機能のターゲット依存定義 8.2 システムログタスクのターゲット依存定義 8.3 シリアルインタフェースドライバのターゲット依存部 8.3.1 変数,データ型,管理関数 8.3.2 デバイスサービスルーチン 8.3.3 コールバックルーチン 8.4 カーネル起動メッセージの出力のターゲット依存定義 8.5 サンプルプログラムとテストプログラムのターゲット依存定義 8.6 実行時間分布集計サービスのターゲット依存定義 9.その他 9.1 ドキュメント 9.2 パッケージ記述ファイル 10.リファレンス 10.1 ターゲット依存部のファイル一覧 1.共通事項 1.1 ターゲット依存部の構成 ターゲット依存部は,targetディレクトリの下に,ターゲットハードウェアと 開発環境の組み合わせ毎に用意する.ただし,ターゲット依存部の再利用性を 考慮し,開発環境/プロセッサコア/チップのみに依存する部分を,開発環境 依存部/プロセッサコア依存部/チップ依存部という形で切り分けてもよい. 切り分け方は,ターゲット依存部の実装に任されている.開発環境依存部/プ ロセッサコア依存部/チップ依存部は,archディレクトリの下に置く. ASP3カーネルのターゲット依存部は,システム構築環境のターゲット依存部, TOPPERS共通定義のターゲット依存部,システムインタフェースレイヤ(SIL) のターゲット依存部,カーネルAPIのターゲット依存部,カーネル実装のターゲッ ト依存部(コンフィギュレータ設定ファイルのターゲット依存部を含む),シ ステムサービス等のターゲット依存部,ターゲット依存部に関するドキュメン トで構成される. 1.1.1 ターゲット略称とターゲット依存部ディレクトリ 新しいターゲット依存部を作成する時は,まず,ターゲット略称を定める.ター ゲット略称は,システム略称と開発環境略称を"_"で連結したものとする.シス テム略称に用いる文字は英小文字と数字と"_"に,開発環境略称に用いる文字は 英小文字と数字に限定する.GNU開発環境の開発環境略称は,"gcc"とする.例 えば,システム略称が"ct11mpcore"で,GNU開発環境を用いる場合には,ターゲッ ト略称は"ct11mpcore_gcc"となる. ターゲット依存部のファイルを置くために,targetディレクトリの下に,ター ゲット略称を名称とするディレクトリを作成する.これをターゲット依存部ディ レクトリと呼ぶ. 1.1.2 開発環境依存部ディレクトリ ターゲット依存部から開発環境依存部を切り分ける場合には,archディレクト リの下に,開発環境略称を名称とするディレクトリを作成する.これを開発環 境依存部ディレクトリと呼ぶ. 1.1.3 プロセッサコア依存部ディレクトリ ターゲット依存部からプロセッサコア依存部を切り分ける場合には,まず,プ ロセッサコア略称を定める.プロセッサコア略称に用いる文字は,英小文字と 数字と"_"に限定する. プロセッサコア依存部のファイルを置くために,archディレクトリの下に,プ ロセッサコア略称と開発環境略称を"_"で連結したものを名称とするディレクト リを作成する.例えば,プロセッサコア略称が"arm"で,GNU開発環境を用いる 場合には,ディレクトリの名称は"arm_gcc"となる. チップ依存部ディレクトリをプロセッサコア依存部ディレクトリの下に置く場 合(「1.1.4 チップ依存部ディレクトリ」の節の(1)の場合)を除いては,これ をプロセッサコア依存部ディレクトリと呼ぶ. 1.1.4 チップ依存部ディレクトリ ターゲット依存部からチップ依存部を切り分ける場合には,まず,チップ略称 を定める.チップ略称に用いる文字は,英小文字と数字と"_"に限定する. チップ依存部のファイルを置くディレクトリ(これをチップ依存部ディレクト リと呼ぶ)は,その置き場所によって,次の2つ方法がある. (1) プロセッサコア依存部ディレクトリの下に置く チップ依存部ディレクトリを,プロセッサコア依存部ディレクトリの下に置く 場合には,チップ略称をディレクトリの名称とする. この方法を取る場合,プロセッサコアのみに依存するファイルは,プロセッサ コア依存部ディレクトリの直下には置かず,プロセッサコア依存部ディレクト リの下に"common"という名称のディレクトリを作成し,その下に置く.この場 合には,プロセッサコアのみに依存するファイルを置くディレクトリを,プロ セッサコア依存部ディレクトリと呼ぶ. 例えば,プロセッサコア略称が"arm",チップ略称が"mpcore"で,GNU開発環境 を用いる場合には,プロセッサコア依存部ディレクトリは arch/arm_gcc/common,チップ依存部ディレクトリはarch/arm_gcc/mpcoreとな る. (2) archディレクトリの直下に置く チップ依存部ディレクトリを,archディレクトリの直下に置く場合には,チッ プ略称と開発環境略称を"_"で連結したものを,ディレクトリの名称とする. 1.2 名前の衝突の防止 TOPPERSプロジェクトが提供するソフトウェアのために,TOPPERS_で始まるシン ボルを予約している.ヘッダファイル中に記述され,アプリケーションから参 照できる内部シンボルは,TOPPERS_で始まる名前とする. また,_kernel_で始まるシンボルは,カーネル内部の変数や関数のために予約 している.カーネル内部の変数や関数の名前で,リンク時にアプリケーション の名前と衝突する可能性があるものは,リネーム記述にリストアップすること で,コンパイル時に_kernel_で始まる名前に置き換えることとしている. 1.3 ヘッダファイルの記述ルール ヘッダファイルは,この節のルールに従って記述しなければならない.なお, この節の記述内容は,本来はコーディングルールに含めるべき内容である. 1.3.1 ヘッダファイルの自己完結 ヘッダファイルは,自己完結するように,必要な他のヘッダファイルをインク ルードするのを原則とする.言い換えると,ヘッダファイルをインクルードす る前に,他のヘッダファイルをインクルードしてあることを仮定してはならな い. 1.3.2 多重インクルードへの対応 ヘッダファイルには,多重にインクルードされても問題ないようにするための 条件コンパイル記述を含めるものとする.例えば,target_kernel_impl.hであ れば,ファイルの先頭に #ifndef TOPPERS_TARGET_KERNEL_IMPL_H #define TOPPERS_TARGET_KERNEL_IMPL_H を,ファイルの末尾に #endif /* TOPPERS_TARGET_KERNEL_IMPL_H */ を記述する. 1.3.3 アセンブリ言語とのヘッダファイルの共用 ヘッダファイルの中で,アセンブリ言語のソースファイルからもインクルード される可能性のあるものは,次のルールに従って記述するものとする. ・TOPPERS_MACRO_ONLYがマクロ定義されている場合には,アセンブリ言語では  解釈できない記述(マクロ定義以外の記述)を除くように記述する. ・符号無し整数型の定数値は,UINT_CやULONG_Cなどの整数定数を作るためのマ  クロを用いて記述する.ただし,アセンブリ言語のソースファイルからもイ  ンクルードされるファイル中であっても,C言語のみで用いる定数は,これら  のマクロを使って記述する必要はない. ・アセンブリ言語からも用いる定数の定義中に型キャストを用いる場合には,  CASTマクロを用いて記述する. アセンブリ言語からヘッダファイルをインクルードする際には,必要に応じて, TOPPERS_MACRO_ONLY,UINT_C,ULONG_C,CASTをマクロ定義してから,インクルー ドしなければならない. 1.4 インクルード記述の方法 開発環境で用意されている標準ヘッダファイルおよびincludeディレクトリ下の 標準ヘッダファイルは,「#include <...>」によりインクルードする. その他のヘッダファイルは,「#include "..."」によりインクルードする.ヘッ ダファイルが,カレントディレクトリやインクルードするファイルと同じディ レクトリ以外のディレクトリに置かれている場合には,次のようにパス指定を 行う. ・ターゲット依存部ディレクトリ,開発環境依存部ディレクトリ,プロセッサ  コア依存部ディレクトリ,チップ依存部ディレクトリに置かれている場合は,  パス指定を行わず,ファイル名のみを記述する. 例)#include "target_kernel_impl.h" 例)#include "core_kernel_impl.h" 例)#include "tool_stddef.h"  これは,コンパイラに与える-Iオプションにより,インクルードするファイ  ルを制御できるようにするためである. ・その他のディレクトリに置かれている場合には,ソースプログラムのルート  ディレクトリ(configureが置かれているディレクトリ)からの相対パスで記  述する. 例)#include "arch/logtrace/trace_config.h" ・カーネルを構成するファイルから,kernelディレクトリ下のヘッダファイル  をインクルードする場合は,パス指定を行わず,ファイル名のみを記述する. 例)#include "kernel_impl.h" 1.5 クリティカルセクションの出入処理の実現に関する制約 カーネル内で用いるクリティカルセクションの出入処理を実現する場合には, 次の2つの条件を満たすように実装しなければならない. (1-5-1) 出入処理から抜けた時点では,割込みの禁止/許可が完了していなけ ればならない.例えば,割込み禁止/許可命令を実行してから実際に割込みが 禁止/許可されるまで何命令か遅延するプロセッサの場合には,出入処理の中 にNOP命令を入れるなどの方法で,出入処理を抜けた時点では,割込みが禁止/ 許可された状態になっていることを保証しなければならない. (1-5-2) メモリ上のデータ構造が書き変わる可能性があることを,何らかの方 法でコンパイラに知らせなければならない.GNU開発環境では,次のいずれかの 方法でこの制約を満たすことができる. (a) クリティカルセクションの出入処理の全体または出入処理の本質的な部分 (具体的には,割込み禁止/許可する処理)を(インラインでない)通常 の関数により実現する. (b) クリティカルセクションの出入処理の本質的な部分をインラインアセンブ ラによって実現している場合には,そのインラインアセンブラのclobber変 数リストに"memory"を追加する. (c) クリティカルセクションの出入処理の本質的な部分が,マクロやインライ ン関数呼出しで実現している場合には,クリティカルセクションに入る処 理の最後と出る処理の先頭に,Asm("":::"memory")という記述を入れる. このような制約を設ける理由については,「TOPPERS/ASP3カーネル 設計メモ」 の「カーネルのデータ構造に対するvolatile宣言について」の節を参照するこ と. 2.システム構築環境のターゲット依存部 この章の説明は,GNU開発環境(GCC,GAS,BINUTILS,GNU Make)を用いること を想定して記述してある.それ以外の開発環境を用いる場合には,開発環境に あわせて修正する必要がある. GNU開発環境用のシステム構築環境は,サンプルのMakefile(sample/Makefile), コンフィギュレーションスクリプト(configure)で構成される. GNU開発環境以外の開発環境を用いる場合には,これらのファイルを,その開発 環境用に用意する必要がある場合がある.その場合には,これらのファイルを, ターゲット依存部ディレクトリか開発環境依存部ディレクトリに置くものとす る.また,開発環境用のプロジェクトファイルが必要な場合には,ターゲット 依存部ディレクトリに置くものとする. サンプルのMakefileは,ターゲット依存部ディレクトリのMakefile.targetをイ ンクルードする.Makefileのターゲット依存部は,ターゲット依存部ディレク トリのMakefile.targetまたはそこからインクルードされるファイル(開発環境 依存部/プロセッサコア依存部/チップ依存部で用意されるファイルなど)に 含める.以下では,Makefileのターゲット依存部に記述すべき内容について説 明する. 2.1 システム略称・開発環境略称等の設定 システム略称,開発環境略称,プロセッサコア略称,チップ略称を設定するた めに,Makefileのターゲット依存部で次の変数を定義する.なお,ターゲット 略称は,ターゲット非依存のMakefileにおいて,変数TARGETに定義されている ことを想定する. (2-1-1) SYS システム略称 システム略称に定義する. (2-1-2) TOOL 開発環境略称 開発環境依存部を用いる場合には,開発環境略称に定義する.GNU開発環境を用 いる場合には,gccに定義する. (2-1-3) CORE プロセッサコア略称 (2-1-4) CHIP チップ略称 プロセッサコア依存部/チップ依存部を用いる場合には,それぞれ,プロセッ サコア略称/チップ略称に定義する. 2.2 依存部ディレクトリの設定 開発環境依存部ディレクトリ,プロセッサコア依存部ディレクトリ,チップ依 存部ディレクトリを設定するために,Makefileのターゲット依存部で次の変数 を定義する. なお,ターゲット依存部ディレクトリは,ターゲット非依存のMakefileにおい て,変数TARGETDIRに定義されていることを想定する.また,ソースプログラム のルートディレクトリ(configureが置かれているディレクトリ)は,変数 SRCDIRに定義されていることを想定する. (2-2-1) TOOLDIR 開発環境依存部ディレクトリ (2-2-2) COREDIR プロセッサコア依存部ディレクトリ (2-2-3) CHIPDIR チップ依存部ディレクトリ 開発環境依存部/プロセッサコア依存部/チップ依存部を用いる場合には,そ れぞれ,開発環境依存部ディレクトリ/プロセッサコア依存部ディレクトリ/ チップ依存部ディレクトリに定義する. 2.3 コマンド名の設定 (2-3-1) GCC_TARGET GNU開発環境のターゲット名 GNU開発環境を用いる場合に,GNU開発環境をconfigureする場合に指定するター ゲット名に定義する.ここで指定したターゲット名は,開発環境のコマンド名 の先頭に付与される文字列となる.例えば,GCC_TARGETをarm-none-eabiに定義 した場合には,コンパイラとしてarm-none-eabi-gccが使われる.この変数が定 義されない場合には,単なるgccが使われる. (2-3-2) CC Cコンパイラドライバの名称 (2-3-3) CXX C++コンパイラドライバの名称 (2-3-4) AS アセンブラの名称 (2-3-5) LD リンカの名称 (2-3-6) AR アーカイバの名称 (2-3-7) NM nmプログラムの名称 (2-3-8) RANLIB ranlibプログラムの名称 (2-3-9) OBJCOPY objcopyプログラムの名称 (2-3-10) OBJDUMP objdumpプログラムの名称 GNU開発環境以外の開発環境を用いる場合に,それぞれのコマンドの名称に定義 する.対応するコマンドがない場合や,コマンドパラメータが異なる場合には, Makefile中でそのコマンドを呼び出している部分を変更する必要がある. GNU開発環境では,これらはGCC_TARGETを用いて定義されるので,定義する必要 はない. 2.4 コンパイルオプションとオブジェクトファイルの設定 Makefileのターゲット依存部で以下で説明する変数を定義する時には,":="を 用いて,それまでの定義に追加する形で行う.例えば,コンパイラに対するそ の他のオプションとして「-Wall -g -O2」を追加したい場合には,「COPTS := $(COPTS) -Wall -g -O2」という記述をMakefileのターゲット依存部に含める. (2-4-1) COPTS コンパイラに対するその他のオプション (2-4-2) CDEFS マクロ定義オプション(-Dオプション) (2-4-3) INCLUDES ヘッダファイルの置かれたディレクトリ指定オ プション(-Iオプション) (2-4-4) LDFLAGS リンカに対するその他のオプション (2-4-5) LIBS ライブラリリンク指定のためのオプション ターゲットに依存して,すべてのソースファイルに共通するコンパイルオプショ ンの追加が必要な場合には,オプションの種類毎に上に示した変数に定義する. ほとんどの場合に,ターゲット依存部ディレクトリのMakefile.targetには,以 下の記述を含める必要がある. ---------------------------------------- INCLUDES := $(INCLUDES) -I$(TARGETDIR) -I$(TOOLDIR) ---------------------------------------- コンパイラの問題等で,警告メッセージが出ることを防げない状況以外では, COPTSに-Werrorを追加することを推奨する. ---------------------------------------- COPTS := $(COPTS) -Werror ---------------------------------------- カーネルのコンパイル時に,dereferencing type-punned pointer will break strict-aliasing rulesという警告が出る場合には,以下を追加するとよい.こ の警告メッセージに関する詳細は,「TOPPERS/ASP3カーネル 設計メモ」の「型 キャストに伴う警告メッセージ」の節を参照すること. ---------------------------------------- KERNEL_CFLAGS := $(KERNEL_CFLAGS) -fno-strict-aliasing ---------------------------------------- また,アセンブリ言語レベルの識別名が,C言語レベルの識別名の先頭に"_"が 付いたものになる場合には,CDEFSに-DTOPPERS_LABEL_ASMを追加する. (2-4-6) SYSSVC_DIRS システムサービスのソースが置かれたディレクトリ (2-4-7) SYSSVC_ASMOBJS アセンブリ言語で記述されたシステムサービスの オブジェクト (2-4-8) SYSSVC_COBJS C言語で記述されたシステムサービスのオブジェクト (2-4-9) SYSSVC_CFLAGS システムサービスに対するコンパイルオプション ターゲットに依存して,システムサービス(システムログタスクやデバイスド ライバなど)のソースが置かれたディレクトリ,システムサービスを構成する オブジェクトファイルのリスト,それらをコンパイルする際に適用するコンパ イルオプションを追加する場合には,上に示した変数に定義する.なお, SYSSVC_CFLAGSに定義したオプションは,コンフィギュレータが生成したファイ ルをコンパイルする場合には適用されないため,注意すること. (2-4-10) KERNEL_DIRS カーネルのソースが置かれたディレクトリ (2-4-11) KERNEL_ASMOBJS アセンブリ言語で記述されたカーネルのオブジェクト (2-4-12) KERNEL_COBJS C言語で記述されたカーネルのオブジェクト (2-4-13) KERNEL_CFLAGS カーネルに対するコンパイルオプション ターゲットに依存して,カーネルのソースが置かれたディレクトリ,カーネル を構成するオブジェクトファイルのリスト,それらをコンパイルする際に適用 するコンパイルオプションを追加する場合には,上に示した変数に定義する. ほとんどの場合に,ターゲット依存部ディレクトリのMakefile.targetには,以 下の記述を含める必要がある. ---------------------------------------- KERNEL_DIRS := $(KERNEL_DIRS) $(TARGETDIR) KERNEL_ASMOBJS := $(KERNEL_ASMOBJS) target_support.o KERNEL_COBJS := $(KERNEL_COBJS) target_kernel_impl.o target_timer.o ---------------------------------------- (2-4-14) OBJ_LDFLAGS カーネルに対するリンクオプション ターゲットに依存して,カーネルをリンクする際に適用するオプションを追加 する場合には,上に示した変数に定義する.LDFLAGSと異なり,この変数に追加 したオプションは,cfg1_out.cをリンクする際には適用されない. (2-4-15) CFG_TABS コンフィギュレータに対するオプション ターゲットに依存して,コンフィギュレータに対するオプションを追加する場 合には,上に示した変数に定義する.具体的には,コンフィギュレータの値取 得シンボルテーブルのターゲット依存部(target_def.csv)がある場合には, それを指定するオプションを追加する必要がある. ほとんどの場合に,ターゲット依存部ディレクトリのMakefile.targetには,以 下の記述を含める必要がある. ---------------------------------------- CFG_TABS := $(CFG_TABS) --cfg1-def-table $(TARGETDIR)/target_def.csv ---------------------------------------- (2-4-16) CFG1_OUT_LDFLAGS cfg1_out.cに対するリンクオプション ターゲットに依存して,cfg1_out.cをリンクする際に適用するオプションを追 加する場合には,上に示した変数に定義する.LDFLAGSと異なり,この変数に追 加したオプションは,カーネルをリンクする際には適用されない. (2-4-17) CFG_ASMOBJS アセンブリ言語で記述されたシステムコンフィ ギュレーションのためのオブジェクト (2-4-18) CFG_COBJS C言語で記述されたシステムコンフィギュレー ションのためのオブジェクト ターゲットに依存して,システムコンフィギュレーションのためのオブジェク トファイルを(kernel_cfg.o以外に)追加する場合には,上に示した変数に定 義する.この場合,追加したオブジェクトファイルの作成ルール(コンパイル/ アセンブルルールと依存関係作成ルール)を,Makefileのターゲット依存部に 記述する必要がある. (2-4-19) CFG2_OUT_SRCS ターゲットに依存して,コンフィギュレータのパス2でkernel_cfg.cと kernel_cfg.h以外のファイルを生成する場合には,上に示した変数に定義する. (2-4-20) OMIT_WARNING_ALL (2-4-21) OMIT_OPTIMIZATION サンプルのMakefileでは,コンパイラに対するオプションに「-Wall -g -O2」 を追加する.-Wallを追加したくない場合には,Makefileのターゲット依存部で OMIT_WARNING_ALLを"true"に定義する.-O2を追加したくない場合には, Makefileのターゲット依存部でOMIT_OPTIMIZATIONを"true"に定義する. 2.5 オフセットファイルの生成方法 アセンブリ言語で記述されるプログラムから,C言語の構造体にアクセスする場 合には,構造体の各フィールドのオフセット値を参照することが必要である. ASP3カーネルでは,コンフィギュレータを用いて必要なオフセット値を求め, オフセットファイル(offset.h)に生成するための仕組みを用意している. この仕組みを用いることで,例えば,TCB中のp_tinibフィールドのオフセット 値をTCB_p_tinibにマクロ定義することや,TCB中のタスクコンテキストブロッ ク(tskctxb)に含まれるpcフィールドのオフセット値をTCB_pcにマクロ定義す ることができる.また,TCB中のenaterフィールドのオフセット値,ビット位置, ビットマスクを,それぞれTCB_enater,TCB_enater_bit,TCB_enater_maskにマ クロ定義することができる. 用意している仕組みによりオフセットファイルを生成できない時には,オフセッ トファイルをターゲット依存部で用意する必要がある. オフセットファイルが必要ない場合や,オフセットファイルをターゲット依存 部で用意する場合には,Makefileのターゲット依存部でOMIT_OFFSET_Hを "true"に定義する. 拡張パッケージの中には,TCBにフィールドを追加するものがあるため,TCB中 のフィールドのオフセット値は変化する.offset.hを生成する場合でも,ター ゲット依存部で用意する場合でも,拡張パッケージに対応するためには,この ことを考慮する必要がある. 以下では,コンフィギュレータを用いてoffset.hを生成する方法について説明 する.この方法では,コンフィギュレータのパス1で生成するcfg1_out.cをコン パイルして生成したオブジェクトファイルから,コンフィギュレータによって offset.hを生成する. この方法を用いるためには,ターゲット依存部でオフセットファイル生成用テ ンプレートファイルを用意し,target_cfg1_out.h(または,そこからインクルー ドされるファイル)とtarget_def.csv(または,同等の役割を持つファイル) に記述を追加する必要がある.なお,これらのファイルを新たに用意した際や 修正した際には,offset.hに妥当な定義が生成されていることを確認すべきで ある. オフセットファイル生成用テンプレートファイルは,ターゲット依存部で, target_offset.tfに用意する.オフセットファイル生成用テンプレートファイ ルを別のディレクトリまたは別のファイル名で用意する場合には,そのファイ ル名を,Makefileのターゲット依存部でOFFSET_TFに定義する. オフセットファイル生成用テンプレートファイルには,以下の内容を記述する. (1) 標準テンプレートファイルのインクルード オフセットファイル生成用の標準テンプレートファイル(kernel/genoffset.tf) をインクルードする.標準テンプレートファイルには,以下で用いるDEFINE関 数やDEFINE_BIT関数の定義などが含まれている. ---------------------------------------- $ 標準テンプレートファイルのインクルード $INCLUDE "kernel/genoffset.tf"$ ---------------------------------------- (2) オフセット値のマクロ定義の生成 DEFINE関数を用いて,オフセット値のマクロ定義を生成する.例えば,TCB中の タスクコンテキストブロック(tskctxb)に含まれるpcフィールドのオフセット 値を,TCB_pcにマクロ定義する場合には,次のように記述する. ---------------------------------------- $ オフセット値のマクロ定義の生成 $DEFINE("TCB_pc", offsetof_TCB_pc)$ ---------------------------------------- ここで,DEFINE関数の第1パラメータはマクロ定義するシンボル,第2パラメー タは,オフセット値を保持するコンフィギュレータの変数である. また,コンフィギュレータが,オフセット値を保持する変数(上の例では offsetof_TCB_pc)に値を設定するために,target_def.csv(または,同等の役 割を持つファイル)に次の例のような行を追加する. ---------------------------------------- offsetof_TCB_pc,"offsetof(TCB,tskctxb.pc)" ---------------------------------------- ただし,各オブジェクトの初期化ブロックのターゲット非依存のフィールドの オフセット値を取得するための記述は,kernel/kernel_def.csvに含まれている. kernel/kernel_def.csvに含まれている記述は,target_def.csv(または,同等 の役割を持つファイル)に追加する必要はない. (3) ビットオフセット値等のマクロ定義の生成 DEFINE_BIT関数を用いて,ビットのオフセット値,ビット位置,ビットマスク のマクロ定義を生成する.例えば,TCB中のenaterフィールドのオフセット値, ビット位置,ビットマスクを,それぞれTCB_enater,TCB_enater_bit, TCB_enater_maskにマクロ定義する場合には,次のように記述する. ---------------------------------------- $DEFINE_BIT("TCB_enater", sizeof_TCB, "B")$ ---------------------------------------- ここで,DEFINE_BIT関数の第1パラメータはマクロ定義するシンボル(の先頭部 分),第2パラメータは構造体のサイズである.第3パラメータには,ビットの オフセット,ビット位置,ビットマスクを,8ビット単位(バイト単位)で求め る場合には"B"を,16ビット単位で求める場合には"H"を,32ビット単位で求め る場合には"W"を指定する.なお,ビット位置は,LSBを0とした値(ビットリト ルエンディアンを想定)を求める. また,target_cfg1_out.h(または,そこからインクルードされるファイル)に, ビットオフセット値等を求めるための構造体の変数定義を追加する.この構造 体の変数は,名称をマクロ定義するシンボル(DEFINE_BIT関数の第1パラメータ) とし,対象のビットのみが1で,他のすべてのビットが0になるように初期化す る.また,const修飾子を付加する.例えば,TCB中のenaterフィールドのビッ トオフセット値等を求める場合には,次のような定義を追加する(tskctxbの初 期値は,ターゲット依存なので注意すること). ---------------------------------------- const TCB TCB_enater = { { NULL, NULL }, /* task_queue */ NULL, /* p_tinib */ 0U, /* tstat */ 0U, /* bpriority */ 0U, /* priority */ false, /* actque */ false, /* wupque */ false, /* raster */ true, /* enater */ #ifdef TOPPERS_SUPPORT_OVRHDR false, /* staovr */ #endif /* TOPPERS_SUPPORT_OVRHDR */ #ifdef TOPPERS_SUPPORT_SUBPRIO 0U, /* subpri */ #endif /* TOPPERS_SUPPORT_SUBPRIO */ NULL, /* p_winifo */ NULL, /* p_lastmtx */ #ifdef TOPPERS_SUPPORT_OVRHDR 0U, /* leftotm */ #endif /* TOPPERS_SUPPORT_OVRHDR */ { NULL, NULL } /* tskctxb */ }; ---------------------------------------- さらに,コンフィギュレータが,構造体のサイズ(上の例ではsizeof_TCB)に 値を設定するために,target_def.csv(または,同等の役割を持つファイル) に次の例のような行を追加する. ---------------------------------------- sizeof_TCB,sizeof(TCB) ---------------------------------------- ただし,前述した通り,kernel/kernel_def.csvに含まれている記述は, target_def.csv(または,同等の役割を持つファイル)に追加する必要はない. 最後に,target_cfg1_out.h(または,そこからインクルードされるファイル) に,offset.hを生成する仕組みが正しく動作していることを確認するための次 の記述を追加する. ---------------------------------------- const uint8_t MAGIC_1 = 0x12; const uint16_t MAGIC_2 = 0x1234; const uint32_t MAGIC_4 = 0x12345678; ---------------------------------------- 2.6 リンク方法の設定 (2-6-1) LDSCRIPT リンカスクリプトのファイル名 開発環境に標準のリンカスクリプトが使用できない場合には,ターゲット依存 部でリンカスクリプトを用意し,そのファイル名をこの変数に定義する. (2-6-2) TEXT_START_ADDRESS テキストセクションの先頭番地 (2-6-3) DATA_START_ADDRESS データセクションの先頭番地 各セクションの先頭番地の指定が必要な場合には,これらの変数に先頭番地を 定義する. (2-6-4) START_OBJS 先頭にリンクすべきモジュール名 (2-6-5) END_OBJS 最後にリンクすべきモジュール名 ターゲットによっては,ロードモジュールの先頭と最後にリンクすべきモジュー ルを,ターゲット依存部で用意する必要がある.多くの場合,スタートアップ モジュールをロードモジュールの先頭にリンクする必要がある. ロードモジュールの先頭にリンクすべきプログラムがある場合には,Makefile のターゲット依存部において,そのオブジェクトファイル名をSTART_OBJSに定 義し,それに対するコンパイルルールと依存関係作成ルールを定義する.ロー ドモジュールの最後にリンクすべきモジュールがある場合には,そのオブジェ クトファイル名をEND_OBJSに定義し,それに対するコンパイルルールと依存関 係作成ルールを定義する.また,標準のスタートアップモジュール(crt0.o) をリンクしないように,LDFLAGSとCFG1_OUT_LDFLAGSに-nostdlibを追加する必 要がある.さらに,-nostdlibをつけることで標準ライブラリがリンクされなく なるため,LIBSに-lgccを追加しなければならない. 例えば,スタートアップモジュールのソースファイルがstart.Sの場合には, Makefileのターゲット依存部に次のような記述を入れるとよい. ---------------------------------------- # スタートアップモジュールのオブジェクトファイル名 START_OBJS = start.o # スタートアップモジュールのコンパイルルール $(START_OBJS): %.o: %.S $(CC) -c $(CFLAGS) $(KERNEL_CFLAGS) $< # リンカに対するオプション LDFLAGS := -nostdlib $(LDFLAGS) CFG1_OUT_LDFLAGS := -nostdlib $(CFG1_OUT_LDFLAGS) LIBS := $(LIBS) -lgcc ---------------------------------------- また,GNU開発環境で,コンパイラに標準のcrtbegin.oとcrtend.oを用いる場合 には,Makefile のターゲット依存部に次のような記述を入れるとよい. ---------------------------------------- # オブジェクトファイル名 START_OBJS = $(shell $(CC) -print-file-name=crtbegin.o) END_OBJS = $(shell $(CC) -print-file-name=crtend.o) # リンカに対するオプション LDFLAGS := -nostdlib $(LDFLAGS) CFG1_OUT_LDFLAGS := -nostdlib $(CFG1_OUT_LDFLAGS) LIBS := $(LIBS) -lgcc ---------------------------------------- この場合,これらのファイルをコンパイルすることはないため,コンパイルルー ルは不要である.また,依存関係作成ルールはダミーでよい(依存関係作成ルー ルがないとエラーになる). (2-6-6) HIDDEN_OBJS 指定しなくてもリンクされるモジュール名 ロードモジュールにリンクすべきモジュールを,リンカに対するパラメータで はなく,リンカスクリプト中に(例えば,GNU開発環境のリンカスクリプトの STARTUPを使って)記述する場合には,そのオブジェクトファイル名を, (START_OBJSまたはEND_OBJSではなく)HIDDEN_OBJSに定義し,それに対するコ ンパイルルールと依存関係作成ルールを定義する.HIDDEN_OBJSに定義したモ ジュールは,リンカに対するパラメータからは除外される.LDFLAGSと CFG1_OUT_LDFLAGS,LIBSについては,START_OBJSまたはEND_OBJSを用いる場合 と同様である. 例えば,スタートアップモジュールのソースファイルがstart.Sで,start.oを リンクすることをリンカスクリプト中に記述する場合には,Makefileのターゲッ ト依存部に次のような記述を入れるとよい. ---------------------------------------- # スタートアップモジュールのオブジェクトファイル名 HIDDEN_OBJS = start.o # スタートアップモジュールのコンパイルルール $(HIDDEN_OBJS): %.o: %.S $(CC) -c $(CFLAGS) $(KERNEL_CFLAGS) $< # リンカに対するオプション LDFLAGS := -nostdlib $(LDFLAGS) CFG1_OUT_LDFLAGS := -nostdlib $(CFG1_OUT_LDFLAGS) LIBS := $(LIBS) -lgcc ---------------------------------------- 2.7 依存関係の定義(オプション) ターゲット依存部の開発中は,コンフィギュレータの各パスに対して,ターゲッ ト依存部のテンプレートファイルへの依存関係を定義すると便利である.具体 的には,パス1,パス2,パス3が依存するファイルを,それぞれcfg1_out.c, kernel_cfg.timestamp,$(OBJFILE)に対する依存関係の形で記述する. ほとんどの場合,ターゲット依存部ディレクトリのMakefile.targetに含める記 述は,以下のようになる. ---------------------------------------- cfg1_out.c: $(TARGETDIR)/target_def.csv kernel_cfg.timestamp: $(TARGETDIR)/target.tf $(OBJFILE): $(TARGETDIR)/target_check.tf ---------------------------------------- 2.8 その他の設定 (2-8-1) CLEAN_FILES cleanにより削除するファイル名 cleanにより削除するファイルをターゲット依存部で追加したい場合には,ファ イル名をこの変数に追加定義する. (2-8-2) REALCLEAN_FILES realcleanにより削除するファイル名 realcleanにより削除するファイルをターゲット依存部で追加したい場合には, ファイル名をこの変数に追加定義する. 3.TOPPERS共通定義のターゲット依存部 TOPPERS共通定義(t_stddef.h)のターゲット依存部は,target_stddef.hまた はそこからインクルードされるファイル(開発環境依存部/プロセッサコア依 存部/チップ依存部で用意されるヘッダファイルなど)に含める. 3.1 ターゲット識別マクロ アプリケーションやシステムサービスでターゲットを識別するために, "TOPPERS_"にシステム略称を大文字にした文字列を連結したもの(例えば, "TOPPERS_CT11MPCORE")をマクロ定義する. また,ターゲット依存部からプロセッサコア依存部/チップ依存部を切り分け た場合には,"TOPPERS_"にプロセッサコア略称/チップ略称を大文字にした文 字列を連結したもの(例えば,"TOPPERS_ARM")をマクロ定義する. 3.2 整数型の最大値・最小値・ビット数 (3-2-1) INT_MAX intに格納できる最大値(C90準拠) (3-2-2) INT_MIN intに格納できる最小値(C90準拠) (3-2-3) UINT_MAX unsigned intに格納できる最大値(C90準拠) (3-2-4) LONG_MAX longに格納できる最大値(C90準拠) (3-2-5) LONG_MIN longに格納できる最小値(C90準拠) (3-2-6) ULONG_MAX unsigned longに格納できる最大値(C90準拠) (3-2-7) CHAR_BIT char型のビット数(C90準拠) 整数型の最大値・最小値・ビット数を,これらのシンボルにマクロに定義する. これらのマクロは,C90に準拠したものである.開発環境にC90に準拠した limits.hが用意されている場合には,これらのマクロを定義することに代えて, limits.hをインクルードすればよい. 3.3 サイズの指定された整数型,その最大値・最小値,整数定数を作るマクロ (3-3-1) int8_t 符号付き8ビット整数(オプション,C99準拠) (3-3-2) uint8_t 符号無し8ビット整数(オプション,C99準拠) (3-3-3) int16_t 符号付き16ビット整数(C99準拠) (3-3-4) uint16_t 符号無し16ビット整数(C99準拠) (3-3-5) int32_t 符号付き32ビット整数(C99準拠) (3-3-6) uint32_t 符号無し32ビット整数(C99準拠) (3-3-7) int64_t 符号付き64ビット整数(オプション,C99準拠) (3-3-8) uint64_t 符号無し64ビット整数(オプション,C99準拠) (3-3-9) int128_t 符号付き128ビット整数(オプション,C99準拠) (3-3-10) uint128_t 符号無し128ビット整数(オプション,C99準拠) (3-3-11) int_least8_t 8ビット以上の符号付き整数(C99準拠) (3-3-12) uint_least8_t 8ビット以上の符号無し整数(C99準拠) (3-3-13) size_t メモリ領域のサイズを表す符号無し整数(C90準拠) (3-3-14) intptr_t ポインタを格納できるサイズの符号付き整数(C99準拠) (3-3-15) uintptr_t ポインタを格納できるサイズの符号無し整数(C99準拠) (3-3-16) INT8_MAX int8_tに格納できる最大値(オプション,C99準拠) (3-3-17) INT8_MIN int8_tに格納できる最小値(オプション,C99準拠) (3-3-18) UINT8_MAX uint8_tに格納できる最大値(オプション,C99準拠) (3-3-19) INT16_MAX int16_tに格納できる最大値(C99準拠) (3-3-20) INT16_MIN int16_tに格納できる最小値(C99準拠) (3-3-21) UINT16_MAX uint16_tに格納できる最大値(C99準拠) (3-3-22) INT32_MAX int32_tに格納できる最大値(C99準拠) (3-3-23) INT32_MIN int32_tに格納できる最小値(C99準拠) (3-3-24) UINT32_MAX uint32_tに格納できる最大値(C99準拠) (3-3-25) INT64_MAX int64_tに格納できる最大値(オプション,C99準拠) (3-3-26) INT64_MIN int64_tに格納できる最小値(オプション,C99準拠) (3-3-27) UINT64_MAX uint64_tに格納できる最大値(オプション,C99準拠) (3-3-28) INT128_MAX int128_tに格納できる最大値(オプション,C99準拠) (3-3-29) INT128_MIN int128_tに格納できる最小値(オプション,C99準拠) (3-3-30) UINT128_MAX uint128_tに格納できる最大値(オプション,C99準拠) (3-3-31) INT_LEAST8_MAX int_least8_tに格納できる最大値(C99準拠) (3-3-32) INT_LEAST8_MIN int_least8_tに格納できる最小値(C99準拠) (3-3-33) UINT_LEAST8_MAX uint_least8_tに格納できる最大値(C99準拠) (3-3-34) INT8_C(val) int_least8_t型の定数を作るマクロ(C99準拠) (3-3-35) UINT8_C(val) uint_least8_t型の定数を作るマクロ(C99準拠) (3-3-36) INT16_C(val) int16_t型の定数を作るマクロ(C99準拠) (3-3-37) UINT16_C(val) uint16_t型の定数を作るマクロ(C99準拠) (3-3-38) INT32_C(val) int32_t型の定数を作るマクロ(C99準拠) (3-3-39) UINT32_C(val) uint32_t型の定数を作るマクロ(C99準拠) (3-3-40) INT64_C(val) int64_t型の定数を作るマクロ(オプション,C99準拠) (3-3-41) UINT64_C(val) uint64_t型の定数を作るマクロ(オプション,C99準拠) (3-3-42) INT128_C(val) int128_t型の定数を作るマクロ(オプション,C99準拠) (3-3-43) UINT128_C(val) uint128_t型の定数を作るマクロ(オプション,C99準拠) 指定されたサイズの整数型を,これらのシンボルに型定義する.また,データ 型に格納できる最大値・最小値と,整数定数を作るマクロを,これらのシンボ ルにマクロ定義する. size_t型は,C90に準拠したものである.C90準拠のC言語環境では,size_tの定 義はstddef.h等に含まれているため,これをインクルードしてもよい. その他のデータ型およびマクロは,C99に準拠したものである.開発環境にC99 に準拠したstdint.hが用意されている場合には,これらのデータ型およびマク ロを定義することに代えて,stdint.hをインクルードすればよい. 上でオプションと記述したものは,該当するデータ型がコンパイラでサポート されている場合にのみ定義することを示す. 3.4 サイズの指定された浮動小数点型,その最大値・最小値のマクロ (3-4-1) float32_t IEEE754準拠の32ビット単精度浮動小数点数(オプ ション) (3-4-2) double64_t IEEE754準拠の64ビット倍精度浮動小数点数(オプ ション) (3-4-3) FLOAT32_MIN float32_tに格納できる最小の正規化された正の浮 動小数点数(オプション) (3-4-4) FLOAT32_MAX float32_tに格納できる表現可能な最大の有限浮動 小数点数(オプション) (3-4-5) DOUBLE64_MIN double64_tに格納できる最小の正規化された正の浮 動小数点数(オプション) (3-4-6) DOUBLE64_MAX double64_tに格納できる表現可能な最大の有限浮動 小数点数(オプション) 指定されたサイズ・表現形式の浮動小数点型を,これらのシンボルに型定義す る.また,データ型に格納できる最大値・最小値を,これらのシンボルにマク ロ定義する. いずれも,該当するデータ型がコンパイラでサポートされている場合にのみ定 義する. 3.5 コンパイラの拡張機能のためのマクロ定義 コンパイラの拡張機能を用いるためのマクロとして,必要に応じて,以下のマ クロの定義を含める. (3-5-1) inline(オプション,デフォルトは未定義) (3-5-2) Inline(オプション,デフォルトはstatic inline) インライン関数であることを示す指定.Inlineは,コンパイル単位にローカル なインライン関数であることを示す. (3-5-3) asm(オプション,デフォルトは未定義) (3-5-4) Asm(オプション,デフォルトは未定義) インラインアセンブラを記述するための指定.Asmは,最適化により削除しては ならないことを示す.これらは,ターゲット依存部でのみ使うマクロであるた め,ターゲット依存部で使わないなら定義する必要はない. (3-5-5) offsetof(structure, field)(オプション,デフォルトの定義あり) 構造体structureの中での,フィールドfieldのオフセットを求めるマクロ. C90準拠のC言語環境では,offsetofの定義はstddef.hに含まれているため,こ れをインクルードしてもよい. (3-5-6) alignof(type)(オプション,デフォルトの定義あり) データ型typeのアラインメント単位を求めるマクロ. (3-5-7) NoReturn(オプション,デフォルトは未定義) リターンすることのない関数であることを示す指定.これは,ターゲット依存 部のみ使うマクロであるため,ターゲット依存部で使わないなら定義する必要 はない. 3.6 標準的な定義の上書き t_stddef.hに含まれるTOPPERS共通定義の標準的な定義を上書きする場合には, 以下のマクロを定義する. (3-6-1) TOPPERS_bool(オプション,デフォルトはint) (3-6-2) TOPPERS_fp(オプション,デフォルトは他と互換性のない関数ポインタ) それぞれ,bool_t,FPに型定義すべきデータ型. (3-6-3) UINT_C(val)(オプション,デフォルトはUを付加) (3-6-4) ULONG_C(val)(オプション,デフォルトはULを付加) それぞれ,unsigned uint型,unsigned long型の定数を作るためのマクロ. (3-6-5) NULL(オプション,デフォルトは0) C90準拠のC言語環境では,NULLの定義はstddef.hに含まれているため,これを インクルードしてもよい. (3-6-6) ERCD(mercd, sercd)(オプション) (3-6-7) MERCD(ercd)(オプション) (3-6-8) SERCD(ercd)(オプション) ERCD,MERCD,SERCDの標準の定義は,符号付き整数が2の補数で表現されており, 右シフト演算子(>>)が算術シフトされることを仮定している.多くのコンパ イラでこの仮定が成り立つが,そうでない場合には,ターゲット依存部でこれ らの定義を上書きする必要がある. (3-6-9) ALIGN_TYPE(addr, type)(オプション) アドレスaddrが,データ型typeのアラインメント単位にアラインしているか チェックするマクロ. 3.7 アサーションのための定義 t_stddef.hには,assertの定義が含まれる.assertが失敗した場合(assertの パラメータがfalseになった場合)の処理を,ターゲット依存に用意する必要が ある.これらの定義は,assertマクロを使用する前であれば,t_stddef.h以降 にインクルードされるファイルに含まれていてもよい.なお,assertを無効に する(NDEBUGをマクロ定義してコンパイルする)場合には,これらを用意する 必要はない. (3-7-1) TOPPERS_assert_abort(void) assertが失敗した場合に,プログラムを停止させる関数.システム開発中はデ バッガに落とすのが理想的である.システム稼働時には例外処理を行わせるこ とになる. (3-7-2) TOPPERS_assert_fail(exp, file, line) assertが失敗した時の情報を表示/記録するためのマクロ.システムログ機能を 用いる場合には,t_syslog.hにシステムログ機能に記録するための定義が含ま れているので,ターゲット依存部で用意する必要はない. 4.システムインタフェースレイヤ(SIL)のターゲット依存部 システムインタフェースレイヤ(SIL,sil.h)のターゲット依存部の定義は, target_sil.hまたはそこからインクルードされるファイル(開発環境依存部/ プロセッサコア依存部/チップ依存部で用意されるヘッダファイルなど)に含 める. SILのサービスコールは,任意のシステム状態で呼び出すことができる.そのた め,SILのターゲット依存部の関数は,任意のシステム状態で呼び出せるように 実装しなければならない. 4.1 全割込みロック状態の管理 SILのターゲット依存部では,全割込みロック状態へ遷移する機能と,元の状態 へ戻す機能(元の状態を記憶するために変数を使う)を提供する.全割込みロッ ク状態であるかを判別する機能は提供する必要がない. SILの機能は,カーネルを使用しない場合にも使用できる必要がある.そのため, 全割込みロック状態への遷移と元の状態への復帰は,カーネルを用いず,プロ セッサのリソースを直接操作することによって実現する.また,全割込みロッ ク状態への遷移と元の状態への復帰は,全割込みロック状態やCPUロック状態で も行える必要がある. 保護機能を持ったカーネルでは,ユーザタスクからプロセッサのリソースを直 接操作することができないため,ユーザタスクからはこれらの機能を用いるこ とができない.用いた場合の振舞いはターゲットプロセッサに依存するが,典 型的には,特権命令違反などのCPU例外が発生することになる. (4-1-1) SIL_PRE_LOC 全割込みロックフラグの状態を保存するための変数を定義するマクロ.型名の 後に,変数名を続けたものに定義する.変数名は,他の名前と衝突しないよう に,"TOPPERS_"で始まる名前にする. (4-1-2) SIL_LOC_INT() 現在の全割込みロックフラグの状態をSIL_PRE_LOCで定義した変数に保存し,全 割込みロック状態に遷移させるマクロ.このマクロを実現する際には,「1.5 クリティカルセクションの出入処理の実現に関する制約」の節に記述されてい る制約に従わなければならない. (4-1-3) SIL_UNL_INT() SIL_LOC_INT()によって変数に保存した状態に戻すマクロ.このマクロを実現す る際には,「1.5 クリティカルセクションの出入処理の実現に関する制約」の 節に記述されている制約に従わなければならない. 4.2 微少時間待ち (4-2-1) void sil_dly_nse(ulong_t dlytim) dlytimで指定された以上の時間(単位はナノ秒),ループなどによって待つ関 数. 以下の関数と等価な処理を,アセンブリ言語で記述する方法を,標準的な実装 方法とする.アセンブリ言語で記述するのは,コンパイラの最適化に依存しな いようにするためである.またこの関数は,キャッシュ等の影響を受けないよ うに,できる限りメモリアクセスを行わないように実装すべきである. void sil_dly_nse(ulong_t dlytim) { dlytim -= SIL_DLY_TIM1; if (結果が0より大きい) { do { dlytim -= SIL_DLY_TIM2; } while (結果が0より大きい); } } この関数の動作は次の通りである.dlytimがSIL_DLY_TIM1以下の場合には,最 初のif文の条件が成立せず,すぐに関数から抜ける.dlytimがSIL_DLY_TIM1よ り大きく,(SIL_DLY_TIM1+SIL_DLY_TIM2)以下の場合には,最初のif文の条件は 成立するが,doループは1回も回らずに関数から抜ける.dlytimが (SIL_DLY_TIM1+SIL_DLY_TIM2)より大きく,(SIL_DLY_TIM1+SIL_DLY_TIM2*2)以 下の場合には,doループを1回だけ回って関数から抜ける.その後,dlytimが SIL_DLY_TIM2大きくなる度に,whileループを回る回数が1回ずつ増える. なお,この関数をアセンブリ言語(または,C言語)で記述する場合,どのファ イルに記述するかが問題になる.SILのターゲット依存部には,標準では,アセ ンブリ言語(または,C言語)の関数定義を記述するためのファイルを用意して いない.ターゲット依存で用意してもよいが,例外的に,カーネル実装のター ゲット依存モジュール(target_support.Sまたはtarget_kernel_impl.c)に記 述してもよいことにする. (4-2-2) SIL_DLY_TIM1(オプション) (4-2-3) SIL_DLY_TIM2(オプション) sil_dly_nseを上記の標準的な方法で実現した場合,この2つの定数をターゲッ ト依存部でマクロ定義する. SIL_DLY_TIM2は,上記の関数において,doループ1回の実行時間(単位はナノ秒) に設定する.ターゲットプロセッサの命令セットにもよるが,おおよそ,減算 命令と条件分岐命令各1回の実行時間になる.SIL_DLY_TIM2が決まれば,関数呼 出しも含めた全体の時間がdlytimで指定された以上の時間になるように, SIL_DLY_TIM1を決める. この2つの定数値の決定を支援するプログラムとして,testディレクトリに, test_dlynseを用意している.test_dlynseを実行すると,次のような出力が得 られる. -- for fitting parameters -- sil_dly_nse(0): 430 OK sil_dly_nse(420): 430 OK sil_dly_nse(510): 520 OK sil_dly_nse(600): 610 OK <中略> -- for checking boundary conditions -- sil_dly_nse(421): 520 OK sil_dly_nse(511): 610 OK sil_dly_nse(601): 700 OK "for fitting parameters"に続く出力は,sil_dly_nse(dlytim)を呼び出した場 合の待ち時間を測定した結果である.このプログラムを用いて,":"の右側の数 値が,dlytimよりも大きい範囲でなるべく近い値になるように,2つの定数値を 調整する."for checking boundary conditions"に続く出力は,プログラムの 妥当性をチェックするためのもので,":"の右側の数値が,dlytimよりも大きい ことを確認する(近い値になる必要はない). 4.3 プロセッサのエンディアン (4-3-1) SIL_ENDIAN_BIG (4-3-2) SIL_ENDIAN_LITTLE プロセッサのエンディアンにより,いずれか片方のシンボルをマクロ定義する. (4-3-3) TOPPERS_SIL_REV_ENDIAN_UINT16(オプション) (4-3-4) TOPPERS_SIL_REV_ENDIAN_UINT32(オプション) それぞれ,16ビット,32ビットの符号無し整数のエンディアンを反転させるマ クロ.プロセッサがエンディアン反転のための命令を持つ場合には,その命令 を用いて実現する.これらのシンボルをマクロ定義しない場合には,デフォル トの定義が使われる. 4.4 メモリ空間アクセス関数 (4-4-1) TOPPERS_OMIT_SIL_ACCESS 標準のメモリ空間アクセス関数を使用せず,ターゲット依存部で用意する場合 には,このシンボルをマクロ定義する. (4-4-2) TOPPERS_OMIT_SIL_REH_LEM (4-4-3) TOPPERS_OMIT_SIL_WRH_LEM (4-4-4) TOPPERS_OMIT_SIL_REH_BEM (4-4-5) TOPPERS_OMIT_SIL_WRH_BEM (4-4-6) TOPPERS_OMIT_SIL_REW_LEM (4-4-7) TOPPERS_OMIT_SIL_WRW_LEM (4-4-8) TOPPERS_OMIT_SIL_REW_BEM (4-4-9) TOPPERS_OMIT_SIL_WRW_BEM それぞれ,標準のsil_reh_lem,sil_wrh_lem,sil_reh_bem,sil_wrh_bem, sil_rew_lem,sil_wrw_lem,sil_rew_bem,sil_wrw_bemを使用せず,ターゲッ ト依存部で用意する場合には,これらのシンボルをマクロ定義する. 4.5 I/O空間アクセス関数 メモリ空間とは別にI/O空間を持つプロセッサでは,I/O空間にあるデバイスレ ジスタをアクセスするための関数として,sil_reb_iop,sil_wrb_iop, sil_reh_iop,sil_wrh_iop,sil_reh_lep,sil_wrh_lep,sil_reh_bep, sil_wrh_bep,sil_rew_iop,sil_wrw_iop,sil_rew_lep,sil_wrw_lep, sil_rew_bep,sil_wrw_bepの中で必要なものを,ターゲット依存部で用意する. 5.カーネルAPIのターゲット依存部 カーネルAPI(kernel.h)のターゲット依存部の定義は,target_kernel.hまた はそこからインクルードされるファイル(開発環境依存部/プロセッサコア依 存部/チップ依存部で用意されるヘッダファイルなど)に含める. 5.1 ターゲット定義でサポートする機能 (5-1-1) TOPPERS_TARGET_SUPPORT_DIS_INT dis_intをサポートする (5-1-2) TOPPERS_TARGET_SUPPORT_ENA_INT ena_intをサポートする dis_int,ena_intをサポートする場合に,それぞれのシンボルをマクロ定義す る. 5.2 割込み優先度の範囲 (5-2-1) TMIN_INTPRI 割込み優先度の最小値(最高値) (5-2-2) TMAX_INTPRI 割込み優先度の最大値(最低値) それぞれ,カーネル管理の割込み優先度の最小値(=優先度が最高),カーネ ル管理の割込み優先度の最大値(優先度が最低)に定義する.TMAX_INTPRIは-1 に固定されているが,対称性のために,ターゲット依存部で定義することにし ている. 5.3 高分解能タイマのタイマ周期とカウント値の進み幅 高分解能タイマドライバに関して,アプリケーションから参照できるマクロを 定義する.高分解能タイマドライバの詳細に関しては,「6.13 高分解能タイマ ドライバ」の節を参照すること. (5-3-1) TCYC_HRTCNT 高分解能タイマのタイマ周期 高分解能タイマのタイマ周期を,このマクロに定義する.タイマ周期が2^32の 場合には,このマクロを定義しない. (5-3-2) TSTEP_HRTCNT 高分解能タイマのカウント値の進み幅 高分解能タイマのカウント値の進み幅を,このマクロに定義する.例えば,高 分解能タイマが,2マイクロ秒毎に2ずつカウントアップする場合には, TSTEP_HRTCNTを2に定義する. 5.4 メモリ領域確保のための型定義 (5-4-1) TOPPERS_STK_T スタック領域を確保するための型(オプション) (5-4-2) TOPPERS_MPF_T 固定長メモリプール領域を確保するための型(オプション) スタック領域と固定長メモリプール領域は,標準ではintptr_t型の配列として 確保するが,より大きい単位でアラインさせたいなどの理由でそれ以外の型の 配列として確保する場合には,それぞれTOPPERS_STK_TとTOPPERS_MPF_Tを,配 列のベースとなるデータ型にマクロ定義する. 5.5 ビットパターンのビット数 (5-5-1) TBIT_FLGPTN イベントフラグのビット数(オプション) TBIT_FLGPTNの標準の定義では,整数型の有効ビット数が,その型のsizeofに CHAR_BITを乗じたものと一致していることを仮定している.多くのコンパイラ でこの仮定が成り立つが,そうでない場合には,ターゲット依存部でこれらの 定義を上書きする必要がある.ただし,これらの値は16以上でなければならな い. 5.6 メモリ領域確保のためのマクロ (5-6-1) TOPPERS_ROUND_SZ(オプション) (5-6-2) TOPPERS_COUNT_SZ(オプション) TOPPERS_COUNT_SZ(sz, unit)は,sz/unitを切り上げた値を求めるマクロで,サ イズがszのメモリ領域をサイズがunitのデータ型の配列で確保する場合の要素 数を求めるために用いる.TOPPERS_ROUND_SZ(sz, unit)は,sz/unitを切り上げ たものにunitをかけた値を求めるマクロで,サイズがszのメモリ領域をサイズ がunitのデータ型の配列で確保する場合のトータルサイズを求めるために用い る. それぞれ,標準のTOPPERS_ROUND_SZ,TOPPERS_COUNT_SZが適切でなく,ターゲッ ト依存部で用意する場合には,これらのシンボルを適切な値にマクロ定義する. 5.7 オーバランハンドラ機能拡張のための定義(オプション) オーバランハンドラ機能拡張パッケージをサポートする(使用できるようにす る)場合には,次の3つを実施することが必要である. ・この節で説明する定義を行う. ・6章に示すコード中で,TOPPERS_SUPPORT_OVRHDRがマクロ定義されている場  合にのみ有効となるコードを実装する. ・オーバランタイマドライバを用意する.オーバランタイマドライバについて  は,「6.14 オーバランタイマドライバ」の節を参照すること. (5-7-1) TOPPERS_TARGET_SUPPORT_OVRHDR オーバランハンドラ機能拡張パッケージをサポートする場合には,このシンボ ルをマクロ定義する. (5-7-2) TMAX_OVRTIM(オプション,デフォルトはUINT32_MAX) プロセッサ時間としてオーバランタイマに設定できる最大値(単位はマイクロ 秒)にマクロ定義する. 6.カーネル実装のターゲット依存部 【TOPPERS/ASP1カーネルとの関係】 ASP1カーネルでは,カーネル実装のターゲット依存部を構成する関数を,タス クコンテキスト専用(t_で始まるもの),非タスクコンテキスト専用(i_で始 まるもの),いずれのコンテキストからでも呼び出すことができるもの(x_で 始まるもの)に分けていたが,ASP3カーネルでは分けないことにした. 6.1 カーネル実装のターゲット依存部の共通事項 カーネル実装のターゲット依存部は,以下の要素で構成される. (a) カーネル実装のターゲット依存の定義 カーネル実装のターゲット非依存部から参照されるターゲット依存の定義は, target_kernel_impl.hまたはそこからインクルードされるファイル(開発環境 依存部/プロセッサコア依存部/チップ依存部で用意されるヘッダファイルな ど)に含める. ターゲットのハードウェア資源(割込みハンドラ番号やCPU例外ハンドラ番号, デバイスレジスタの番地など)の定義は,システムサービスやアプリケーショ ンにも有用であるため,カーネル実装のみに有用な定義を含むファイルとは切 り分けて,独立したヘッダファイルに含める.このヘッダファイルの標準的な 名称を,システム略称.h(または,チップ略称.h,プロセッサ略称.h)とする. (b) カーネル実装のターゲット依存モジュール カーネル実装のターゲット依存の変数定義や関数を含むモジュール.C言語で記 述される部分をtarget_kernel_impl.c,アセンブリ言語で記述される部分を target_support.Sに含める.開発環境依存部/プロセッサコア依存部/チップ 依存部を切り分けることや,ファイルが大きくなる場合に複数のファイルに分 割することも可能である. (c) カーネル実装のターゲット依存部のためのリネーム記述 カーネル実装のターゲット依存部の変数名や関数名を,先頭に_kernel_を付与 した名前にリネームするためのモジュール.target_rename.defを用意し,ツー ル(utils/genrename)により,target_rename.hとtarget_unrename.hを生成す る.開発環境依存部/プロセッサコア依存部/チップ依存部を切り分ける場合 には,リネーム記述も切り分ける. (d) タイマドライバ カーネルがシステム時刻の更新に用いるため高分解能タイマを抽象化するため の高分解能タイマドライバのヘッダファイル,実装ファイル,システムコンフィ ギュレーションファイルを,それぞれ,target_timer.h,target_timer.c, target_timer.cfgに含める.開発環境依存部/プロセッサコア依存部/チップ 依存部を切り分けることも可能である. また,オーバランハンドラ機能拡張パッケージをサポートする場合には,オー バランハンドラを起動するためのオーバランタイマドライバも,同じファイル に含める. なお,この章に示すコード中で,TOPPERS_SUPPORT_OVRHDRがマクロ定義されて いる場合にのみ有効となるコードは,オーバランハンドラ機能拡張パッケージ をサポートしない場合には,実装する必要がない. (e) コンフィギュレータ設定ファイル コンフィギュレータの設定ファイルのターゲット依存部を,target_def.csv, target.tf,target_check.tfに用意する.コンフィギュレータ設定ファイルの 記述方法については,7章で説明する. 6.2 トレースログ機能への対応 カーネルのトレースログ機能の中で,ディスパッチャ,割込みハンドラ,CPU例 外ハンドラの開始・終了のトレースログ取得は,ターゲット依存部で実装する 必要がある.ほとんどのターゲットシステムにおいて,それらの処理はアセン ブリ言語で記述されており,ターゲット非依存部向けのトレースログマクロと 同じ方法(トレースログマクロを,トレースログ取得処理のC言語記述にマクロ 定義する方法)は,用いることができない. そこで,アセンブリ言語で記述されている処理中にトレースログ取得を埋め込 む場合には,トレースログマクロが定義されていれば,それが何に定義されて いるかは無視して,標準的なトレースログ関数がC言語で記述されていると想定 して,それを呼び出すようにコーディングする. 具体的には,下の表の左側に示したトレースログマクロが定義されていれば, 表の右側に示したC言語記述と同等の処理を行うようにコーディングする. トレースログマクロ トレースログ取得処理 ----------------------------------------------- LOG_DSP_ENTER log_dsp_enter(p_runtsk) LOG_DSP_LEAVE log_dsp_leave(p_runtsk) LOG_INH_ENTER log_inh_enter(inhno) LOG_INH_LEAVE log_inh_leave(inhno) LOG_EXC_ENTER log_exc_enter(excno) LOG_EXC_LEAVE log_exc_leave(excno) 6.3 システム状態の管理 ASP3カーネルを新たなターゲットシステムにポーティングする際に,最も重要 な作業は,カーネルが定義するシステム状態を,ハードウェア(プロセッサ) 上でどのように実現するかである.以下の説明は,TOPPERS新世代カーネルにお けるシステム状態の定義・意味を知っていることを前提に記述している. 6.3.1 全割込みロック状態の管理 全割込みロック状態は,NMIを除くすべての割込みをマスクした状態である.全 割込みロック状態を管理する機能は,システムインタフェースレイヤ(SIL)に よって提供され,カーネルは全割込みロック状態を管理しない. 全割込みロック状態では,sns_kerとext_ker以外のカーネルのサービスコール を呼ぶことはできないものとしており,呼んだ場合には何が起こるか保証して いない.sns_kerとext_kerから呼び出す処理は,トレースログ取得処理とSILの サービスコールを除くと,call_exit_kernelのみである.そのため, call_exit_kernelから呼び出すものを除いて,カーネルのターゲット依存部の 関数が,全割込みロック状態で呼び出される状況は考える必要がない. 6.3.2 コンテキストの管理 処理単位が実行されるコンテキストは,タスクコンテキストと非タスクコンテ キストに分類される. ターゲット依存部は,実行中の処理単位が,タスクコンテキストで実行されて いるか非タスクコンテキストで実行されているかを判別する機能を提供する. また,CPU例外が発生したコンテキストについて判別する機能を提供する. ターゲット依存部では,割込みハンドラとCPU例外ハンドラの入口処理で非タス クコンテキストに切り換え,それらの出口処理で元のコンテキストに戻す. (6-3-2-1) bool_t sense_context(void) 実行中の処理単位が,タスクコンテキストで実行されている場合にはfalse,非 タスクコンテキストで実行されている場合にはtrueを返す関数.この関数は, CPUロック状態でもCPUロック解除状態でも呼び出せるように実装しなければな らない. 6.3.3 CPUロック状態の管理 ターゲット依存部は,CPUロック状態へ遷移する機能,CPUロック解除状態へ遷 移する機能,CPUロック状態であるかを判別する機能を提供する. (6-3-3-1) void lock_cpu(void) CPUロック解除状態から,CPUロック状態へ遷移させる関数.この関数は,CPUロッ ク状態で呼び出されることはなく,呼び出された場合の動作は保証する必要が ない. この関数を実現する際には,「1.5 クリティカルセクションの出入処理の実現 に関する制約」の節に記述されている制約に従わなければならない. (6-3-3-2) void lock_cpu_dsp(void) タスクディスパッチできる状態において,CPUロック解除状態から,CPUロック 状態へ遷移させる関数. この関数は,ディスパッチできる状態でのみ呼び出される.ディスパッチでき る状態においては,割込み優先度マスク全解除状態であるため,プロセッサに よっては,lock_cpuより効率的に実装できる場合がある.そうでない場合には, lock_cpuに定義すればよい. lock_cpu_dspによってCPUロック状態に遷移した後,unlock_cpuによってCPUロッ ク状態を解除する場合がある.そのため,lock_cpuでCPUロック状態に遷移する 前の状態を変数に保存する場合には,lock_cpu_dspでもその変数を設定する必 要がある. (6-3-3-3) void unlock_cpu(void) CPUロック状態から,CPUロック解除状態へ遷移させる関数.この関数は,CPUロッ ク解除状態で呼び出されることはなく,呼び出された場合の動作は保証する必 要がない. タスクコンテキストでCPUロック状態に遷移した場合には,CPUロック解除状態 に戻るのはタスクコンテキストに限られ,非タスクコンテキストでCPUロック解 除状態に戻ることはない.同様に,非タスクコンテキストでCPUロック状態に遷 移した場合には,CPUロック解除状態に戻るのは非タスクコンテキストに限られ, タスクコンテキストでCPUロック解除状態に戻ることはない. これらの関数を実現する際には,「1.5 クリティカルセクションの出入処理の 実現に関する制約」の節に記述されている制約に従わなければならない. (6-3-3-4) void unlock_cpu_dsp(void) タスクディスパッチできる状態に戻る状況において,CPUロック状態から,CPU ロック解除状態へ遷移させる関数. この関数は,CPUロック解除後は,ディスパッチできる状態に戻る状況でのみ呼 び出される.ディスパッチできる状態においては,割込み優先度マスク全解除 状態であるため,プロセッサによっては,unlock_cpuより効率的に実装できる 場合がある.そうでない場合には,unlock_cpuに定義すればよい. (6-3-3-5) bool_t sense_lock(void) 現在のシステム状態が,CPUロック状態の場合はtrue,CPUロック解除状態の場 合にはfalseを返す関数. この関数が全割込みロック状態で呼び出される状況は考える必要がないことか ら,全割込みロック状態とCPUロック状態を区別できる必要はない.NMI以外に カーネルの管理外の割込みを設けない場合には,全割込みロック状態とCPUロッ ク状態が全く同一の状態でもかまわない. (6-3-3-6) void delay_for_interrupt(void) 割込みが受け付けられるように処理を遅延させる関数. カーネル内で,CPUロック状態での実行が長くなる場合に,一時的にCPUロック 状態を解除して,割込みを受け付けるようにしている.この時,unlock_cpuと lock_cpuをこの順で呼び出すが,この2つの関数を連続して呼び出すと,ターゲッ トによっては割込みが受け付けられない場合がある.そこで,unlock_cpuと lock_cpuを呼び出す間に,この関数(delay_for_interrupt)を呼び出す.2つ の関数を連続して呼び出すと割込みが受け付けられないターゲットでは,この 関数により,割込みが受け付けられるように実装する. 6.4 割込みに関連するシステム状態の管理 割込み番号と割込みハンドラ番号はターゲット定義で付与されるため,それら が有効な値かどうかを判断する機能は,ターゲット依存部で用意する必要があ る. (6-4-0-1) bool_t VALID_INTNO(INTNO intno) intnoが,割込み番号として有効な値である場合にtrue,そうでない場合に falseを返すマクロ. VALID_INTNO_DISINT,VALID_INTNO_CREISRを個別に定義し,ターゲット依存部 でもこのマクロを使用しない場合には,用意する必要がない. (6-4-0-2) bool_t VALID_INHNO(INHNO inhno)(オプション) inhnoが,割込みハンドラ番号として有効な値である場合にtrue,そうでない場 合にfalseを返すマクロ.なお,ASP3カーネルでは,割込みハンドラ番号を用い るAPIは,DEF_INHのみである. ASP3カーネルのターゲット非依存部では,このマクロは使われていないため, ターゲット依存部でも使用しない場合には,用意する必要がない. 6.4.1 割込み優先度マスクの管理 ターゲット依存部は,割込み優先度マスクを設定する機能と,割込み優先度マ スクを参照する機能を提供する. (6-4-1-1) bool_t VALID_INTPRI_CHGIPM(PRI intpri)(オプション) intpriが,chg_ipmに対する割込み優先度として有効な値である場合にtrue,そ うでない場合にfalseを返すマクロ.標準では,TMIN_INTPRI以上,TIPM_ENAALL (=0)以下の値がchg_ipmに対する割込み優先度として有効であるが,ターゲッ ト依存部でこのマクロを定義することで,TMIN_INTPRIよりも小さい値を有効と することができる(有効な値の範囲を狭めてはならない). (6-4-1-2) void t_set_ipm(PRI intpri) 割込み優先度マスクの値をintpriに設定する関数. この関数は,ターゲット非依存部からは,タスクコンテキストで,CPUロック状 態の場合にのみ呼び出される. また,この関数は,VALID_INTPRI_CHGIPM(intpri)がtrueを返すintpriに対して のみ呼ばれる.intpriにそうでない値が渡された場合の動作は保証する必要が ない. (6-4-1-3) PRI t_get_ipm(void) 割込み優先度マスクの値を参照して返す関数. この関数は,ターゲット非依存部からは,タスクコンテキストで,CPUロック状 態の場合にのみ呼び出される. 割込み優先度マスクを用いてカーネル管理の割込みをすべてマスクした状態は, CPUロック状態と区別できることが必要である.具体的には,CPUロック解除状 態において,t_set_ipmを用いてカーネル管理の割込みをすべてマスクした場合 でも,sense_lockはfalseを返す. それに対して,割込み優先度マスクを用いてNMIを除くすべての割込みをマスク できる場合,その状態と全割込みロック状態を区別できる必要はなく,全く同 一の状態でもかまわない. 6.4.2 割込み要求禁止フラグの管理 ターゲット依存部は,割込み要求禁止フラグをセットする機能とクリアする機 能を提供する. (6-4-2-1) bool_t VALID_INTNO_DISINT(INTNO intno)(オプション) intnoが,dis_int/ena_intに対する割込み番号として有効な値である場合に true,そうでない場合にfalseを返すマクロ.割込み要求禁止フラグがセット/ クリアできないintnoに対しては,このマクロがfalseを返すようにする. このマクロを定義しない場合,VALID_INTNOが使われる.VALID_INTNOで有効と 判断される割込み番号が,dis_int/ena_intに対して有効な割込み番号と一致 している場合,このマクロを用意する必要はない. (6-4-2-2) bool_t disable_int(INTNO intno) intnoで指定された割込み要求ラインに対する割込み要求禁止フラグをセットし, trueを返す関数.指定された割込み要求ラインに対して,割込み属性が設定さ れていない場合には,falseを返す. この関数は,ターゲット非依存部がCPUロック解除状態で呼び出すことはないた め,CPUロック解除状態で呼び出された場合の動作は保証する必要がない.ただ し,ターゲット依存部からCPUロック解除状態で呼び出す場合には,保証する必 要がある. また,この関数は,VALID_INTNO_DISINT(intno)がtrueとなるintnoに対しての み呼ばれる.intnoにそうでない値が渡された場合の動作は保証する必要がない. dis_intサービスコールをサポートする場合(TOPPERS_SUPPORT_DIS_INTをマク ロ定義する場合)には,disable_intが用意されていなければならない. (6-4-2-3) bool_t enable_int(INTNO intno) intnoで指定された割込み要求ラインに対する割込み要求禁止フラグをクリアし, trueを返す関数.指定された割込み要求ラインに対して,割込み属性が設定さ れていない場合には,falseを返す. この関数は,ターゲット非依存部がCPUロック解除状態で呼び出すことはないた め,CPUロック解除状態で呼び出された場合の動作は保証する必要がない.ただ し,ターゲット依存部からCPUロック解除状態で呼び出す場合には,保証する必 要がある. また,この関数は,VALID_INTNO_DISINT(intno)がtrueとなるintnoに対しての み呼ばれる.intnoにそうでない値が渡された場合の動作は保証する必要がない. ena_intサービスコールをサポートする場合(TOPPERS_SUPPORT_ENA_INTをマク ロ定義する場合)には,t_enable_intが用意されていなければならない. 6.4.3 割込み要求のクリア (6-4-3-1) void clear_int(INTNO intno) intnoで指定された割込み要求ラインがエッジトリガである場合に,トリガされ た割込み要求をクリアする関数.intnoで指定された割込み要求ラインがレベル トリガである場合には何もしない. ASP3カーネルのターゲット非依存部では,この関数を呼び出していないが,ター ゲット依存部やシステムサービスで呼び出す可能性が高いため,用意すること としている.そのため,この関数がどのようなシステム状態で呼び出せるかは, ターゲット依存部内で一貫していればよい. 6.4.4 割込み要求のプローブ (6-4-4-1) bool_t probe_int(INTNO intno) intnoで指定された割込み要求ラインに対して,割込みが要求されている場合に true,そうでない場合にfalseを返す関数. ASP3カーネルのターゲット非依存部では,この関数を呼び出していないが,ター ゲット依存部やシステムサービスで呼び出す可能性が高いため,用意すること としている.そのため,この関数がどのようなシステム状態で呼び出せるかは, ターゲット依存部内で一貫していればよい. 6.5 タスクディスパッチャ 6.5.1 タスクコンテキストブロックとタスク初期化コンテキストブロック (6-5-1-1) TSKCTXB ターゲット依存のタスクコンテキストを保存するために,TCB中に持つことが必 要なデータ構造の型を,TSKCTXBに定義する.標準的には,TSKCTXBには,タス クのスタックポインタと実行再開番地を格納する. (6-5-1-2) USE_TSKINICTXB(オプション) (6-5-1-3) TSKINICTXB(オプション) ターゲット依存の情報をタスク初期化ブロック(TINIB)に入れたい場合や, TINIB中のスタック領域のサイズと先頭番地の持ち方をターゲット依存に変更し たい場合には,USE_TSKINICTXBをマクロ定義し,TINIB中に持つことが必要なデー タ構造の型を,TSKINICTXBに定義する. USE_TSKINICTXBをマクロ定義すると,TINIB中にスタック領域とサイズと先頭番 地が含まれなくなるため,それに代わる情報をTSKINICTXB中に持つ必要がある. また,コンフィギュレータのパス2のテンプレートファイルのターゲット非依存 部で,TSKINICTXBの初期化情報を生成するためのGENERATE_TSKINICTXBを,パス 3のテンプレートファイルのターゲット非依存部で,TINIBからスタック領域の 先頭番地を取り出すためのGET_STK_TSKINICTXBを定義する必要がある. 6.5.2 ディスパッチャ本体 ディスパッチャ本体(dispatcher)は,ターゲット非依存部から直接呼び出さ れることはなく,カーネルのターゲット依存部の内部からのみ呼び出される. dispatcherは,タスクコンテキスト・CPUロック状態・割込み優先度マスク全解 除状態・ディスパッチ許可状態で呼び出される. dispatcherの処理内容は次の通り. ---------------------------------------- void dispatcher(void) { #ifdef LOG_DSP_ENTER log_dsp_enter(p_runtsk); #endif /* LOG_DSP_ENTER */ dispatcher_0: p_runtsk = p_schedtsk; if (p_runtsk != NULL) { 自タスク(p_runtsk)のTCBからスタックポインタを復帰する #ifdef LOG_DSP_LEAVE log_dsp_leave(p_runtsk); #endif /* LOG_DSP_LEAVE */ 自タスクのTCBから実行再開番地を復帰し,そこへ分岐する … (*a) } /* * アイドル処理 */ 割込みを許可したらCPUロック解除状態になるよう準備する 割込みをすべて許可する while (true) { 割込み発生を待つ … (*b) } } ---------------------------------------- (*b)において,割込み発生を待つ命令が用意されていない場合や,それを発行 するのが不都合な場合には,割込み発生を待つ処理を省き,whileループによっ て割込み発生を待つようにしても良い. 割込み待ちの間は,p_runtskをNULL(=0)に設定しなければならない(上の処 理内容をそのまま実装すればこうなる).このように設定しないと,割込みハ ンドラからget_tidを呼び出した際の動作が仕様に合致しなくなる. dispatcherをアセンブリ言語で記述する場合には,トレースログ取得処理は, 「6.2 トレースログ機能への対応」の節で記述した方法でコーディングするこ と.なお,log_dsp_enterは切換え前のタスクのスタックで,log_dsp_leaveは 切換え後のタスクのスタックで実行する. なお,dispatcherに分岐してきた時,スタックポインタは,最後に実行状態で あったタスクのスタックを指している.ただし,カーネル動作開始直後にアイ ドルになった時には,IDが1のタスクのスタックを指している. 【TOPPERS/ASP1カーネルとの関係】 アイドル処理の設計を一新した.詳しくは,「TOPPERS/ASP3カーネル 設計メモ」 の「アイドル処理」の節を参照すること. 6.5.3 自発的なディスパッチ (6-5-3-1) void dispatch(void) タスクコンテキストから呼ばれたサービスコール処理において,タスク切換え が必要になった場合には,タスクからの自発的なディスパッチ処理(dispatch) が呼び出される. dispatchは,タスクコンテキスト・CPUロック状態・割込み優先度マスク全解除 状態・ディスパッチ許可状態で呼び出される. dispatchの処理内容は次の通り. ---------------------------------------- void dispatch(void) { #ifdef TOPPERS_SUPPORT_OVRHDR ovrtimer_stop(); /* オーバランタイマの停止 */ #endif /* TOPPERS_SUPPORT_OVRHDR */ スクラッチレジスタ(*)を除くすべてのレジスタをスタックに保存する スタックポインタを自タスク(p_runtsk)のTCBに保存する dispatch_rを,実行再開番地として自タスクのTCBに保存する … (*a) dispatcherに分岐する dispatch_r: スクラッチレジスタを除くすべてのレジスタをスタックから復帰する #ifdef TOPPERS_SUPPORT_OVRHDR ovrtimer_start(); /* オーバランタイマの動作開始 */ #endif /* TOPPERS_SUPPORT_OVRHDR */ } ---------------------------------------- ここでスクラッチレジスタ(*)とは,関数呼出しにより保存されないレジスタの ことである.必要な場合には,関数を呼び出す側で保存しなければならないた め,caller saved registerと呼ばれる場合もある. dispatchを呼び出したタスクが次に実行される時には,実行再開番地として登 録したdispatch_rに戻ってくる.dispatch_rには,dispatcherのみから分岐し, その時の状態は,タスクコンテキスト・CPUロック状態・割込み優先度マスク全 解除状態・ディスパッチ許可状態である. (6-5-3-2) void request_dispatch(void) 非タスクコンテキストにおいてタスク切換えが必要になった場合には,非タス クコンテキストからの自発的なディスパッチ要求(request_dispatch)が呼び 出される. 割込みハンドラの出入口処理を,標準通りに実装する(dispatchを明示的に呼 び出す)場合には,request_dispatchでは何もする必要がない. 6.5.4 ディスパッチャの動作開始 (6-5-4-1) void start_dispatch(void) ディスパッチャの動作開始処理(start_dispatch)は,カーネル起動時に,カー ネルの初期化処理から呼び出される.start_dispatchは,リターンすることの ない関数である. start_dispatchは,非タスクコンテキストで,NMIを除くすべての割込みをマス クした状態(全割込みロック状態と同等の状態)で呼び出される. start_dispatch内で,タスクコンテキストに切り換え,CPUロック状態・割込み 優先度マスク全解除状態にしなければならない.また,スタックを,IDが1のタ スクのスタック領域に切り換える. start_dispatchの処理内容は次の通り. ---------------------------------------- void start_dispatch(void) { タスクコンテキストに切り換える スタックをIDが1のタスクのスタック領域に切り換える CPUロック状態・割込み優先度マスク全解除状態にする dispatcher_0に分岐する } ---------------------------------------- 6.5.5 現在のコンテキストを捨ててディスパッチ (6-5-5-1) void exit_and_dispatch(void) 自タスクを終了させるサービス処理からは,現在のコンテキストを捨ててディ スパッチする処理(exit_and_dispatch)が呼び出される.exit_and_dispatch は,リターンすることのない関数である. exit_and_dispatchは,タスクコンテキスト・CPUロック状態・割込み優先度マ スク全解除状態・ディスパッチ許可状態で呼び出される. exit_and_dispatchの処理内容は次の通り. ---------------------------------------- void exit_and_dispatch(void) { dispatcherに分岐する } ---------------------------------------- 6.5.6 タスクの起動準備 (6-5-6-1) void activate_context(TCB *p_tcb) タスクの起動準備処理(activate_context)は,タスクを休止状態から実行で きる状態にする時に呼ばれ,p_tcbで指定されたタスク(対象タスク)のTCB中 のスタックポインタを初期化し,実行再開番地をタスク開始時処理(start_r) に設定する.この時点では,後述する理由で,対象タスクのスタック領域を使っ てはならない. 対象タスクが最初に実行される時には,対象タスクを自タスクとして,実行再 開番地として登録したstart_rに分岐してくる.start_rには,dispatcherのみ から分岐し,その時の状態は,タスクコンテキスト・CPUロック状態・割込み優 先度マスク全解除状態・ディスパッチ許可状態である. start_rは,CPUロック状態を解除した後,タスクの起動番地を呼び出す.さら に,タスクの起動番地から戻ってきた場合には,ext_tskを呼び出す. activate_contextとstart_rの処理内容は次の通り. ---------------------------------------- void activate_context(TCB *p_tcb) { 指定されたタスク(p_tcb)のTCB中のスタックポインタを初期化する start_rを,実行再開番地として自タスクのTCBに保存する … (*a) return; start_r: #ifdef TOPPERS_SUPPORT_OVRHDR ovrtimer_start(); /* オーバランタイマの動作開始 */ #endif /* TOPPERS_SUPPORT_OVRHDR */ CPUロック解除状態にする 自タスク(p_runtsk)の起動番地を,拡張情報をパラメータとして呼び出す ext_tskに分岐する ... (*c) } ---------------------------------------- (*c)でext_tskを呼ぶ代わりに,自タスクの起動番地を呼び出す時の返り番地を ext_tskの番地としておく方法がある. ここで,タスクの起動処理において対象タスクのスタック領域を使ってはなら ない理由は,次の通り.制約タスク拡張パッケージにおいて,複数の制約タス クがスタック領域を共有している場合に,タスクの起動時点では,そのタスク とスタック領域を共有しているタスクが,スタック領域を使用している可能性 があるためである. このポーティングガイドでは,タスクの実行再開番地をTCBに保存している (*a).これをスタックに保存する方法も考えられるが,タスクの起動処理でス タック領域が使えないことから,タスクの起動処理だけは例外扱いしなければ ならない.例えば,タスクの起動処理においてはTCB中のスタックポインタを特 殊な値(例えば0)に設定しておき,ディスパッチャ本体でTCB中のスタックポ インタがその値の場合にはstart_rに分岐させ,start_rにおいてスタックポイ ンタを初期化する方法が考えられる. 6.6 割込みハンドラ 6.6.1 割込みハンドラの出入口処理 カーネル管理の割込みハンドラの出入口処理は,以下の擬似コードと等価にな るように実装する.処理内容が等価であれば,処理順序を変更してもかまわな い. プロセッサによっては,擬似コードに含まれる処理がハードウェアで実現され ている場合もあるが,そのような処理はソフトウェアで行う必要はない. 擬似コード中で,「少なくともカーネル管理の割込みを禁止した状態」とは, カーネル内部で用いる一時的な状態であり,この状態のままでカーネル外に出 ることはない.そのため,この状態では,CPUロック状態であると識別できなく てもよい.例えば,CPUロック状態であることを示す変数を用意している場合に は,この状態ではその変数をCPUロック状態を示す値に変更する必要はない.ま た,この状態では,カーネル管理外の割込み(の一部)が禁止されていてもよ い. ---------------------------------------- void <割込みの出入口処理>(void) { 少なくともカーネル管理の割込みを禁止した状態にする … (*d) スクラッチレジスタをスタックに保存する if (割込みがタスクコンテキストで発生) { #ifdef TOPPERS_SUPPORT_OVRHDR ovrtimer_stop(); /* オーバランタイマの停止 */ … (*e) #endif /* TOPPERS_SUPPORT_OVRHDR */ スタックを非タスクコンテキスト用のスタックに切り換え, 非タスクコンテキストに切り換える } 割込み優先度マスクを,受け付けた割込みの割込み優先度に設定する CPUロック解除状態にする(受け付けた割込みよりも優先度の高い割込みを 受け付けるようにする) 割込みハンドラの入口で必要なIRCの操作を行う(割込み要求ラインがエッ ジトリガである場合のトリガされた割込み要求のクリアなど) #ifdef LOG_INH_ENTER log_inh_enter(割込みハンドラ番号); #endif /* LOG_INH_ENTER */ 割込みハンドラを呼び出す #ifdef LOG_INH_LEAVE log_inh_leave(割込みハンドラ番号); #endif /* LOG_INH_LEAVE */ 割込みハンドラの出口で必要なIRCの操作を行う(IRCに対する割込み処理 の終了通知など) 少なくともカーネル管理の割込みを禁止した状態にする 割込み優先度マスクを,割込みを受け付ける前の値に戻す … (*f) if (割込みがタスクコンテキストで発生) { スタックをタスク用のスタックに戻し,タスクコンテキストに切り換える … (*g) if (p_runtsk != p_schedtsk) { CPUロック状態にする … (*h) 割込み優先度マスクは,全解除状態(TIPM_ENAALL)になって いなければならない … (*i) if (p_runtsk != NULL) { スクラッチレジスタを除くすべてのレジスタをスタックに保存する スタックポインタを自タスク(p_runtsk)のTCBに保存する ret_int_rを,実行再開番地として自タスクのTCBに保存する … (*a) dispatcherに分岐する } else { dispatcher_0に分岐する } ret_int_r: スクラッチレジスタを除くすべてのレジスタをスタックから復帰する #ifdef TOPPERS_SUPPORT_OVRHDR ovrtimer_start(); /* オーバランタイマの動作開始 */ #endif /* TOPPERS_SUPPORT_OVRHDR */ } #ifdef TOPPERS_SUPPORT_OVRHDR else { if (p_runtsk != NULL) { ovrtimer_start(); /* オーバランタイマの動作開始 */ } } #endif /* TOPPERS_SUPPORT_OVRHDR */ } 割込み処理からのリターンにより,CPUロック解除状態に戻るように準備する スクラッチレジスタをスタックから復帰する 割込み処理からのリターン } ---------------------------------------- 割込みの受付けにより割込みが禁止されないプロセッサでは,(*d)において, 少なくともカーネル管理の割込みを禁止する.これは,ovrtimer_stopやスタッ クを切り換える処理等において,カーネルの内部変数をアクセスする(場合が ある)ため,それらに対する排他制御が必要なためである.オーバランタイマ をサポートせず,その他の処理でもカーネルの内部変数をアクセスしない場合 には,(*d)を省略できる場合がある. ただし,ハードウェアによりスタックポインタを切り換える機能がないプロセッ サでは,割込みハンドラの入口処理のできる限り早いタイミングで,カーネル 管理外の割込みも含めて,すべての割込みを禁止するのが望ましい.詳しくは, 「多重割込みとスタック」の項を参照すること. 割込みの受付けにより割込みが禁止されないプロセッサでは,(*e)の処理を, if文の手前で(つまり,割込みが発生したコンテキストに依らずに)行うべき である.これは,(*d)において割込みを禁止する前に多重割込みが受け付けら れた場合に,その割込み処理の間もオーバランタイマの動作を止めておくため に必要である.なお,ovrtimer_stopは,オーバランタイマが動作していない時 は何も行わないため,過剰に呼び出しても差し支えない. (*f)において,割込み優先度マスクを割込みを受け付ける前の値に戻す処理は, 割込み処理からリターンするまでに行えばよい.割込み処理からのリターンに より割込み優先度マスクを元に戻す機能がある場合には,それに委ねてもよい. ただし,そのようにした場合には,(*i)において,割込み優先度マスクは全解 除状態(TIPM_ENAALL)にする処理を行う必要がある. (*g)においてタスクコンテキストに切り換える処理は,割込み処理からのリター ンによりスタックとコンテキストが元に戻るプロセッサでは,dispatcherに分 岐する場合にのみ行えばよい.dispatcherに分岐しない場合には,非タスクコ ンテキストのまま処理を続け,割込み処理からのリターンでタスクコンテキス トに戻ることになる. (*h)においてCPUロック状態にするのは,dispatcherに分岐する際に,CPUロッ ク状態になっている必要があるためである. (*i)の処理に到達するのは,割込み処理前に割込み優先度マスクが全解除状態 (TIPM_ENAALL)であった場合に限られるため,(*f)において割込み優先度マス クを割込みを受け付ける前の値に戻していれば,ここでは何もしなくても良い. ただし,割込み優先度マスクを戻す処理を後で行う場合には,(*i)において, 割込み優先度マスクを全解除状態に設定しなければならない.なお,ここで割 込み優先度マスクが全解除状態になっていなければならないのは,dispatcher に分岐する際には,割込み優先度マスク全解除状態になっている必要があるた めである. タスクの実行中に割込みが発生し,割込みからの出口処理中でdispatcherに分 岐した場合,そのタスクが次に実行される時には,実行再開番地として登録し たret_int_rに戻ってくる.ret_int_rには,dispatcherのみから分岐し,その 時の状態は,タスクコンテキスト・CPUロック状態・割込み優先度マスク全解除 状態・ディスパッチ許可状態である. 割込みの出入口処理をアセンブリ言語で記述する場合には,トレースログ取得 処理は,「6.2 トレースログ機能への対応」の節で記述した方法でコーディン グすること. 〔多重割込みとスタック〕 ハードウェアによりスタックポインタを切り換える機能がないプロセッサでは, 割込みの入口処理において,非タスクコンテキスト用のスタックに切り換える 前に多重割込みを受け付けると,タスクのスタック領域が使用される.そのた め,各タスクのスタック領域を確保する際に,ここで受け付ける割込みが使用 するスタックを見込んで確保しなければならない. 各タスクのスタック領域をなるべく小さくするためには,スタックをなるべく 使用しない内に,カーネル管理外の割込みも含めて,多重割込みを禁止するの が望ましい.一方で,カーネル管理外の割込みの禁止時間が長くなると,カー ネル管理外の割込みの応答性が低下するため,ユーザに注意を促す必要がある. 特に,割込みの受付により割込みが禁止されず,ハードウェアによりスタック ポインタを切り換える機能がないプロセッサでは,次の点に注意が必要である. このようなプロセッサでは,非タスクコンテキスト用のスタックに切り換える 前に,最大で割込み優先度の段数分の多重割込みが発生することを防ぐことは できず,各タスクのスタック領域をその分を見込んで確保しなければならない. そこで,スタックをなるべく使用しない内に多重割込みを禁止するために,ス クラッチレジスタをスタックに保存する前に,すべての割込みを禁止するのが 望ましい.ただし,割込みの禁止処理に必要な最低限のレジスタについては, 割込みの禁止に先立ってスタックに保存する必要がある. カーネルの管轄外ではあるが,カーネル管理外の割込み処理においても,非タ スクコンテキスト用のスタック(または,カーネル管理外の割込み処理用のス タック)に切り換えることが望ましい. 【TOPPERS/ASP1カーネルとの関係】 擬似コードの構成を見直した(擬似コードで想定しているプロセッサのタイプ を変えた). reqflgを廃止した.また,タスク切換えの条件判定で,dspflgをチェックする 必要がなくなった. アイドル処理の設計を変更したため,割込みハンドラの出口処理におけるタス ク切換えにおいて,p_runtskがNULLとなっている状況を考える必要が生じた. 6.6.2 割込みハンドラ毎の出入口処理の生成 割込みベクトルをハードウェアで実現している場合など,割込みハンドラ毎に 出入口処理を用意した方が効率が良いプロセッサのために,割込みハンドラ毎 に出入口処理を生成する機構を用意している. 以下のマクロは,標準の割込み管理機能の初期化処理を用いた場合のみ,ター ゲット非依存部で使われる.割込み管理機能の初期化処理をターゲット依存部 で用意し,その中でこれらのマクロを使わない場合には,これらのマクロを用 意する必要はない. (6-6-2-1) INT_ENTRY(inhno, inthdr) 割込みハンドラ番号がinhno,割込みハンドラの関数名がinthdrである割込みハ ンドラの出入口処理のラベルを作るマクロ.INTHDR_ENTRYを用いて割込みハン ドラ毎に出入口処理を生成する場合には,次のように定義する. #define INT_ENTRY(inhno, inthdr) _kernel_##inthdr##_##inhno 割込みハンドラ毎に出入口処理を作る必要がない場合には,次のように定義し て,割込みハンドラの関数名をそのまま返す. #define INT_ENTRY(inhno, inthdr) inthdr (6-6-2-2) INTHDR_ENTRY(inhno, inhno_num, inthdr) 割込みハンドラ番号がinhno,割込みハンドラの関数名がinthdrである割込みハ ンドラの出入口処理を生成するマクロ.inhno_numには,アセンブリ言語記述用 に,割込みハンドラ番号が数値で渡される.割込みハンドラ毎に出入口処理を 作る必要がない場合には,空に定義する. 6.6.3 割込みハンドラの設定 (6-6-3-1) void define_inh(INHNO inhno, FP int_entry) inhnoで指定された割込みハンドラの出入口処理の番地をint_entryに設定する. この関数は,標準の割込み管理機能の初期化処理を用いた場合のみ,ターゲッ ト非依存部から呼び出される.割込み管理機能の初期化処理をターゲット依存 部で用意し,その中でこの関数を呼び出さない場合には,この関数を用意する 必要はない. この関数は,ターゲット非依存部のカーネル初期化処理から呼び出されるため, カーネルの初期化処理(NMIを除くすべての割込みがマスクされている)から呼 び出せるように実装すればよい. 指定された割込みハンドラ番号がDEF_INHに対するものとして有効な値でない場 合の動作は保証する必要がない(assertでエラーとするのが望ましい).これ は,コンフィギュレータが,パス2のテンプレートファイルのターゲット依存部 で定義するINHNO_DEFINH_VALIDを用いてエラーを検出するためである. 6.6.4 割込み要求ラインの属性の設定 (6-6-4-1) void config_int(INTNO intno, ATR intatr, PRI intpri) intnoで指定された割込み要求ラインの割込み属性を,intatrで指定された通り に設定する.また,割込み優先度を,intpriで指定された値に設定する. この関数は,標準の割込み管理機能の初期化処理を用いた場合のみ,ターゲッ ト非依存部から呼び出される.割込み管理機能の初期化処理をターゲット依存 部で用意し,その中でこの関数を呼び出さない場合には,この関数を用意する 必要はない. この関数は,ターゲット非依存部のカーネル初期化処理から呼び出されるため, カーネルの初期化処理(NMIを除くすべての割込みがマスクされている)から呼 び出せるように実装すればよい. intatrとして設定できる割込み属性は次の通り. TA_ENAINT 0x01 割込み要求禁止フラグをクリア TA_EDGE 0x02 エッジトリガ この他に,ターゲット定義で割込み属性を追加してもよい.ターゲット定義で 追加するために,以下の属性名が予約されている. TA_POSEDGE ポジティブエッジトリガ TA_NEGEDGE ネガティブエッジトリガ TA_BOTHEDGE 両エッジトリガ TA_LOWLEVEL ローレベルトリガ TA_HIGHLEVEL ハイレベルトリガ これらの属性名をターゲット定義で追加する場合には,その属性値を決定し, 定義をtarget_kernel.h(または,そこからインクルードされるファイル)に含 める.また,コンフィギュレータテンプレートファイルから参照できるように, target_def.csv(または,同等の役割を持つファイル)に含め,コンフィギュ レータテンプレートファイルのターゲット非依存部でエラーとならないように, target.tf(または,そこからインクルードされるファイル)でTARGET_INTATR に設定する. 指定された割込み番号が有効な値でない場合や,その割込み要求ラインに対し て設定できない属性を指定した場合,設定できない割込み優先度を指定した場 合の動作は保証する必要がない(assertでエラーとするのが望ましい).この ようなケースは,コンフィギュレータでエラーを検出すべきである.コンフィ ギュレータテンプレートファイルのターゲット非依存部は,パス2のテンプレー トファイルのターゲット依存部で定義するINTNO_CFGINT_VALID, TARGET_INTATR,INTPRI_CFGINT_VALIDを用いてエラーを検出するが,標準の割 込み属性(TA_ENAINT,TA_EDGE)が設定できない場合や,設定できない属性や 割込み優先度が割込み要求ラインによって異なる場合には,コンフィギュレー タテンプレートファイルのターゲット依存部で検出しなければならない. 6.6.5 割込み管理機能の初期化処理の変更 (6-6-5-1) OMIT_INITIALIZE_INTERRUPT(オプション) 割込み管理機能の初期化処理をターゲット依存部で用意し,ターゲット非依存 部に含まれる標準の割込み管理機能の初期化処理を用いない場合には,このシ ンボルをマクロ定義する. このシンボルをマクロ定義すると,INHINIB,INTINIB,initialize_interrupt の定義が,カーネルのターゲット非依存部から取り除かれる.また, TNUM_DEF_INHNO,tnum_def_inhno,inhinib_table,TNUM_CFG_INTNO, tnum_cfg_intno,intinib_tableの定義と,割込みハンドラ毎の出入口処理を生 成するための記述(INTHDR_ENTRYマクロのリスト)が,コンフィギュレータの パス2のテンプレートファイルのターゲット非依存部によってkernel_cfg.cに生 成されなくなる. (6-6-5-2) void initialize_interrupt(void)(オプション) OMIT_INITIALIZE_INTERRUPTをマクロ定義した場合には,この関数をターゲット 依存部で用意する.OMIT_INITIALIZE_INTERRUPTをマクロ定義することにより取 り除かれるその他のデータ型,変数,マクロは,この関数で使用する場合にの み用意すればよい. (6-6-5-3) USE_INHINIB_TABLE(オプション) OMIT_INITIALIZE_INTERRUPTをマクロ定義したが,割込みハンドラの初期化に必 要な情報をkernel_cfg.cに生成したい場合には,このシンボルをマクロ定義す る. このシンボルをマクロ定義すると,INHINIBの定義が,カーネルのターゲット非 依存部から取り除かれない.また,TNUM_DEF_INHNO,tnum_def_inhno, inhinib_tableの定義と,割込みハンドラ毎の出入口処理を生成するための記述 (INTHDR_ENTRYマクロのリスト)が,ターゲット非依存部によって生成される. (6-6-5-4) USE_INTINIB_TABLE(オプション) OMIT_INITIALIZE_INTERRUPTをマクロ定義したが,割込み要求ラインの初期化に 必要な情報をkernel_cfg.cに生成したい場合には,このシンボルをマクロ定義 する. このシンボルをマクロ定義すると,INTINIBの定義が,カーネルのターゲット非 依存部から取り除かれない.また,TNUM_CFG_INTNO,tnum_cfg_intno, intinib_tableの定義が,ターゲット非依存部によって生成される. 6.6.6 デフォルトの割込みハンドラ (6-6-6-1) void default_int_handler(void)(オプション) コンフィギュレータにより割込みハンドラのテーブルを生成する場合などには, 割込みハンドラを登録しなかった割込みハンドラ番号に対して,デフォルトの 割込みハンドラとして,default_int_handlerを登録する. default_int_handlerは,標準のものをターゲット依存部で用意するが,ユーザ が用意したもので置き換えられるように,OMIT_DEFAULT_INT_HANDLERをマクロ 定義した場合には,ターゲット依存部で定義しないようにする.なお,ユーザ が用意する場合の名称は,_kernel_default_int_handlerとなる. 6.6.7 カーネル管理外の割込み カーネル管理外の割込みハンドラは,カーネル内の割込み出入口処理を経由せ ずに実行するのが基本である. ただし,すべての割込みで同じアドレスに分岐するプロセッサでは,カーネル 内の割込み出入口処理を全く経由せずにカーネル管理外の割込みハンドラを実 行することができないため,割込み出入口処理のなるべく早いタイミングで, カーネル管理外の割込みであるかを判別し,処理内容を分ける必要がある.具 体的には,カーネル管理外の割込みの出入口処理では,オーバランハンドラの 停止と動作開始を行ってはならない.また,タスク切換えを行う必要がない. さらに,NMIの出入口処理では,トレースログ取得処理(log_inh_enterおよび log_inh_leave)を呼び出してはならない. カーネル管理外の割込みハンドラを実行する際に,カーネル内の割込み出入口 処理の一部分を経由する場合には,CPU例外が起こる可能性を極力減らすととも に,CPU例外を起こす可能性がある場合には,その可能性をターゲット依存部の ユーザーズマニュアルに記載しなければならない. 次に,カーネル管理外の割込みの設定方法に関して,「TOPPERS新世代カーネル 統合仕様書」の「2.7.8 カーネル管理外の割込みの設定方法」の節の3つの方法 のいずれを採用するかを決定する. (a-1)または(a-2)を採用し,カーネル管理外とした割込みに対して,カーネル のAPIによる割込みハンドラの登録と割込み要求ラインの属性の設定をサポート しない場合には,それに代わる方法をターゲット依存部のユーザーズマニュア ルに記述する. (a-1)または(a-2)を採用してカーネルのAPIによる割込みハンドラの登録や割込 み要求ラインの属性の設定をサポートする場合や,(b)を採用した場合には,ター ゲット依存部においてそれを実現する必要がある. カーネル管理外の割込みに対して,DEF_INHによる割込みハンドラの登録をサポー トするには,次の設定が必要になる. ・TARGET_INHATRに,TA_NONKERNELを設定する. ・(a-1)または(a-2)を採用した場合には,INHNO_DEFINH_VALIDに,カーネル管  理外とした割込みに対応する割込みハンドラ番号を含める.また,  VALID_INHNOを,カーネル管理外とした割込みハンドラ番号を有効な値と判定  するようにする. ・(a-1)または(a-2)を採用した場合には,INHNO_FIX_KERNELにカーネル管理と  した割込みハンドラ番号のリストを,INHNO_FIX_NONKERNELにカーネル管理外  とした割込みハンドラ番号のリスト設定する. ・DEF_INHがカーネル管理外の割込みに対応できるようにする.標準の割込み管  理機能の初期化処理を用いる場合には,define_inhをカーネル管理外の割込  みに対応させる. ・必要な場合には,TA_NONKERNEL属性が設定された割込みハンドラをカーネル  管理外と扱うように,カーネル内の割込み出入口処理を修正する.標準の割  込み管理機能の初期化処理を用いる場合,カーネル管理外の割込みに対して  は,カーネル内の割込み出入口処理を生成せず,アプリケーションが登録し  た割込みハンドラを直接呼び出すように,ターゲット非依存部により設定さ  れるため,ターゲット依存部では対応する必要がない. カーネル管理外の割込みに対して,CFG_INTによる割込み要求ラインの属性の設 定をサポートするには,次の設定が必要になる. ・(a-1)または(a-2)を採用した場合には,INTNO_CFGINT_VALIDに,カーネル管  理外とした割込みに対応する割込み番号を含める.また,VALID_INTNOを,カー  ネル管理外とした割込み番号を有効な値と判定するようにする.必要であれ  ば,VALID_INTNO_DISINTとVALID_INTNO_CREISRの定義を追加または変更する. ・(a-1)または(a-2)を採用した場合には,INTNO_FIX_KERNELにカーネル管理と  した割込み番号のリストを,INTNO_FIX_NONKERNELにカーネル管理外とした割  込み番号のリスト設定する. ・INTPRI_CFGINT_VALIDに,カーネル管理外の割込みとなる優先度を含める. ・CFG_INTがカーネル管理外の割込みに対応できるようにする.標準の割込み管  理機能の初期化処理を用いる場合には,config_intをカーネル管理外の割込  みに対応させる. chg_ipmにより,(NMI以外の)カーネル管理外の割込みをマスクできるように する場合には,次の設定が必要になる. ・VALID_INTPRI_CHGIPMを,カーネル管理外の割込みとなる優先度を有効な値と  判定するようにする. ・t_set_ipmを,カーネル管理外の割込みとなる優先度を扱えるようにする. 6.6.8 割込みサービスルーチンの生成 (6-6-8-1) bool_t VALID_INTNO_CREISR(INTNO intno)(オプション) intnoが,acre_isrに対する割込み番号として有効な値である場合にtrue,そう でない場合にfalseを返すマクロ.動的生成機能拡張パッケージを使用しない場 合には,定義する必要がない. このマクロを定義しない場合,VALID_INTNOが使われる.VALID_INTNOで有効と 判断される割込み番号が,acre_isrに対して有効な割込み番号と一致している 場合,このマクロを用意する必要はない. 6.7 CPU例外ハンドラとCPU例外発生時のシステム状態の参照 6.7.1 CPU例外ハンドラの出入口処理 CPU例外ハンドラの出入口処理は,以下の擬似コードと等価になるように実装す る.処理内容が等価であれば,処理順序を変更してもかまわない. ---------------------------------------- void (void) { スクラッチレジスタをスタックに保存する CPU例外が発生した状況を判断するための追加情報をスタックに保存する … (*j) この時点でのスタックポインタ±nを,CPU例外の情報を記憶している領域の 先頭番地とする(必要なら保存する) if (カーネル管理外のCPU例外) { if (CPU例外がタスクコンテキストで発生) { スタックを非タスクコンテキスト用のスタックに切り換え, 非タスクコンテキストに切り換える … (*k) } システム状態(コンテキストは除く)を,CPU例外発生時の状態にする CPU例外ハンドラを,CPU例外の情報を記憶している領域の先頭番地を パラメータ(p_excinf)として呼び出す if (CPU例外がタスクコンテキストで発生) { スタックをタスク用のスタックに戻し, タスクコンテキストに切り換える … (*k) } CPU例外処理からのリターン後に,CPU例外発生時のシステム状態に 戻るように準備する } else { if (CPU例外がタスクコンテキストで発生) { 少なくともカーネル管理の割込みを禁止した状態にする #ifdef TOPPERS_SUPPORT_OVRHDR ovrtimer_stop(); /* オーバランタイマの停止 */ #endif /* TOPPERS_SUPPORT_OVRHDR */ スタックを非タスクコンテキスト用のスタックに切り換え, 非タスクコンテキストに切り換える } 割込み優先度マスクを,CPU例外発生時の値に設定する … (*l) CPUロック解除状態にする(CPU例外発生時の割込み優先度マスクよりも 優先度の高い割込みを受け付けるようにする) #ifdef LOG_EXC_ENTER log_exc_enter(CPU例外ハンドラ番号); #endif /* LOG_EXC_ENTER */ CPU例外ハンドラを,CPU例外の情報を記憶している領域の先頭番地を パラメータ(p_excinf)として呼び出す #ifdef LOG_EXC_LEAVE log_exc_leave(CPU例外ハンドラ番号); #endif /* LOG_EXC_LEAVE */ 少なくともカーネル管理の割込みを禁止した状態にする … (*m) 割込み優先度マスクを,CPU例外発生時の値に設定する … (*n) if (CPU例外がタスクコンテキストで発生) { スタックをタスク用のスタックに戻し,タスクコンテキストに切り換える … (*g) if (p_runtsk != p_schedtsk) { CPUロック状態にする … (*h) 割込み優先度マスクは,全解除状態(TIPM_ENAALL)になって いなければならない … (*i) if (p_runtsk != NULL) { スクラッチレジスタを除くすべてのレジスタをスタックに保存する スタックポインタを自タスク(p_runtsk)のTCBに保存する ret_exc_rを,実行再開番地として自タスクのTCBに保存する … (*a) dispatcherに分岐する } else { dispatcher_0に分岐する } ret_exc_r: スクラッチレジスタを除くすべてのレジスタをスタックから復帰する #ifdef TOPPERS_SUPPORT_OVRHDR ovrtimer_start(); /* オーバランタイマの動作開始 */ #endif /* TOPPERS_SUPPORT_OVRHDR */ } #ifdef TOPPERS_SUPPORT_OVRHDR else { if (p_runtsk != NULL) { ovrtimer_start(); /* オーバランタイマの動作開始 */ } } #endif /* TOPPERS_SUPPORT_OVRHDR */ } CPU例外処理からのリターン後に,CPUロック解除状態に戻るように準備する } CPU例外が発生した状況を判断するための追加情報をスタック上から捨てる スクラッチレジスタをスタックから復帰する CPU例外処理からのリターン } ---------------------------------------- CPU例外ハンドラは,非コンテキストに切り換えることを除いては,CPU例外発 生時と同じシステム状態で呼び出さなければならない.例えば,CPU例外がCPU ロック状態で発生した場合にはCPUロック状態,CPUロック解除状態で発生した 場合にはCPUロック解除状態で,CPU例外ハンドラを呼び出さなければならない. CPUロック状態で発生したCPU例外は,カーネル管理外のCPU例外となるため,カー ネル管理のCPU例外ハンドラについては,CPUロック解除状態で呼び出すことに なる. (*j)では,CPU例外ハンドラの中(および,そこから呼び出されたxsns_dpn)で は,CPU例外が発生した状況を判断するために必要となる追加情報をスタックに 保存する.追加情報が必要ない場合は,(*j)の処理は必要ない. プロセッサによっては,カーネル管理外のCPU例外を正確に判定するのが難しい 場合がある.このような場合には,割込み優先度マスクが全解除でない状態で 発生したCPU例外を,カーネル管理外のCPU例外と扱ってもよい.これは,割込 み優先度マスクが全解除でない場合にはxsns_dpnがtrueを返すため,カーネル 機能を用いたリカバリができないためである. 具体的には,全割込みロック(またはCPUロック)を小さいオーバヘッドで実現 しようとすると,CPU例外ハンドラの中で,全割込みロック状態(またはCPUロッ ク状態)と割込み優先度マスクを高いレベルに設定した状態を区別できない場 合がある.また,カーネル管理外の割込み処理中やカーネル実行中であること を正確に判断することも難しい場合がある. カーネル管理外のCPU例外の場合に,(*k)において,スタックを非タスクコンテ キスト用のスタックに切り換え,非タスクコンテキストに切り換えているが, この切換えはターゲット定義で省いても良い.これは,カーネル管理外のCPU例 外は,カーネル内のクリティカルセクション中で発生する可能性があるため, 安全に切り換えられるとは限らないためである.また,カーネル管理外の割込 みハンドラを呼ぶ時のコンテキストやスタックはターゲット依存なので,カー ネル管理外のCPU例外ハンドラもそれと同様に扱って良いと考えられるためであ る. 上の擬似コードでは,カーネル管理外のCPU例外に対して,トレースログ取得処 理(log_exc_enterおよびlog_exc_leave)を呼び出していないが,全割込みロッ ク状態かNMIの処理中にCPU例外が発生した場合を除外すれば,呼び出してもか まわない.全割込みロック状態かNMIの処理中に発生したCPU例外の場合には, トレースログ取得処理を呼び出してはならない. (*l)の処理は,CPU例外の発生/受付により,割込み優先度マスクが変化しない プロセッサでは省いてもよい.それに対して(*n)の処理は,CPU例外ハンドラ中 で割込み優先度マスクが変更された場合に対応するためのものなので,省くこ とはできない. (*m)の処理は,プロセッサによっては,CPU例外がタスクコンテキストで発生し た時のみに行ってもよい場合がある. CPU例外ハンドラを実行する際に経由する部分では,CPU例外が起こる可能性を 極力減らすとともに,CPU例外を起こす可能性がある場合(例えば,スクラッチ レジスタをスタックに保存する時に,バスエラーなどのCPU例外が発生する可能 性が考えられる)には,その可能性をターゲット依存部のユーザーズマニュア ルに記載しなければならない. CPU例外ハンドラの出口処理は,割込みハンドラの出口処理と共通部分が多いた め,プロセッサによっては,共通のルーチンを用いることができる可能性があ る. CPU例外の出入口処理をアセンブリ言語で記述する場合には,トレースログ取得 処理は,「6.2 トレースログ機能への対応」の節で記述した方法でコーディン グすること. 【TOPPERS/ASP1カーネルとの関係】 擬似コードの構成を見直した(擬似コードで想定しているプロセッサのタイプ を変えた). reqflgを廃止した.また,タスク切換えの条件判定で,dspflgをチェックする 必要がなくなった. アイドル処理の設計を変更したため,CPU例外ハンドラの出口処理におけるタス ク切換えにおいて,p_runtskがNULLとなっている状況を考える必要が生じた. 6.7.2 CPU例外ハンドラの出入口処理の生成 CPU例外ベクトルをハードウェアで実現している場合など,CPU例外ハンドラ毎 に出入口処理を用意した方が効率が良いターゲットのために,CPU例外ハンドラ 毎に出入口処理を生成する機構を用意している. 以下のマクロは,標準のCPU例外管理機能の初期化処理を用いた場合のみ,ター ゲット非依存部で使われる.CPU例外管理機能の初期化処理をターゲット依存部 で用意し,その中でこれらのマクロを使わない場合には,これらのマクロを用 意する必要はない. (6-7-2-1) EXC_ENTRY(excno, exchdr) CPU例外ハンドラ番号がexcno,CPU例外ハンドラの関数名がexchdrであるCPU例 外ハンドラの出入口処理のラベルを作るマクロ.EXCHDR_ENTRYを用いてCPU例外 ハンドラ毎に出入口処理を生成する場合には,次のように定義する. #define EXC_ENTRY(excno, exchdr) _kernel_##exchdr##_##excno CPU例外ハンドラ毎に出入口処理を作る必要がない場合には,次のように定義し て,CPU例外ハンドラの関数名をそのまま返す. #define EXC_ENTRY(excno, exchdr) exchdr (6-7-2-2) EXCHDR_ENTRY(excno, excno_num, exchdr) CPU例外ハンドラ番号がexcno,CPU例外ハンドラの関数名がexchdrであるCPU例 外ハンドラの出入口処理を生成するマクロ.excno_numには,アセンブリ言語記 述用に,CPU例外ハンドラ番号が数値で渡される.CPU例外ハンドラ毎に出入口 処理を作る必要がない場合には,空に定義する. 6.7.3 CPU例外ハンドラの設定 (6-7-3-1) bool_t VALID_EXCNO(EXCNO excno)(オプション) excnoが,CPU例外ハンドラ番号として有効な値である場合にtrue,そうでない 場合にfalseを返すマクロ.なお,ASP3カーネルでは,CPU例外ハンドラ番号を 用いるAPIは,DEF_EXCのみである. ASP3カーネルのターゲット非依存部では,このマクロは使われていないため, ターゲット依存部で使わないなら,用意する必要がない. (6-7-3-2) void define_exc(EXCNO excno, FP exc_entry) excnoで指定されたCPU例外ハンドラの出入口処理の番地をexc_entryに設定する. この関数は,標準のCPU例外管理機能の初期化処理を用いた場合のみ,ターゲッ ト非依存部から呼び出される.CPU例外管理機能の初期化処理をターゲット依存 部で用意し,その中でこの関数を呼び出さない場合には,この関数を用意する 必要はない. この関数は,ターゲット非依存部のカーネル初期化処理から呼び出されるため, カーネルの初期化処理(NMIを除くすべての割込みがマスクされている)から呼 び出せるように実装すればよい. 指定されたCPU例外ハンドラ番号がDEF_EXCに対するものとして有効な値でない 場合の動作は保証する必要がない(assertでエラーとするのが望ましい).こ れは,コンフィギュレータが,パス2のテンプレートファイルのターゲット依存 部で定義するEXCNO_VALIDを用いてエラーを検出するためである. 6.7.4 CPU例外管理機能の初期化処理の変更 (6-7-4-1) OMIT_INITIALIZE_EXCEPTION(オプション) CPU例外管理機能の初期化処理をターゲット依存部で用意し,ターゲット非依存 部に含まれる標準の割込み管理機能の初期化処理を用いない場合には,このシ ンボルをマクロ定義する. このシンボルをマクロ定義すると,EXCINIBとinitialize_exceptionの定義が, カーネルのターゲット非依存部から取り除かれる.また,TNUM_DEF_EXCNO, tnum_def_excno,excinib_tableの定義と,CPU例外ハンドラ毎の出入口処理を 生成するための記述(EXCHDR_ENTRYマクロのリスト)を,コンフィギュレータ のパス2のテンプレートファイルのターゲット非依存部によってkernel_cfg.cに 生成されなくなる. (6-7-4-2) void initialize_exception(void)(オプション) OMIT_INITIALIZE_EXCEPTIONをマクロ定義した場合には,この関数をターゲット 依存部で用意する.OMIT_INITIALIZE_EXCEPTIONをマクロ定義することにより取 り除かれるその他のデータ型,変数,マクロは,この関数で使用する場合にの み用意すればよい. 6.7.5 デフォルトのCPU例外ハンドラ (6-7-5-1) void default_exc_handler(void *p_excinf)(オプション) コンフィギュレータによりCPU例外ハンドラのテーブルを生成する場合などには, CPU例外ハンドラを登録しなかったCPU例外ハンドラ番号に対して,デフォルト のCPU例外ハンドラとして,default_exc_handlerを登録する. default_exc_handlerは,標準のものをターゲット依存部で用意するが,ユーザ が用意したもので置き換えられるように,OMIT_DEFAULT_EXC_HANDLERをマクロ 定義した場合には,ターゲット依存部で定義しないようにする.なお,ユーザ が用意する場合の名称は,_kernel_default_exc_handlerとなる. 6.7.6 CPU例外発生時のシステム状態の参照 (6-7-6-1) bool_t exc_sense_intmask(void *p_excinf) CPU例外が発生した時のシステム状態が,以下の条件をすべて満たす場合に true,そうでない時にfalseを返す関数.  (1) カーネル内のクリティカルセクションの実行中でない  (2) 全割込みロック状態でない  (3) CPUロック状態でない  (4) カーネル管理外の割込みハンドラ実行中でない  (5) カーネル管理外のCPU例外ハンドラ実行中でない  (6) タスクコンテキスト  (7) 割込み優先度マスクが全解除 多くの場合,カーネル管理の割込みがすべてマスクされていることをチェック することで,(1)〜(5)の判定を一括して行うことができる.また,割込み優先 度マスクを実現しているハードウェアレジスタをチェックすることで,(1)〜 (5)と(7)の判定を一括して行える場合も多い. p_excinfには,CPU例外の情報を記憶している領域の先頭番地が渡される. 6.8 カーネルの起動・終了とスタック領域など (6-8-1) スタートアップモジュール カーネルのスタートアップモジュールは,システムのリセット後に最初に実行 されるプログラムである.スタートアップモジュールは,標準的には,プロセッ サ依存部またはチップ依存部で用意し以下の処理を行うが,それにこだわる必 要はない.具体的には,開発環境に用意されているスタートアップモジュール を用いる方法(この場合,ターゲット依存部でmain関数を用意する必要がある) や,アプリケーションで用意する場合が考えられる. (a) プロセッサ状態の初期化 プロセッサモード,スタックポインタ,フレームポインタ等,プロセッサの状 態を初期化する.また,NMIを除くすべての割込みをマスクした状態(全割込み ロック状態と同等の状態)とする.DRAMコントローラの初期化など,メモリを アクセスするために必要な初期化処理をここで行ってもよい(次の hardware_init_hookで行ってもよい). (b) hardware_init_hookを呼び出す システムのリセット後すぐに行う必要のあるターゲットシステム依存の初期化 処理を行うために,hardware_init_hookを呼び出す.hardware_init_hookが用 意されていない場合は,何もしない.GNU開発環境では,リンカスクリプト中の weak definitionにより,hardware_init_hookが用意されていない場合の値を0 とすることで,これを実現できる.weak definitionの機能を持たない開発環境 では,hardware_init_hookを必ず呼び出すことにする. hardware_init_hookは,ターゲット依存部で用意するのが標準であるが,シス テムのリセット後すぐに行う必要のある初期化処理を追加するために,アプリ ケーションで用意したものを用いる場合もある. メモリアクセスに必要な初期化処理をhardware_init_hookで行う場合には,こ れを呼び出す時点でメモリにアクセスすることができないため,関数(サブルー チン)を呼び出すためにスタックを使用するプロセッサでは,戻り番地を汎用 レジスタに入れて呼び出すといった工夫が必要である.この場合, hardware_init_hookをC言語で記述することはできなくなるが,やむをえない. (c) bssセクションとdataセクションの初期化 bssセクションをクリアし,dataセクションに初期値を設定する. ただし,カーネル本体は,kerflgがfalse(=0)に初期化されること以外に, これらのセクションが初期化されることに依存していないため,スタートアッ プモジュールをアプリケーションで用意する場合で,システムサービスやアプ リケーションがこれらのセクションが初期化されることに依存していない場合 には,システムの起動時間を短縮するために,kerflgをfalseに初期化するだけ で十分である. (d) software_init_hookを呼び出す 開発環境(特にライブラリ)に依存して必要な初期化処理を行うために, software_init_hookを呼び出す.software_init_hookが用意されていない場合 は,何もしない.GNU開発環境では,リンカスクリプト中のweak definitionに より,software_init_hookが用意されていない場合の値を0とすることで,これ を実現できる.weak definitionの機能を持たない開発環境では, software_init_hookを必ず呼び出すことにする. software_init_hookは,ターゲット依存部で用意するのが標準である. (e) sta_kerへ分岐 sta_kerを呼び出す.sta_kerは,NMIを除くすべての割込みをマスクした状態 (全割込みロック状態と同等の状態)で呼び出さなければならない.sta_kerか らはリターンすることがないため,スタートアップモジュールに戻ってくるこ とは考える必要がない. (6-8-2) void target_initialize(void) ターゲット依存部の初期化を行う関数.sta_kerの最初で呼び出される.開発環 境依存/プロセッサコア依存/チップ依存の初期化処理を,それらの依存部に 切り分けることも可能である. この関数は,あくまでもカーネルのターゲット依存部の初期化処理を行うため のものである.アプリケーションに必要な初期化処理は,初期化ルーチンで行 うのが基本であるが,システムのリセット後すぐに行う必要がある場合には, hardware_init_hookを用いる. (6-8-3) void call_exit_kernel(void) 非タスクコンテキストに切り換えて,exit_kernelへ分岐する関数.ext_kerか ら呼び出される.exit_kernelからはリターンすることがないため,この関数に 戻ってくることは考える必要がない. 非タスクコンテキストに切り換えるのは,終了処理ルーチンを,非タスクコン テキスト用のスタックで実行するためである.終了処理ルーチンをタスク用の スタックで実行すると,各タスクのスタック領域のサイズを決定する際に,終 了処理ルーチンが使用するスタック領域を考慮しなければならない.これには, 終了処理ルーチンが使用するスタック領域が大きい場合に各タスクのスタック 領域を無駄に大きくしなければならないことに加えて,意図しないスタックオー バーフローが発生する可能性を高めるという問題がある. この関数は,全割込みロック状態で呼ばれるため,全割込みロック状態から呼 び出すことができない関数を呼ばないように実装しなければならない. (6-8-4) void target_exit(void) ターゲット依存部の終了処理を行う関数.この関数は,カーネル終了処理の最 後に呼び出され,リターンしてはならない.開発環境依存/プロセッサコア依 存/チップ依存の終了処理を,それらの依存部に切り分けることも可能である. この関数では,最初に,atexitによって登録された関数とデストラクタを呼び 出すことを意図しており,標準的には,software_term_hookを呼び出す. software_term_hookが用意されていない場合は,何もしない.GNU開発環境では, リンカスクリプト中のweak definitionにより,software_term_hookが用意され ていない場合の値を0とすることで,これを実現できる.weak definitionの機 能を持たない開発環境では,software_term_hookを必ず呼び出すことにする. この関数は,全割込みロック状態で呼ばれるため,全割込みロック状態から呼 び出すことができない関数を呼ばないように実装しなければならない. 6.9 カーネル内部のチューニング 6.9.1 ビットマップサーチ (6-9-1-1) OMIT_BITMAP_SEARCH(オプション) (6-9-1-2) uint_t bitmap_search(uint16_t bitmap)(オプション) ターゲット非依存部で,uint16_t型の整数値(bitmap)中の1のビットの内,最 も下位(右)のものをサーチし,そのビット番号を返す関数bitmap_searchを用 意している.ここで,ビット番号は最下位ビットを0とし,bitmapに0を指定し てはならないものとしている. ビットサーチ命令を持つプロセッサでは,bitmap_searchを,ビットサーチ命令 を使うように書き直した方が効率が良い場合がある.このような場合には,ター ゲット依存部でビットサーチ命令を使ったbitmap_searchを定義し, OMIT_BITMAP_SEARCHをマクロ定義する. 標準ライブラリにビットサーチ命令を用いたffsがある場合,bitmap_searchを (ffs(bitmap) - 1)に定義するとよい. (6-9-1-3) uint16_t PRIMAP_BIT(PRI pri)(オプション) ビットサーチ命令のサーチ方向が逆などの理由で,優先度とビットとの対応を 変更したい場合には,PRIMAP_BITをマクロ定義する. 6.9.2 ビットフィールド (6-9-2-1) BIT_FIELD_UINT(オプション) 8ビット以下の幅のビットフィールドで,符号無し整数値を保持したい場合に用 いるべきデータ型.デフォルトの定義はunsigned intとなっているが,ターゲッ トやツール依存で,unsigned charまたはunsigned shortに定義した方が効率が 良い場合がある. (6-9-2-2) BIT_FIELD_BOOL(オプション) 1ビット幅のビットフィールドで,ブール値を保持したい場合に用いるべきデー タ型.デフォルトではBIT_FIELD_UINTと同一に定義しているが,ブール値を保 持することを明示するために別の名前としている. (6-9-2-3) TBIT_TCB_PRIORITY(オプション) 現在優先度(および,ミューテックス拡張におけるベース優先度)を保持する ためのTCB中のフィールドのビット数.デフォルトでは8ビットに定義している が,それ以外に定義したい場合に,ビット数をこの名前にマクロ定義する. 6.10 カーネル実装に関するその他の定義 6.10.1 ターゲット依存のオブジェクト属性 (6-10-1-1) TARGET_TSKATR(オプション) ターゲット定義のタスク属性 (6-10-1-2) TARGET_ISRATR(オプション) ターゲット定義のISR属性 (6-10-1-3) TARGET_INHATR(オプション) ターゲット定義の割込みハンドラ属性 (6-10-1-4) TARGET_INTATR(オプション) ターゲット定義の割込み属性 (6-10-1-5) TARGET_EXCATR(オプション) ターゲット定義のCPU例外ハンドラ属性 各オブジェクトの属性を,ターゲット定義に拡張する場合に,該当するオブジェ クト属性を示す変数に,拡張に使用するビットの論理和を定義する.これによ り,拡張に使用するビットが設定されている場合に,エラーになるのを防ぐ. なお,TOPPERS新世代カーネル統合仕様書では,割込みサービスルーチン(ISR) 属性をターゲット定義で拡張できる仕様とはなっていない. 6.10.2 エラーチェック方法の指定 (6-10-2-1) TARGET_MIN_STKSZ(オプション) ターゲット定義で,タスクのスタックサイズの最小値を設定する場合には,こ の変数をスタックサイズの最小値に定義する. (6-10-2-2) TARGET_MIN_ISTKSZ(オプション) ターゲット定義で,非タスクコンテキストのスタックサイズの最小値を設定す る場合には,この変数をスタックサイズの最小値に定義する. (6-10-2-3) CHECK_STKSZ_ALIGN(オプション) スタック領域のサイズがある値(アライン単位)の倍数でなければならない場 合に,この変数をアライン単位に定義する.この変数を定義することで, kernel.tfおよびacre_tsk(動的生成機能拡張パッケージのみ)において,スタッ ク領域のサイズが正しくない(この変数に定義した値の倍数でない)場合のエ ラーをチェックするようになる.チェックが必要ない場合には,この変数を定 義しない. (6-10-2-4) CHECK_INTPTR_ALIGN(オプション) intptr_t型の変数のアライン単位 (6-10-2-5) CHECK_INTPTR_NONNULL(オプション)intptr_t型の変数の非NULLチェック (6-10-2-6) CHECK_FUNC_ALIGN(オプション) 処理単位のアライン単位 (6-10-2-7) CHECK_FUNC_NONNULL(オプション) 処理単位の非NULLチェック (6-10-2-8) CHECK_STACK_ALIGN(オプション) スタック領域のアライン単位 (6-10-2-9) CHECK_STACK_NONNULL(オプション)スタック領域の非NULLチェック (6-10-2-10) CHECK_MPF_ALIGN(オプション) 固定長メモリプール領域のアライン単位 (6-10-2-11) CHECK_MPF_NONNULL(オプション) 固定長メモリプール領域の非NULL チェック intptr_t型の変数/処理単位/スタック領域/固定長メモリプール領域の先頭 番地がある値(アライン単位)の倍数でなければならない場合に,それぞれ, CHECK_INTPTR_ALIGN/CHECK_FUNC_ALIGN/CHECK_STACK_ALIGN/ CHECK_MPF_ALIGNをアライン単位に定義する.intptr_t型の変数/処理単位/ス タック領域/固定長メモリプール領域の先頭番地がNULLでないかのチェックを 行う場合には,それぞれCHECK_INTPTR_NULL/CHECK_FUNC_NONNULL/ CHECK_STACK_NONNULL/CHECK_MPF_NONNULLを定義する. (6-10-2-12) CHECK_MB_ALIGN(オプション) 管理領域のアライン単位 カーネル内の管理領域(具体的には,データキュー管理領域,優先度データ キュー管理領域,固定長メモリプール管理領域)の先頭番地がある値(アライ ン単位)の倍数でなければならない場合に,この変数をアライン単位に定義す る.動的生成機能拡張パッケージを使用しない場合には,定義する必要がない. 6.10.3 非タスクコンテキスト用のスタック領域 (6-10-3-1) DEFAULT_ISTKSZ DEF_ICSにより非タスクコンテキスト用のスタック領域が指定されない場合の, デフォルトのスタック領域のサイズ. (6-10-3-2) DEFAULT_ISTK(オプション) DEF_ICSにより非タスクコンテキスト用のスタック領域が指定されない場合の, デフォルトのスタック領域の先頭番地.このマクロが定義されない場合には, サイズがDEFAULT_ISTKSZのスタック領域が,配列により確保される. (6-10-3-3) STK_T *TOPPERS_ISTKPT(STK_T *istk, size_t istksz)(オプション) 非タスクコンテキスト用のスタックポインタの初期値を保持する変数(istkpt) を用いる場合に,このシンボルに,スタック領域の先頭番地(istk)とスタッ ク領域のサイズ(istksz)から,スタックポインタの初期値を求めるマクロを 定義する. 6.10.4 空ラベルの定義 (6-10-4-1) TOPPERS_EMPTY_LABEL(type, symbol)(オプション) リンクエラーを防ぐために,データ型typeの配列である変数symbolに定義を与 えるためのマクロ.与えた定義が参照されることはないため,どのような定義 を与えてもよい. デフォルトでは,symbolを,要素型がtypeでサイズが0の配列に定義している. サイズが0の配列がエラーとならないコンパイラ(GCCはこれに該当)を用いる 場合には,ターゲット依存部で定義する必要はない. 6.11 トレースログ機能に関する設定 ASP3カーネルのソースコードには,カーネルの実行トレースログを取得するた めのマクロ等が埋め込んである.デフォルトでは,これらのマクロは空に定義 されてトレースログの取得は行わないが,これらのマクロを適切に定義するこ とでトレースログの取得を行うことができる. 6.11.1 取得できるトレースログの種類とマクロ 取得できるトレースログの種類と,それを取得するために定義するマクロは次 の通りである. (a) カーネルの動作開始と終了 次のマクロを定義することで,カーネルの動作開始時と終了時のトレースログ を取得することができる. LOG_KER_ENTER カーネルが動作を開始する直前(初期化の完了後) LOG_KER_LEAVE カーネルの終了(ext_ker)が呼ばれた直後(終了処 理の実行前) (b) 処理単位の実行開始と終了 次のマクロを定義することで,割込みハンドラ(INH),割込みサービスルーチ ン(ISR),周期ハンドラ(CYC),アラームハンドラ(ALM),CPU例外ハンド ラ(EXC)の実行開始前と終了後のトレースログを取得することができる. LOG_<処理単位略号>_ENTER 処理単位の実行開始直前 LOG_<処理単位略号>_LEAVE 処理単位の終了直後 割込みハンドラは,アプリケーションが登録したもののみを対象とし,割込み サービスルーチンを呼び出すためにカーネル内に生成されるものは対象としな い.タスクの実行開始と終了は,他の方法で取得できるため,この方法は用意 していない. なお,割込みハンドラとCPU例外ハンドラの実行開始と終了のトレースログ取得 は,ターゲット依存部で実装する必要がある.詳しくは,「6.2 トレースログ 機能への対応」「6.6.1 割込みハンドラの出入口処理」「6.7.1 CPU例外ハンド ラの出入口処理」の節を参照すること. (c) タスク状態の変化 次のマクロを定義することで,タスク状態が変化した時のトレースログを取得 することができる.ただし,実行状態と実行可能状態の間の遷移は,他の方法 で取得できるため,このマクロでは取得できない. LOG_TSKSTAT タスク状態の変化 (d) ディスパッチャの実行開始と終了 次のマクロを定義することで,ディスパッチャが実行開始する時と,終了する 時のトレースログを取得することができる. LOG_DSP_ENTER ディスパッチャの実行開始 LOG_DSP_LEAVE ディスパッチャの終了 ディスパッチャの実行開始は,タスクが実行状態から実行可能状態に遷移する タイミングであるため,実行可能状態へ遷移するタスクのTCBへのポインタをパ ラメータとする.逆に,ディスパッチャの終了は,タスクが実行可能状態から 実行状態に遷移するタイミングであるため,実行状態へ遷移するタスクのTCBへ のポインタをパラメータとする. ASP3カーネルでは,実行できるタスクがなく,カーネルがアイドル状態になる 場合には,ディスパッチャの中に留まる.そのため,アイドル状態への遷移と アイドル状態から他の状態への遷移は,このマクロでは取得できない. なお,ディスパッチャの実行開始と終了のトレースログ取得は,ターゲット依 存部で実装する必要がある.詳しくは,「6.2 トレースログ機能への対応」と 「6.5.2 ディスパッチャ本体」の節を参照すること. (e) サービスコールの入口と出口 次のマクロを定義することで,各サービスコールの入口と出口のトレースログ を取得することができる. LOG_<サービスコールの大文字表記>_ENTER サービスコール名の入口 LOG_<サービスコールの大文字表記>_LEAVE サービスコール名の出口 それぞれのマクロの名称やパラメータの詳細については,カーネルのソースコー ドを参照すること. 6.11.2 トレースログ記録のサンプルコード トレースログを記録する方法の一例として,メモリ上にトレースログを記録す るためのサンプルコードをarch/logtraceディレクトリに用意している.このサ ンプルコードは,システムログ機能と同様のトレースログ機能を用意し,トレー スログ情報をメモリ上に記録するとともに,それを読み出して表示する機能を 実現している. このサンプルコードを組み込む方法は次の通りである. (1) target_kernel_impl.hおよびtarget_syssvc.hに,次の記述を追加する. #ifdef TOPPERS_ENABLE_TRACE #include "arch/logtrace/trace_config.h" #endif /* TOPPERS_ENABLE_TRACE */ (2) Makefile.targetに,次の記述を追加する. ifeq ($(ENABLE_TRACE),true) COPTS := $(COPTS) -DTOPPERS_ENABLE_TRACE KERNEL_DIRS := $(KERNEL_DIRS) $(SRCDIR)/arch/logtrace KERNEL_COBJS := $(KERNEL_COBJS) trace_config.o trace_dump.o endif (3) スタートアップモジュールで,bssセクションのクリアを省略している場合 には,trace_modeをTRACE_STOP(=0)に初期化するコードを追加する.こ れは,トレースログ機能が初期化される前に書き込まれるトレースログを 無視するためである. このサンプルコードを用いて,トレースログを記録・ダンプする方法の例につ いては,「TOPPERS/ASP3カーネル ユーザーズマニュアル」の「11.6 トレース ログ記録のサンプルコードの使用方法」の節を参照すること. なお,このサンプルコードでは,ディスパッチャの出口,タスクの状態遷移, システムログの出力の3つのトレースログのみを記録している.他のトレースロ グを記録したい場合には,trace_config.h(およびtrace_dump.c)を修正する 必要がある. 6.12 カーネル実装のターゲット依存部のためのリネーム記述 カーネル内部に閉じて使われる関数や変数などの名称で,オブジェクトファイ ルのシンボル表に登録されて外部から参照できる名称は,C言語レベルで,先頭 が"_kernel_"または"_KERNEL_"である名称としなければならないが,ASP3カー ネルでは,ソースコードをコンパクトに保ちつつこれを実現するために,リネー ム記述ファイルを導入している. 具体的には,リネームすべき名称をリストアップしたxxx_rename.defを用意し, このファイルからツール(utils/genrename)により,名称をリネームするため のマクロ定義を含むxxx_rename.hと,それらのマクロ定義を解除するための xxx_unrename.hを生成する.ツールの起動方法は次の通りである. % genrename xxx xxx_rename.defには,リネームすべき名称を1行に1つ記述する.xxxxという名 称が記述されている場合,xxx_rename.hには次のような記述が生成される. #define xxxx _kernel_xxxx #ifdef TOPPERS_LABEL_ASM #define _xxxx __kernel_xxxx #endif /* TOPPERS_LABEL_ASM */ また,xxx_unrename.hには次のような記述が生成される. #undef xxxx #ifdef TOPPERS_LABEL_ASM #undef _xxxx #endif /* TOPPERS_LABEL_ASM */ xxx_rename.defの中には,他のリネーム記述を取り込むために,「INCLUDE "yyy"」または「INCLUDE 」という記述を含めることができる.この記述 がされている場合,xxx_rename.hには「#include "yyy_rename.h"」または 「#include 」という記述が,xxx_unrename.hには「#include "yyy_unrename.h"」または「#include 」という記述が生成さ れる. xxx_rename.defの中の"#"で始まる行はコメントとして読み飛ばされる.また, 空行も無視される. カーネルのターゲット非依存部で使われる名称をリネームするために,kernel ディレクトリに,kernel_rename.defと,そこから生成したkernel_rename.hお よびkernel_unrename.hが用意されている.kernel_rename.defには, 「INCLUDE "target"」という記述が含まれており,ターゲット依存部のリネー ム記述を取り込むようになっている.ターゲット依存部で定義し,ターゲット 非依存部で参照される名称は,ターゲット依存部のリネーム記述に含める. ターゲット依存部では,ターゲット依存部で使われる名称をリネームするため に,target_rename.defと,そこから生成したtarget_rename.hおよび target_unrename.hを用意する.ターゲット依存部から開発環境依存部/プロセッ サコア依存部/チップ依存部を切り分ける場合には,target_rename.defに INCLUDE記述を入れ,開発環境依存部/プロセッサコア依存部/チップ依存部の リネーム記述を取り込むようにする. 6.13 高分解能タイマドライバ 高分解能タイマドライバは,カーネルがシステム時刻の更新に用いるため高分 解能タイマを抽象化するためのデバイスドライバである.高分解能タイマドラ イバに関連して,target_kernel.hまたはそこからインクルードされるファイル に含めるべき定義については,「5.3 高分解能タイマのタイマ周期とカウント 値の進み幅」の節を参照すること. 【TOPPERS/ASP1カーネルとの関係】 ASP3カーネルでは,タイムティックを用いない時間管理のために,高分解能タ イマを用いている.高分解能タイマを効率的に実現できないターゲットシステ ム向けには,高分解能タイマドライバを,タイムティックを用いて実装する方 法もある.この実装方法については,「6.13.4 タイムティックを用いたタイマ ドライバの実装」の節を参照すること. 6.13.1 高分解能タイマドライバのファイル構成 高分解能タイマドライバを組み込むための静的APIを記述したシステムコンフィ ギュレーションファイルを,target_timer.cfgに用意する.このファイルには, 高分解能タイマドライバを初期化するための初期化ルーチンの追加,高分解能 タイマドライバを終了させるための終了処理ルーチンの追加,高分解能タイマ 割込みのための割込みハンドラの定義(または,割込みサービスルーチンの生 成),高分解能タイマ割込みのための割込み要求ラインの属性の設定の静的 APIなどを含むことになる. 高分解能タイマドライバを呼び出すために必要な定義を含むヘッダファイルを, target_timer.hに用意する.また,高分解能タイマドライバの実装ファイルを target_timer.cに用意する. システム時刻の経過をきっかけに行う処理の多くは,タスクの起動や待ち解除 を行うものであるため,高分解能タイマ割込みの割込み優先度は,割込みの中 で最低の優先度で十分である.ただし,周期ハンドラやアラームハンドラの実 行開始遅れが問題になる場合には,高分解能タイマ割込みの割込み優先度をよ り高い値に設定したい.そこで,高分解能タイマ割込みの割込み優先度を変更 する方法を,ターゲット依存部のユーザーズマニュアルに記載すべきである. 6.13.2 高分解能タイマの操作と割込み処理 高分解能タイマドライバが提供する抽象化された高分解能タイマは,0から,1 マイクロ秒に1のペースでカウントアップし,タイマ周期に達したら0に戻るも のとする.1マイクロ秒に1のペースでカウントアップすれば,1ずつ連続してカ ウントアップしなくてもよい(例えば,2マイクロ秒毎に2ずつカウントアップ しても良い).タイマ周期はターゲット依存であるが,2^32以下であるものと する. (6-13-2-1) void target_hrt_initialize(intptr_t exinf) 高分解能タイマを初期化し,高分解能タイマの動作を開始させる. この関数は,target_timer.cfg中に記述する静的APIにより,初期化ルーチンと してカーネルに登録する.そのため,関数名を変更しても差し支えない. (6-13-2-2) void target_hrt_terminate(intptr_t exinf) 高分解能タイマの動作を停止させ,高分解能タイマ割込みを発生しないように する. この関数は,target_timer.cfg中に記述する静的APIにより,終了処理ルーチン としてカーネルに登録する.そのため,関数名を変更しても差し支えない. (6-13-2-3) HRTCNT target_hrt_get_current(void) 高分解能タイマの現在値を返す. (6-13-2-4) void target_hrt_set_event(HRTCNT hrtcnt) 高分解能タイマを,hrtcntで指定した値カウントアップしたら割込みを発生さ せるように設定する.割込みを発生させるタイミングがすでに設定されていた 場合は,それまでに設定されていたタイミングはキャンセルする.hrtcntに0が 渡されることはない(そのような場合には,target_hrt_raise_eventが呼ばれ る). 高分解能タイマのカウント値が1ずつ連続してカウントアップしない場合には, 割込みを発生させるタイミングを遅い方に丸める. (6-13-2-5) void target_hrt_raise_event(void) 高分解能タイマ割込みを即座に発生させる.ハードウェアの機能的にこれが実 現できない場合には,最小のカウントアップ値で割込みを発生させる方法,言 い換えると「target_hrt_set_event(1U)」で実現してもよい. (6-13-2-6) HRTCNT_BOUND 高分解能タイマに設定するカウントアップ値の上限値を,このマクロに定義す る.HRTCNT_BOUNDは,高分解能タイマのタイマ周期(TCYC_HRTCNT)からタイマ 割込みの遅延時間よりも長い値を減じた値に定義する.カーネルの実装上の都 合により,HRTCNT_BOUNDは,4,294,000,000未満の値に設定しなければならない. HRTCNT_BOUNDを設けている理由は,高分解能タイマをタイマ周期のぎりぎりで 割込みがかかるように設定した場合,割込みハンドラ内で高分解能タイマを読 んだ時点でタイマ周期を越えており,高分解能タイマが周回したことを見落と す可能性があるためである. (6-13-2-7) void target_hrt_handler(void) または void target_hrt_isr(intptr_t exinf) 高分解能タイマ割込みにより起動される割込み処理プログラム.割込みハンド ラとして実現する場合にはtarget_hrt_handler,割込みサービスルーチンとし て実現する場合にはtarget_hrt_isrの名称とする.ターゲット非依存部の signal_timeを呼び出す. target_hrt_handlerは,標準的には次のように定義する. ---------------------------------------- void target_hrt_handler(void) { 高分解能タイマ割込み要求のクリア(必要なら) signal_time(); } ---------------------------------------- この関数は,target_timer.cfg中に記述する静的APIにより,割込みハンドラま たは割込みサービスルーチンとしてカーネルに登録する.そのため,関数名を 変更しても差し支えない. 6.13.3 高分解能タイマドライバの実装アプローチ 高分解能タイマドライバは,ハードウェアで高機能なタイマを持っている場合 には,1つのタイマだけで実装できる可能性もある(タイマの機能による)が, そうでない場合には,タイマを2つ使って実装することを想定している. 具体的には,片方のタイマ(以下,これをタイマ1と呼ぶ)は,無限にカウント させ(必然的に巡回する),高分解能タイマの現在値を返すのに用い,もう片 方のタイマ(以下,これをタイマ2と呼ぶ)は,割込みを発生させるために用い る. この時,2つのタイマが全く同じタイミングでカウントアップ(またはカウント ダウン)していれば問題ないが,実際には,2つのタイマに別々にプリスケーラ が入っている場合や,2つのタイマを別のクロックで駆動する場合には,カウン トアップのタイミングがずれることも考えられる.このような場合には,以下 の制約を満たすように実装することが必要である. target_hrt_get_current()でタイマ値を読み,target_hrt_set_event(count)に よりタイマ割込みを発生させた後,target_hrt_get_current()でタイマ値を読 んだ場合には,2回のtarget_hrt_get_current()の呼び出しの間に,タイマ値が count以上進んでいなければならない. より厳密には,以下のシーケンスで高分解能タイマドライバを呼び出した場合 に,(count2 - count1 >= count)を満たさなければならない. count1 = target_hrt_get_current(); target_hrt_set_event(count); … ここで時間が経過 … 割込みが発生 count2 = target_hrt_get_current(); 素直に実装するとこの条件を満たさない場合には,target_hrt_set_eventで割 込みを発生させるタイミングを遅い方に調整する. 6.13.4 タイムティックを用いたタイマドライバの実装 ASP1カーネルと同様に,タイムティックによる時間管理を行いたい場合に,高 分解能タイマドライバをタイムティックを用いて実装することで,ターゲット 依存部のみの修正で対応することができる.ただし,この方法は,カーネルの 時間管理機能に手を加えるわけではないため,カーネルが不必要な仕事をして しまうことは許容する必要がある. タイムティックを用いて高分解能タイマドライバを実装する場合には,各マク ロおよび関数を次のように実装する. ・TCYC_HRTCNT(高分解能タイマのタイマ周期)は定義しない(タイマ周期が  2^32の意味になる). ・TSTEP_HRTCNT(高分解能タイマのカウント値の進み幅)を,タイムティック  の周期に定義する(単位はマイクロ秒). ・高分解能タイマの現時点の値を保持する変数(hrtcnt_current,HRTCNT型)  を用意する. ・target_hrt_initializeでは,タイマを初期化し,タイマ割込みを周期的に発  生させるようにする.また,hrtcnt_currentを0に初期化する. ・target_hrt_terminateでは,タイマの動作を停止させ,タイマ割込みを発生  しないようにする. ・target_hrt_get_currentは,hrtcnt_currentの値を返す. ・target_hrt_set_eventとtarget_hrt_raise_eventでは何もしない. ・HRTCNT_BOUNDは,4000000002に定義することを推奨する. ・target_hrt_handlerまたはtarget_hrt_isrは,(必要なら)タイマ割込み要  求をクリアし,hrtcnt_currentにタイムティックの周期を加えた後,ターゲッ  ト非依存部のsignal_timeを呼び出す. 6.14 オーバランタイマドライバ(オプション) オーバランタイマドライバは,カーネルがオーバランハンドラ機能の実現に用 いるためのオーバランタイマを抽象化するためのデバイスドライバである.オー バランハンドラ機能拡張パッケージをサポートしない場合には,オーバランタ イマドライバを用意する必要はない. 6.14.1 オーバランタイマドライバのファイル構成 オーバランタイマドライバは,高分解能タイマドライバと同じファイルの中に 記述する.オーバランタイマドライバのための記述は,TOPPERS_SUPPORT_OVRHDR がマクロ定義されている場合にのみ有効になるようにする. 具体的には,オーバランタイマドライバを組み込むための静的APIは target_timer.cfgの中に記述する.このファイルには,オーバランタイマドラ イバを初期化するための初期化ルーチンの追加,オーバランタイマドライバを 終了させるための終了処理ルーチンの追加,オーバランタイマ割込みのための 割込みハンドラの定義(または,割込みサービスルーチンの生成),オーバラ ンタイマ割込みのための割込み要求ラインの属性の設定の静的APIなどを含むこ とになる. また,オーバランタイマドライバを呼び出すために必要な定義は target_timer.hの中に,オーバランタイマドライバの実装はtarget_timer.cの 中に記述する. オーバランハンドラは,タスクのオーバランに対する処理を行うものであるた め,オーバランタイマ割込みの割込み優先度は,割込みの中で最低の優先度で 十分である.ただし,オーバランタイマ割込みの割込み優先度をより高い値に 設定したい場合もないとは言えないため,オーバランタイマ割込みの割込み優 先度を変更する方法を,ターゲット依存部のユーザーズマニュアルに記載すべ きである. 6.14.2 オーバランタイマの操作と割込み処理 (6-14-2-1) void target_ovrtimer_initialize(intptr_t exinf) オーバランタイマの初期化処理を行う.タイマの動作開始は行わない. この関数は,target_timer.cfg中に記述する静的APIにより,初期化ルーチンと してカーネルに登録する.そのため,関数名を変更しても差し支えない. (6-14-2-2) void target_ovrtimer_terminate(intptr_t exinf) オーバランタイマを停止させ,オーバランタイマ割込みを発生しないようにす る. この関数は,target_timer.cfg中に記述する静的APIにより,終了処理ルーチン としてカーネルに登録する.そのため,関数名を変更しても差し支えない. (6-14-2-3) void target_ovrtimer_start(PRCTIM ovrtim) オーバランタイマを,ovrtimで指定した時間が経過したら割込みが発生するよ うに設定し,動作開始する.ovrtimが0の場合は,できる限り早くオーバランタ イマ割込みを発生させる.ovrtimの単位はマイクロ秒とする. (6-14-2-4) PRCTIM target_ovrtimer_stop(void) オーバランタイマを停止し,タイマの残り時間(割込み発生までの時間)を返 す.残り時間がなくなっていた場合には,0を返す.また,オーバランタイマか らの割込み要求をクリアする(クリアしないとスプリアス割込みが発生するが, クリアすることは必須ではない). (6-14-2-5) PRCTIM target_ovrtimer_get_current(void) オーバランタイマの残り時間(割込み発生までの時間)を読み出す.残り時間 がなくなっていた場合には,0を返す.オーバランタイマからの割込みはクリア しない. (6-14-2-6) void target_ovrtimer_handler(void) または void target_ovrtimer_isr(intptr_t exinf) オーバランタイマ割込みにより起動される割込み処理プログラム.割込みハン ドラとして実現する場合にはtarget_ovrtimer_handler,割込みサービスルーチ ンとして実現する場合にはtarget_ovrtimer_isrの名称とする.ターゲット非依 存部のcall_ovrhdrを呼び出す. target_ovrtimer_handlerは,標準的には次のように定義する. ---------------------------------------- void target_ovrtimer_handler(void) { オーバランタイマ割込み要求のクリア(必要なら) call_ovrhdr(); } ---------------------------------------- この関数は,target_timer.cfg中に記述する静的APIにより,割込みハンドラま たは割込みサービスルーチンとしてカーネルに登録する.そのため,関数名を 変更しても差し支えない. (6-14-2-7) OMIT_OVRTIMER_START(オプション) (6-14-2-8) OMIT_OVRTIMER_STOP(オプション) ターゲット依存部から呼び出すovrtimer_startとovrtimer_stopを,アセンブリ 言語のソースコード中に展開し,C言語の関数が不要になる場合には,それぞれ, OMIT_OVRTIMER_STARTとOMIT_OVRTIMER_STOPをマクロ定義する. 6.15 動的メモリ管理(オプション) 動的生成機能拡張パッケージを使用する場合には,カーネル内での動的メモリ 管理の方法を決める必要がある. 動的生成機能拡張パッケージのターゲット非依存部では,メモリ領域を先頭か ら順に割り当て,解放されたメモリ領域を再利用しないメモリ管理モジュール のみを実装している.デフォルトでは,このメモリ管理モジュールが使用され る. 本格的な動的メモリ管理を行いたい場合には,ターゲット依存部またはユーザ 側で,以下の関数を定義したメモリ管理モジュールを用意する必要がある. (6-15-1) OMIT_KMM_ALLOCONLY(オプション) ターゲット非依存部のメモリ管理モジュールを使用せず,ターゲット依存部ま たはユーザ側で用意する場合には,このシンボルをマクロ定義する. (6-15-2) void initialize_kmm(void)(オプション) メモリ管理モジュールを初期化する関数.カーネルの割り付けるメモリ領域の サイズと先頭番地は,それぞれkmmszとkmmによって参照できる. (6-15-3) void *kernel_malloc(size_t size)(オプション) sizeで指定されたサイズのメモリ領域を割り付け,その先頭番地を返す関数. 割り付けることができない場合には,NULLを返す. (6-15-4) void kernel_free(void *ptr)(オプション) ptrで指定されたメモリ領域を解放する関数. 6.15.1 TLSFを用いたメモリ管理モジュールの例 オープンソースのメモリ割付けライブラリであるTLSFを用いて動的メモリ管理 を実現するには,OMIT_KMM_ALLOCONLYをマクロ定義し,以下の関数定義等をC言 語ソースファイルに含めればよい. ---------------------------------------- #include "tlsf.h" static bool_t tlsf_initialized = false; void initialize_kmm(void) { if (init_memory_pool(kmmsz, kmm) >= 0) { tlsf_initialized = true; } } void * kernel_malloc(size_t size) { if (tlsf_initialized) { return(malloc_ex(size, kmm)); } else { return(NULL); } } void kernel_free(void *ptr) { if (tlsf_initialized) { free_ex(ptr, kmm); } } ---------------------------------------- 7.コンフィギュレータ設定ファイルのターゲット依存部 7.1 設定ファイルとターゲット依存部の位置付け ASP3カーネルのコンフィギュレータは,設定ファイルの記述に従ってファイル の生成およびエラーチェックを行う.コンフィギュレータの設定ファイルには, 以下の4つがある. (a) 静的APIテーブル 静的APIの一覧と,各静的APIのパラメータについて記述したファイル.静的 APIを拡張する場合以外は変更する必要がないため,ターゲット非依存部で用意 している(kernel/kernel_api.csv). (b) 値取得シンボルテーブル コンフィギュレータのパス1において,パラメータ計算用C言語ファイルに出力 し,値を求めたいシンボル(一般には式)を記述するためのファイル.ターゲッ ト非依存部では,ターゲットに依存せずに必要となるシンボルを記述したファ イルを用意している(kernel/kernel_def.csv). ターゲットに依存して必要となるシンボルがある場合には,targetディレクト リに置かれたtarget_def.csv中に記述する.target_def.csv中に記述して値を 求めることができるシンボルは,kernel/kernel_int.hおよびそこからインクルー ドされるファイルで定義されていなければならない.kernel_int.hからは, target_stddef.h,target_kernel.h,target_kernel_impl.hを(間接的に)イ ンクルードしているため,これらのファイルおよびそこからインクルードされ るファイルで定義されるターゲット依存のシンボルは,target_def.csv中に記 述することができる. ここで値を求めたシンボルの値は,コンフィギュレータのパス2およびパス3の テンプレートファイル中で参照することができる. (c) パス2のテンプレートファイル コンフィギュレータのパス2は,テンプレートファイルに従って,カーネルの構 成・初期化ファイル(kernel_cfg.c),構成・初期化ヘッダファイル (kernel_cfg.h)などを生成する.このテンプレートファイルは,ターゲット 非依存部とターゲット依存部に切り分けてあるが,他のファイルのターゲット 依存部とは逆に,ターゲット依存部からターゲット非依存部をインクルードす る形になっている. 具体的には,targetディレクトリに置かれたtarget.tfで,必要な変数を定義し た後,テンプレートファイルのターゲット非依存部(kernel/kernel.tf)をイ ンクルードする.kernel.tfでは,カーネルのターゲット非依存部で使用する変 数定義等を生成する.kernel.tfをインクルードした後,target.tfでは,カー ネルのターゲット依存部で使用する変数定義等を生成する.target.tfから,開 発環境依存部/プロセッサコア依存部/チップ依存部を切り分けてもよい. (d) パス3のテンプレートファイル コンフィギュレータのパス3は,テンプレートファイルに従って,静的APIの一 般定数式パラメータのチェックを行う.このテンプレートファイルも,ターゲッ ト非依存部とターゲット依存部に切り分けてあり,ターゲット依存部からター ゲット非依存部をインクルードする形になっている. 具体的には,targetディレクトリに置かれたtarget_check.tfで,必要な変数を 定義した後,テンプレートファイルのターゲット非依存部 (kernel/kernel_check.tf)をインクルードする.kernel_check.tfでは,カー ネルのターゲット非依存部で初期化ブロックに出力した一般定数式パラメータ のチェックを行う.kernel_check.tfをインクルードした後,target_check.tf では,ターゲットに依存するチェックを行う.target_check.tfから,開発環境 依存部/プロセッサコア依存部/チップ依存部を切り分けてもよい. なお,コンフィギュレータの詳細仕様と設定ファイルの記述方法については, 別途PDFファイルの形で配布している「TOPPERS新世代カーネル用コンフィギュ レータ仕様」および「TOPPERS新世代カーネル用コンフィギュレータ内蔵マクロ プロセッサ仕様」を参照すること. 7.2 パス2のテンプレートファイルのターゲット依存部 以下では,パス2のテンプレートファイルのターゲット依存部を記述する上で必 要な事項について説明する. 7.2.1 ターゲット非依存部をインクルードする前に定義すべき変数 target.tfからkernel.tfをインクルードする前に,次の変数を定義しておかな ければならない. (7-2-1-1) INTNO_VALID 有効な割込み番号のリスト (7-2-1-2) INHNO_VALID 有効な割込みハンドラ番号のリスト (7-2-1-3) EXCNO_VALID 有効なCPU例外ハンドラ番号のリスト 有効な割込み番号/割込みハンドラ番号/CPU例外ハンドラ番号のリストを,各 変数に定義する. (7-2-1-4) INTNO_CREISR_VALID(オプション) (7-2-1-5) INHNO_CREISR_VALID(オプション) CRE_ISRで使用できる割込み番号のリストをINTNO_CREISR_VALIDに,それに対応 する割込みハンドラ番号のリストをINHNO_CREISR_VALIDに定義する.両者は, 順序まで含めて対応していなければならない. これらの変数を定義しない場合,それぞれINTNO_VALIDとINHNO_VALIDが使われ る.それで良い場合には,これらの変数を定義する必要はない. (7-2-1-6) INTPRI_CFGINT_VALID(オプション) CFG_INTで使用できる割込み優先度のリストを定義する変数.標準では, TMIN_INTPRI以上,TMIN_INTPRI(=-1)以下の値がCFG_INTに対する割込み優先 度として有効であるが,ターゲット依存部でこの変数を定義することで, TMIN_INTPRIよりも小さい値を有効とすることができる. (7-2-1-7) INTNO_FIX_KERNEL(オプション) カーネル管理に固定されている 割込み番号 (7-2-1-8) INHNO_FIX_KERNEL(オプション) カーネル管理に固定されている 割込みハンドラ番号 (7-2-1-9) INHNO_FIX_NONKERNEL(オプション) カーネル管理外に固定されている 割込み番号 (7-2-1-10) INHNO_FIX_NONKERNEL(オプション)カーネル管理外に固定されている 割込みハンドラ番号 カーネル管理またはカーネル管理外に固定されている割込みがある場合には, それらの割込み番号と割込みハンドラ番号のリストを,各変数に定義する. (7-2-1-11) GENERATE_TSKINICTXB(オプション) USE_TSKINICTXBをマクロ定義した場合,TSKINICTXBの初期化情報を生成するた めテンプレートファイル関数GENERATE_TSKINICTXBを定義する. GENERATE_TSKINICTXBには,タスクIDがパラメータとして渡される. (7-2-1-12) ALLOC_STACK(オプション) スタック領域の生成方法をデフォルトから変更したい場合には,スタック領域 を生成するためのテンプレートファイル関数ALLOC_STACKを定義する. ALLOC_STACKには,スタック領域の変数名と丸める前のサイズがパラメータとし て渡されるので,スタック領域を生成するコードを生成し,大きい方に丸めた サイズを表す文字列を返す. 7.2.2 ターゲット非依存部で定義される変数 kernel.tfの中では次の変数が定義されるため,kernel.tfをインクルードした 後,target.tfの中でこれらを参照することができる. (7-2-2-1) INTNO[inhno] inhnoを対応するintnoに変換するための連想配列 (7-2-2-2) INHNO[intno] intnoを対応するinhnoに変換するための連想配列 7.3 パス3のテンプレートファイルのターゲット依存部 以下では,パス3のテンプレートファイルのターゲット依存部を記述する上で必 要な事項について説明する. 7.3.1 ターゲット非依存部をインクルードする前に定義すべき変数 target_check.tfからkernel_check.tfをインクルードする前に,必要に応じて, 次の変数を定義しておかなければならない. (7-3-1-1) GET_STK_TSKINICTXB(オプション) USE_TSKINICTXBをマクロ定義した場合,TINIBからスタック領域の先頭番地を取 り出すためのテンプレートファイル関数GET_STK_TSKINICTXBを定義する. GET_STK_TSKINICTXBには,タスク初期化ブロック(TINIB)の先頭番地がパラメー タとして渡される.CHECK_STACK_ALIGN,CHECK_STACK_NONNULLとも定義しない 場合には,GET_STK_TSKINICTXBを定義する必要はない. (7-3-1-2) LMA.ORDER_LIST(オプション) (7-3-1-3) LMA.START_DATA[lmano](オプション) (7-3-1-4) LMA.END_DATA[lmano](オプション) (7-3-1-5) LMA.START_IDATA[lmano](オプション) パス3のテンプレートファイルのターゲット依存部でdataセクションからデータ を取得する場合や,rodataセクションをRAMに置く場合(ユーザーズマニュアル の「11.8 rodataセクションをRAMに置く場合」の節を参照)には,これらのセ クションの内容を,配置アドレス(ROM内のアドレス,LMAと呼ぶ)からアクセ スアドレス(RAM内のアドレス,VMAと呼ぶ)にコピーする必要がある. このコピーは,LMA.ORDER_LISTに,コピーするセクションの番号(lmano)のリ スト(番号は任意に付与してよい),LMA.START_DATA[lmano]にコピーするセク ションのアクセスアドレスの先頭のラベル,LMA.END_DATA[lmano]に末尾のラベ ル,LMA.START_IDATA[lmano]にその配置アドレスの先頭のラベルを設定するこ とで,パス3のテンプレートファイルのターゲット非依存部で実施する. 例えば,コピーするセクションのアクセスアドレスの先頭のラベルが "__data_start",末尾のラベルが"__data_end",その配置アドレスの先頭のラ ベルが"__idata_start"の場合には,パス3のテンプレートファイルのターゲッ ト依存部に以下の記述を含める. ---------------------------------------- $LMA.ORDER_LIST = { 1 }$ $LMA.START_DATA[1] = "__data_start"$ $LMA.END_DATA[1] = "__data_end"$ $LMA.START_IDATA[1] = "__idata_start"$ ---------------------------------------- 7.3.2 ターゲット依存部で行うべきエラーチェック 以下の先頭番地は,ターゲット非依存部で生成するテーブルに出力されないた め,パス3のターゲット非依存部(kernel_check.tf)では,プログラムの開始 番地として正しくない場合のエラーをチェックしない.そのため,ターゲット 依存部でエラーチェックを行う必要がある. ・割込みサービスルーチンの先頭番地(CRE_ISRのisr) ・割込みハンドラの先頭番地(DEF_INHのinthdr) ・CPU例外ハンドラの先頭番地(DEF_EXCのexchdr) ・初期化ルーチンの先頭番地(ATT_INIのinirtn) ・終了処理ルーチンの先頭番地(ATT_TERのterrtn) ただし,ターゲット依存部においても,これらのエラーチェックを行えるとは 限らないため,ユーザーズマニュアルの「1.5 既知の問題」の節には,ターゲッ ト依存でこれらのエラーが検出されないことがある旨を記載してある. 7.4 cfg1_out.cのリンクに必要なスタブの定義ファイル コンフィギュレータに関してターゲット依存に用意する必要があるファイルと して,設定ファイル以外に,cfg1_out.cをリンクするために必要なスタブの定 義ファイルがある. コンフィギュレータのパス1では,静的APIの整数定数式パラメータの値をCコン パイラを用いて求めるために,cfg1_out.cを生成する.これをコンパイル,リ ンクしてオブジェクトファイルを生成する際に,スタートアップモジュールか ら参照されるシンボルの定義を与える必要がある. この定義を与えるために,cfg1_out.cから,ターゲット依存部の target_cfg1_out.hをインクルードしている.target_cfg1_out.h(または,そ こからインクルードされるファイル)には,スタートアップモジュールから参 照されるシンボルのスタブの定義を含める.典型的には,以下のような定義を 含める必要がある. ---------------------------------------- void sta_ker(void) { } void hardware_init_hook(void) { } void software_init_hook(void) { } const size_t _kernel_istksz = 0; STK_T *const _kernel_istk = NULL; ---------------------------------------- また,target_cfg1_out.h(または,そこからインクルードされるファイル)に は,コンフィギュレータを用いてオフセットファイル(offset.h)を生成する ために必要な記述を含める.詳しくは,「2.5 オフセットファイルの生成方法」 の節を参照すること. 8.システムサービス等のターゲット依存部 8.0 システムサービスのターゲット依存部 シリアルポート数やシステムログタスク関連の定数など,システムサービスの 構成を決定するための定義をtarget_syssvc.hまたはそこからインクルードされ るファイル(開発環境依存部/プロセッサコア依存部/チップ依存部で用意さ れるヘッダファイルなど)に含める. なお,TOPPERS組込みコンポーネントシステムが導入されると,このファイルの 内容はコンポーネント記述ファイルに記述されることになり,このファイルは 無くなる(または,大幅に縮小される)見込みである. 8.1 システムログ機能のターゲット依存定義 システムログ機能を使用する場合で,スタートアップモジュールでbssセクショ ンのクリアを省略している場合には,syslog_logmaskとsyslog_lowmask_notを 0に初期化するコードを追加する.これは,システムログ機能が初期化される前 に出力されたログ情報を,低レベル出力機能を用いて出力するためである. ターゲット依存部で提供すべきシステムログ機能のための定義は次の通りであ る. (8-1-1) TCNT_SYSLOG_BUFFER(オプション) システムログ機能のログバッファのサイズを定義するマクロ.定義しない場合 のデフォルト値は32. (8-1-2) void target_fput_log(char c) システムログの低レベル出力のための文字出力関数.ターゲット依存の方法で, 文字cを表示/出力/保存する. この関数は,リエントラントに実装しなければならない.この関数内で排他制 御が必要な場合には,SILを用いて全割込みロック状態にすること.また,全割 込みロック状態で呼ばれる場合があるため,全割込みロック状態から呼び出す ことができない関数を呼ばないように実装しなければならない. 低レベル出力をシリアルポート経由で行う場合で,シリアルインタフェースド ライバとポートを共用しないことが望ましいが,ポート数が足りないためにや むをえず共用する場合には,両者が競合しないように注意が必要である.具体 的には,両者が同じ設定でシリアルI/Oデバイスを使うようにし,シリアルイン タフェースドライバの動作中に低レベル出力が行われても差し支えないように 設計する.また,低レベル出力が動作開始後にシリアルインタフェースドライ バがシリアルI/Oデバイスを初期化すると,文字化けが起こる可能性がある.こ れを避けるためには,共用するポートは低レベル出力側で初期化し,シリアル インタフェースドライバでは初期化しないようにするとよい. なお,この関数の本体を,どのファイルに記述するかが問題になる.システム サービスのターゲット依存部には,標準では,関数定義を記述するためのファ イルを用意していない.ターゲット依存で用意してもよいが,例外的に,カー ネル実装のターゲット依存モジュール(target_kernel_impl.c)に記述しても よい.この場合,target_fput_logを,リネーム記述(target_rename.defなど) に含めてはならない. (8-1-3) LOGTIM,SYSLOG_GET_LOGTIM(オプション) システムログ機能において記録する時刻(ログ時刻)のデータ型をLOGTIMに, 時刻を取得するための処理をSYSLOG_GET_LOGTIMにマクロ定義する.これらを定 義しない場合,高分解能タイマのカウント値をログ時刻に用いる. なお,LOGTIMの定義は,target_stddef.hまたはそこからインクルードされるファ イルに含めなければならない. (8-1-4) LOGPAR,ULOGPAR(オプション) システムログ機能において記録するログパラメータのデータ型をLOGPARにマク ロ定義する.LOGPARに定義したデータ型は,符号付きの整数型でなければなら ない.また,LOGPARと同じサイズの符号無しの整数型を,ULOGPARにマクロ定義 する. これらの定義しない場合,ログパラメータのデータ型はintptr_tとする. なお,LOGPARおよびULOGPARの定義は,target_stddef.hまたはそこからインク ルードされるファイルに含めなければならない. 8.2 システムログタスクのターゲット依存定義 ターゲット依存部で提供すべきシステムログタスクのための定義は次の通りで ある.これらの定義は,target_syssvc.hまたはそこからインクルードされるファ イルに含める. (8-2-1) LOGTASK_PRIORITY(オプション) システムログタスクの優先度を定義するマクロ.定義しない場合のデフォルト 値は3. (8-2-2) LOGTASK_STACK_SIZE(オプション) システムログタスクのスタックサイズを定義するマクロ.定義しない場合のデ フォルト値は1024. (8-2-3) LOGTASK_PORTID(オプション) システムログタスクの出力先のシリアルポート番号.定義しない場合のデフォ ルト値は1. (8-2-4) LOGTASK_INTERVAL(オプション) システムログタスクの動作間隔(単位はマイクロ秒).定義しない場合のデフォ ルト値は10000. (8-2-5) LOGTASK_FLUSH_WAIT(オプション) ログ出力を待ち合わせる処理において,タスクを待たせる単位となる時間(単 位はマイクロ秒).定義しない場合のデフォルト値は1000. 8.3 シリアルインタフェースドライバのターゲット依存部 ターゲット依存部で提供すべきシリアルインタフェースドライバのための定義 は次の通りである.これらの定義は,別に指定がない限り,target_serial.hま たはそこからインクルードされるファイルに含め,必要なコンフィギュレーショ ン情報をtarget_serial.cfgに記述する.関数の実体が必要な場合には, target_serial.c等のファイルを用意する. シリアルインタフェースドライバの中で,ターゲットのシリアルI/Oデバイスに 依存する部分を,シリアルI/Oデバイスドライバと呼ぶ.シリアルI/Oデバイス ドライバは,おおよそ,ITRONデバイスドライバ設計ガイドラインのPDICに相当 する. 8.3.1 変数,データ型,管理関数 (8-3-1-1) TNUM_PORT シリアルインタフェースドライバがサポートするシリアルポート数を定義する マクロ.このマクロの定義は,target_syssvc.hまたはそこからインクルードさ れるファイルに含める. (8-3-1-2) void sio_initialize(intptr_t exinf)(オプション) シリアルI/Oデバイスドライバの初期化処理.target_serial.cfgに,この関数 を初期化ルーチンとして登録する静的APIを含める. (8-3-1-3) void sio_terminate(intptr_t exinf)(オプション) シリアルI/Oデバイスドライバの終了処理.target_serial.cfgに,この関数を 終了処理ルーチンとして登録する静的APIを含める. (8-3-1-4) void sio_isr(intptr_t exinf) シリアルI/Oデバイスの割込みサービスルーチン.target_serial.cfgに,この 関数を割込みサービスルーチンとして登録する静的APIを含める.また,その静 的APIに必要なシリアルI/Oデバイスの割込み番号などは,target_serial.hでマ クロ定義する.割込みサービスルーチンではなく,割込みハンドラとすること もできる. (8-3-1-5) SIOPCB シリアルI/Oポート管理ブロックのデータ型(target_serial.hには,データ型 の宣言だけ含まれていればよい). (8-3-1-6) SIO_RDY_SNDとSIO_RDY_RCV 送信可能コールバックの識別番号をSIO_RDY_SNDに,受信通知コールバックの識 別番号をSIO_RDY_RCVにマクロ定義する.コールバックの禁止/許可を行なうサー ビスコール(sio_ena_cbrとsio_dis_cbr)で用いる. 8.3.2 デバイスサービスルーチン 以下のデバイスサービルルーチンは,(少なくとも)シリアルI/Oポートからの 割込みがマスクされた状態で呼び出される.また,タスクコンテキスト,非タ スクコンテキストのいずれで呼び出される場合もある(いずれで呼び出されて も動作するようにしなければならない). (8-3-2-1) SIOPCB *sio_opn_por(ID siopid, intptr_t exinf) siopidで指定されるシリアルI/Oポートをオープンする関数.exinfはシリアル I/Oポートに対する拡張情報で,コールバックを呼ぶ時にポートを区別するた めに渡す. (8-3-2-2) void sio_cls_por(SIOPCB *siopcb) siopcbで指定されるシリアルI/Oポートをクローズする関数. (8-3-2-3) bool_t sio_snd_chr(SIOPCB *siopcb, char c) siopcbで指定されるシリアルI/Oポートに,cで示される文字を送信する関数. 文字を送信レジスタに入れた場合にはtrueを,前に送信した文字の送信が終わっ ていないために,文字を送信レジスタに入れられなかった場合にはfalseを返す. (8-3-2-4) int_t sio_rcv_chr(SIOPCB *siopcb) siopcbで指定されるシリアルI/Oポートから文字を読む関数.文字を受信してい た場合,読んだ文字のコードは正の値として返し,文字を受信していない場合 には-1を返す. (8-3-2-5) void sio_ena_cbr(SIOPCB *siopcb, uint_t cbrtn) siopcbで指定されるシリアルI/Oポートからの,cbrtnで指定されるコールバッ クを許可する.cbrtnには,SIO_RDY_SNDかSIO_RDY_RCVを指定できる. (8-3-2-6) void sio_dis_cbr(SIOPCB *siopcb, uint_t cbrtn) siopcbで指定されるシリアルI/Oポートからの,cbrtnで指定されるコールバッ クを禁止する.cbrtnには,SIO_RDY_SNDかSIO_RDY_RCVを指定できる. 8.3.3 コールバックルーチン ターゲット依存部は,必要なタイミングで,シリアルインタフェースドライバ のターゲット非依存部に含まれる以下のコールバックルーチンを呼び出びださ なければならない.ただし,それぞれのコールバックが禁止されている時は, コールバックルーチンを呼び出してはならない. コールバックルーチンは,(少なくとも)シリアルI/Oポートからの割込みが禁 止された状態で,非タスクコンテキストで呼び出す.exinfには,シリアルI/O ポートのオープン時に指定された拡張情報を渡す. (8-3-3-1) void sio_irdy_snd(intptr_t exinf) 送信可能コールバックルーチン.シリアルI/Oポートに対して文字が送信できる 状態になった場合に呼び出す.シリアルインタフェースドライバは,このコー ルバックルーチンの中で,sio_snd_chrを呼び出して次の文字を送信するか,送 信すべき文字がない場合には送信可能コールバックを禁止する. (8-3-3-2) void sio_irdy_rcv(intptr_t exinf) 受信通知コールバックルーチン.シリアルI/Oポートから文字を受信した場合に 呼び出す.シリアルインタフェースドライバは,このコールバックルーチンの 中で,必ずsio_rcv_chrを呼び出して受信した文字を取り出す. 8.4 カーネル起動メッセージの出力のターゲット依存定義 ターゲット依存部で提供すべきカーネル起動メッセージの出力のための定義は 次の通りである. (8-4-1) TARGET_NAME ターゲットの名称に定義する. (8-4-2) TARGET_COPYRIGHT(オプション) カーネル起動メッセージに,ターゲット依存部の著作権表示を追加するための マクロ.デフォルトでは,ターゲット依存部の著作権表示を追加しない. 8.5 サンプルプログラムとテストプログラムのターゲット依存定義 ターゲット依存部で提供すべきサンプルプログラムおよびテストプログラムの ための定義は次の通りである.これらの定義は,target_test.h(またはそれら からインクルードされるファイル)に含める. (8-5-1) STACK_SIZE(オプション) サンプルプログラムおよびテストプログラムのタスクのスタックサイズを定義 するマクロ.定義しない場合のデフォルト値は4096.デフォルト設定ではメモ リが不足する場合や,シミュレーション環境などで大きいスタック領域が必要 な場合には,ターゲット依存部でこのマクロを設定するスタックサイズに定義 する. (8-5-2) CPUEXC1(オプション) サンプルプログラムおよびテストプログラムで用いるCPU例外のCPU例外ハンド ラ番号を定義するマクロ.このマクロを定義しない場合,CPU例外ハンドラを使 う部分がサンプルプログラムから除外される.CPU例外ハンドラのテストをする テストプログラムはコンパイルできない. (8-5-3) RAISE_CPU_EXCEPTION(オプション) CPUEXC1に定義したCPU例外を発生させるC言語のプログラムを定義するマクロ. CPUEXC1を定義した場合には必ず定義しなければならない. (8-5-4) PREPARE_RETURN_CPUEXC(オプション) CPU例外を起こした命令をスキップするために戻り番地を修正するなど,CPU例 外ハンドラからリターンできるように準備するためのマクロ.準備が必要ない 場合には,空に定義する. ターゲットシステムの制約により,CPU例外ハンドラからリターンした後に,タ スクの実行を継続できない場合には,このマクロを定義しない.このマクロを 定義しないと,CPU例外ハンドラのテストをするテストプログラムから,CPU例 外ハンドラからリターンした後の処理が除外される. (8-5-5) TASK_PORTID(オプション) サンプルプログラムにおいて,コマンド文字を読み込むシリアルポート番号を 定義するマクロ.定義しない場合のデフォルト値は1. (8-5-6) LOOP_REF(オプション) サンプルプログラムにおいて,プロセッサの速度を計測するためのループ回数 を定義するマクロ.定義しない場合のデフォルト値は1000000.デフォルト設定 では,値が大き過ぎて計測に時間がかかりすぎる場合や,値が小さ過ぎて計測 結果が安定しない場合に,ターゲット依存部でこのマクロを設定するループ回 数に定義する. (8-5-7) MEASURE_TWICE(オプション) サンプルプログラムにおいて,プロセッサの速度を2度計測する場合に定義する マクロ.シミュレーション環境などプロセッサの速度が変動する環境で,1度の 計測では計測結果が安定しない場合に定義する. (8-5-8) TASK_LOOP(オプション) サンプルプログラムにおいて,プロセッサの速度を計測せずに,タスク内での ループ回数を固定する場合に,ループ回数を定義するマクロ.ループ全体の実 行時間が0.4秒程度になるようなループ回数を,このマクロに定義する. 8.6 実行時間分布集計サービスのターゲット依存定義 実行時間分布集計サービスの設定をターゲット依存部で変更する場合に,ター ゲット依存部で提供すべき実行時間分布集計サービスのための定義は次の通り である.これらの定義は,target_test.h(またはそこからインクルードされる ファイル)に含める.この他に,ターゲット依存で必要な初期化処理がある場 合にも,ターゲット依存部に含める. (8-6-1) HISTTIM(オプション) 実行時間計測用の時刻のデータ型を定義するマクロ.定義しない場合のデフォ ルトはHRTCNT. (8-6-2) void HIST_GET_TIM(HISTTIM *p_time)(オプション) 実行時間計測用の現在時刻を*p_timeに取得する処理に定義するマクロ.定義し ない場合のデフォルトは,fch_hrtの返値を*p_timeに取得する処理になる. (8-6-3) uint_t HIST_CONV_TIM(HISTTIM time)(オプション) 実行時間計測用の時刻の差(時間)を,実行時間分布集計用の値に変換する処 理に定義するマクロ.時刻が過去に戻ったかオーバフローしたかの区別がつか ない場合には,最上位ビットが1の値(INT_MAXよりも大きい値)を返す.定義 しない場合のデフォルトは,timeをuint_tにキャストする処理になる. (8-6-4) void HIST_BM_HOOK(void)(オプション) 実行時間計測直前に行うべき処理に定義するマクロ.キャッシュのパージやフィ ル,メモリバリア処理等を行いたい場合には,このマクロに定義する.定義し ない場合のデフォルトは,空の処理になる. 9.その他 9.1 ドキュメント ターゲット依存部のユーザーズマニュアルを,target_user.txtに用意する.開 発環境依存部/プロセッサコア依存部/チップ依存部のユーザーズマニュアル を切り分けてもよいし,ファイルが大きくなる場合には複数のファイルに分割 してよいが,その場合には,target_user.txt中にそれらのファイル名を記述す ること. ターゲット依存部のユーザーズマニュアルには,少なくとも次のような内容を 記述することが望ましい. (1) 対応しているターゲットシステムの種類・構成,バージョン番号 ・ターゲットハードウェア(ボード等)の名称と対応している構成 ・ターゲット略称 ・ターゲット非依存部のバージョン番号 ・開発環境依存部/プロセッサコア依存部/チップ依存部の構成とバージョ  ン番号 (2) 使用する開発環境と動作検証した条件(バージョン,オプション等) ・言語処理系(コンパイラ,アセンブラ,リンカ等) ・デバッグ環境 (3) ターゲット定義事項の規定 (3-1) データ型に関する規定 ・int_t型,long_t型のサイズ ・char型,int_least8_t型,void *型,intptr_t型のサイズ ・int8_t型,uint8_t型,int64_t型,uint64_t型,int128_t型,  uint128_t型,float32_t型,double64_t型のサポートの有無 (3-2) 割込み処理に関する規定 ・割込みハンドラ番号と割込み番号の割当て,両者の対応 ・割込み優先度の段階数(TMIN_INTPRIの値) ・dis_intとena_intのサポートの有無,その制限事項 ・CFG_INTの制限事項と拡張(ターゲット定義で使用できる割込み属性) ・TOPPERS標準割込み処理モデルからのその他の逸脱 ・デフォルトの割込みハンドラ(default_int_handler)の有無と処理内容 (3-3) カーネル管理外の割込みに関する規定 ・TMIN_INTPRIは固定か設定できるか,その設定方法 ・NMI以外にカーネル管理外の割込みを設けるか(設けられるようにするか) ・カーネル管理外の割込みの設定方法 ・カーネル管理外の割込みに対してDEF_INH,CFG_INTをサポートするか ・カーネル管理外の割込みハンドラが実行開始される時のシステム状態と  コンテキスト ・割込みハンドラの終了時に行われる処理 ・カーネル管理外の割込みハンドラの記述方法 ・カーネル内の割込み出入口処理で起こる可能性のあるCPU例外 (3-4) CPU例外処理に関する規定 ・CPU例外ハンドラ番号の割当て ・割込み優先度マスクをTMIN_INTPRIと同じかそれよりも高い値に設定して  いる状態で発生したCPU例外を,カーネル管理外のCPU例外と扱うか ・カーネル内のCPU例外出入口処理で起こる可能性のあるCPU例外 ・デフォルトのCPU例外ハンドラ(default_exc_handler)の有無と処理内容 (3-5) 性能評価用システム時刻の参照に関する規定 ・get_utmのサポートの有無,その制限事項 (3-6) 拡張パッケージに関する規定 ・各拡張パッケージのサポートの有無 - ミューテックス機能拡張パッケージ - オーバランハンドラ機能拡張パッケージ - タスク優先度拡張パッケージ - 制約タスク拡張パッケージ - 動的生成機能拡張パッケージ ・オーバランハンドラ機能拡張パッケージをサポートする場合に,残りプ  ロセッサ時間に指定できる値の最大値(TMAX_OVRTIMの値) ・動的生成機能拡張パッケージをサポートする場合に,動的メモリ管理の  方法 (3-7) その他 ・その他の制限事項 ・その他の拡張機能 (4) カーネルの起動/終了処理に関する情報 ・用意しているスタートアップモジュールの処理内容 ・スタートアップモジュールからhardware_init_hookを呼び出している場  合には,hardware_init_hookをアプリケーションで用意する場合の作成  方法や制限事項など ・カーネルを終了した後の振舞い (5) メモリマップ ・デフォルトのメモリマップ,その変更方法 (6) タイマドライバ関連の情報 ・高分解能タイマの周期とカウントアップの進み幅 ・使用するリソース(タイマ) ・高分解能タイマ割込みの割込み優先度の変更方法 ・オーバランタイマ割込みの割込み優先度の変更方法 (7) シリアルインタフェースドライバの情報 ・使用するリソース(SIOコントローラ) ・通信パラメータ(ボーレート,ビット数,パリティの有無,ストップビット) (8) システムログ機能の情報 ・システムログの低レベル出力の実現方法 ・通信パラメータ(ボーレート,ビット数,パリティの有無,ストップビット) (9) システム構築手順 (10) ターゲットシステム固有の注意事項 ・タスクコンテキストに含まれるレジスタ,含まれないレジスタ (11) 類似のターゲットにポーティングする開発者向けの参考情報 (12) ディレクトリ構成・ファイル構成 (13) バージョン履歴 また,必要に応じて,ターゲット依存部の設計メモを,target_design.txtに用 意する.開発環境依存部/プロセッサコア依存部/チップ依存部に関する設計 メモを切り分けてもよいし,ファイルが大きくなる場合には複数のファイルに 分割してもよいが,その場合には,target_design.txt中にそれらのファイル名 を記述すること. 9.2 パッケージ記述ファイル リリースパッケージ(個別パッケージおよび簡易パッケージ)を作成するため に,パッケージに含めるファイルを記述したパッケージ記述ファイルを用意す る.パッケージ記述ファイルの名称は,個別パッケージ用をMANIFEST,簡易パッ ケージ用をE_PACKAGEとする. 例えば,arch/arm_gccディレクトリに置かれたMANIFESTファイルを用いて個別 パッケージを作成する場合には,次のコマンドを実行する. % utils/makerelease arch/arm_gcc/MANIFEST このコマンドにより,RELEASE/asp3_arch_arm_gcc-<バージョン番号>.tar.gzが 作成される.また,target/ct11mpcore_gccディレクトリに置かれたE_PACKAGE ファイルを用いて簡易パッケージを作成する場合には,次のコマンドを実行す る. % utils/makerelease target/ct11mpcore_gcc/E_PACKAGE このコマンドにより,RELEASE/asp3_ct11mpcore_gcc-<バージョン番号>.tar.gz が作成される(RELEASEディレクトリがない場合には,ディレクトリが作られ る). なお,makereleaseユーティリティは,ASP3カーネルのソースファイルが置かれ たディレクトリが,asp3という名称であることを仮定している(異なる名称の 場合でもパッケージは作成できるが,パッケージを展開した時に展開されるディ レクトリがasp3でなくなる).また,標準のtarコマンドがGNU tarであること (正確には,zオプションに対応していること)を想定している. パッケージ記述ファイルには,パッケージに含めるファイル名を,パッケージ 記述ファイルが置かれたディレクトリからの相対パス名で,1行に1つずつ記述 する.また,必要に応じて,以下のディレクティブを含める. (a) E_PACKAGE <簡易パッケージ名> 簡易パッケージ名を指定する.簡易パッケージ記述ファイル(E_PACKAGE)の先 頭に記述する.簡易パッケージ名は,asp3_<ターゲット略称>とする.例えば, ターゲット略称がct11mpcore_gccの場合には,asp3_ct11mpcore_gccとなる.個 別パッケージと区別するために,簡易パッケージのファイル名には"target"を 含めない. (b) PACKAGE <個別パッケージ名> 個別パッケージ名を指定する.個別パッケージ記述ファイル(MANIFEST)の先 頭に記述する.また,そこからインクルードされる各ファイルの先頭にも記述 し,それをインクルードしている個別パッケージ名を指定する.ターゲット依 存部の個別パッケージ名は,個別パッケージ記述ファイルが置かれたディレク トリの相対パス中の"/"を"_"に置き換えた文字列を,"asp3_"の後につなげたも のとする.例えば,個別パッケージ記述ファイルがarch/arm_gcc/MANIFESTの場 合には,asp3_arch_arm_gccとなる. (c) VERSION <バージョン番号> パッケージのバージョン番号を指定する.簡易パッケージ記述ファイルおよび 個別パッケージ記述ファイルの中に記述する.簡易パッケージにおいて,バー ジョン番号をパッケージ化した日付とする場合には,パッケージ番号の代わり に%dateと記述する. バージョン番号の付与方法については,「TOPPERS/ASP3カーネル ユーザーズマ ニュアル」の「2.2 簡易パッケージ」および「2.3 個別パッケージ」の節を参 照すること. (d) INCLUDE <ファイル名> 別のパッケージ記述ファイルをインクルードする.簡易パッケージ記述ファイ ルからは,個別パッケージ記述ファイルのみをインクルードするのを原則とす る.個別パッケージ記述ファイルからインクルードされるファイル中で指定さ れる個別パッケージ名は,すべて一致していなければならない. 10.リファレンス 10.1 ターゲット依存部のファイル一覧 標準的なターゲット依存部のファイル構成は次の通りである. Makefile.target Makefileのターゲット依存部(2章) target_offset.tf オフセットファイル生成用テンプレートファイル(2.5.1節, オプション) target_stddef.h TOPPERS共通定義(t_stddef.h)のターゲット依存部(3 章).アプリケーションとカーネルの両方からインクルー ドされる target_sil.h システムインタフェースレイヤ(sil.h)のターゲット依 存部(4章).アプリケーションとカーネルの両方から インクルードされる target_kernel.h カーネルAPI(kernel.h)のターゲット依存部(5章). アプリケーションとカーネルの両方からインクルードさ れる target_kernel_impl.h カーネル実装のターゲット依存部のヘッダファイル(6 章).カーネルのみからインクルードされる target_kernel_impl.c カーネル実装のターゲット依存部のC言語で記述される 部分(6章,オプション) target_support.S ターゲット依存部のアセンブリ言語で記述される部分(6 章,オプション) target_rename.def ターゲット依存部のためのリネーム記述(6.12節) target_rename.h target_rename.defから生成されるファイル(6.12節) target_unrename.h target_rename.defから生成されるファイル(6.12節) target_timer.cfg タイマドライバのシステムコンフィギュレーションファ イル(6.13節) target_timer.h タイマドライバのヘッダファイル(6.13節).カーネル のみからインクルードされる target_timer.c タイマドライバの実装ファイル(6.13節,オプション) システム略称.h ターゲットのハードウェア資源(割込みハンドラ番号や CPU例外ハンドラ番号,デバイスレジスタの番地など)の 定義を含むヘッダファイル.アプリケーションとカーネ ルの両方からインクルードされる(6章,オプション) target_def.csv コンフィギュレータの値取得シンボルテーブルのターゲッ ト依存部(7章,オプション) target.tf コンフィギュレータのパス2のテンプレートファイルの ターゲット依存部(7.2節) target_check.tf コンフィギュレータのパス3のテンプレートファイル(7.3 節) target_cfg1_out.h cfg1_out.cのリンクに必要なスタブの定義ファイル(7.4 節) target_syssvc.h システムサービスのターゲット依存定義(8.0節) target_serial.cfg シリアルドライバのシステムコンフィギュレーションファ イル(8.3節) target_serial.h シリアルドライバのヘッダファイル(8.3節).シリアル ドライバのみからインクルードされる target_serial.c シリアルドライバの実装ファイル(8.3節,オプション). target_test.h テストプログラムのターゲット依存定義(8.4節) target_user.txt ユーザーズマニュアル(9.1節) target_design.txt 設計メモ(9.1節,オプション) MANIFEST 個別パッケージに含めるファイルのリスト(9.2節,オプ ション) E_PACKAGE 簡易パッケージに含めるファイルのリスト(9.2節,オプ ション) 以上