= TOPPERS/JSPカーネル ユーザズマニュアル = (SH2 ターゲット依存部) (Release 1.4.1対応,最終更新: 25-Jun-2010) ------------------------------------------------------------------------ TOPPERS/JSP Kernel Toyohashi Open Platform for Embedded Real-Time Systems/ Just Standard Profile Kernel Copyright (C) 2000-2004 by Embedded and Real-Time Systems Laboratory Toyohashi Univ. of Technology, JAPAN Copyright (C) 2001-2010 by Industrial Technology Institute, Miyagi Prefectural Government, JAPAN Copyright (C) 2002-2004 by Hokkaido Industrial Research Institute, JAPAN 上記著作権者は,以下の (1)〜(4) の条件か,Free Software Foundation によって公表されている GNU General Public License の Version 2 に記 述されている条件を満たす場合に限り,本ソフトウェア(本ソフトウェア を改変したものを含む.以下同じ)を使用・複製・改変・再配布(以下, 利用と呼ぶ)することを無償で許諾する. (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作 権表示,この利用条件および下記の無保証規定が,そのままの形でソー スコード中に含まれていること. (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使 用できる形で再配布する場合には,再配布に伴うドキュメント(利用 者マニュアルなど)に,上記の著作権表示,この利用条件および下記 の無保証規定を掲載すること. (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使 用できない形で再配布する場合には,次のいずれかの条件を満たすこ と. (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著 作権表示,この利用条件および下記の無保証規定を掲載すること. (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに 報告すること. (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること. 本ソフトウェアは,無保証で提供されているものである.上記著作権者お よびTOPPERSプロジェクトは,本ソフトウェアに関して,その適用可能性も 含めて,いかなる保証も行わない.また,本ソフトウェアの利用により直 接的または間接的に生じたいかなる損害に関しても,その責任を負わない. @(#) $Id: sh2.txt,v 1.5 2005/07/06 00:45:07 honda Exp $ ------------------------------------------------------------------------ 1.SH2 ターゲット依存部の概要 基本的にSH1.txtと同様である。 1.1 ターゲットシステムと開発環境 SH2プロセッサのターゲットシステムはSH7145、SH7615を搭載した以下のボー ドである。 ・(株)アルファプロジェクト製のAP_SH2F_6A(CPU: SH7145) ・(株)北斗電子製のHSB7615IT(CPU: SH7615) 開発環境には、GCC などの GNU開発環境を用い、オブジェクトファイルフォー マットは ELF を標準とする。 1.2 サポートする機能の概要 SH1/2依存の機能として、割込みマスクの変更・参照(chg_ixx、get_ixx)と、 性能評価用システム時刻参照機能(vxget_tim)をサポートしている。割込み の禁止と許可(dis_int、ena_int)はサポートしていない。 1.3 DSP DSPレジスタの待避は行っていない。 1.4 GDB スタブ GDBスタブについてはhttp://www.hokkaido-iri.go.jpより配布中。 1.5 シリアルポート カーネルのログ出力用にシリアルポートを1つ使用する。 シリアルポートの設定は  ・8ビット  ・パリティなし  ・ストップビット:1ビット  ・ボーレート: である。 2.SH2プロセッサ依存部の機能 この節では、カーネルおよびシステムサービスの機能の中で、SH2依存の部分 について解説する。SH1版と同じである。 2.1 データ型 signed int型,unsigned int型,size_t型のサイズは,いずれも32ビットであ る. 2.2 割込み管理機能と割込みハンドラ カーネル管理外の割込みとしては、 NMI がある。よって、CPUロック状態や初 期化ルーチン内では、NMI 以外の割込みはすべて禁止されている。具体的には、 IPM(Interrupt Priority Mask)が 15 に設定される。 将来的にGDBスタブを利用することを考慮して、ソースコード内に以下のよう な記述を含む。 ボード上に NMI 入力を持たないターゲットのため、GDB のスタブがホストの マシンと通信するためのシリアルポートの優先度を 15 で登録し、GDB で Ctrl-C を押すと 割り込みが入りスタブに制御が移るようにしてある。この機 能を使用するためにはCPUロック状態では、優先度が 14 になるようにしなけ ればならない。そのため、CPUロックで設定される優先度をマクロ MAX_IPMで 指定している。MAX_IPM はcpu_config.h の中で #define されている。スタブ を使う場合はMAX_IPMを14に、スタブを使わない場合はMAX_IPMを15に設定して いる。 SH1/2依存の機能として、SR(Status Register)中の 割り込みマスクビット(I3〜 I0)の値を変更するためのサービスコール chg_ipm と、参照するためのサービ スコール get_ipm をサポートしている。なお、割り込みマスクビットの値を 表すデータ型 IPM は、unsigned int型に定義されている。 これらのサービスコールは、タスクコンテキストで CPUロック解除状態の場合 にのみ呼び出すことができる。chg_ipm により IPM を 0 以外(すなわち、何 らかの割込みが禁止されている状態)にした場合でも、ディスパッチは禁止さ れず、chg_ipm により変更した IPM の値は、ディスパッチ後のタスクに引き 継がれる。例えば、あるタスクで IPM を 1 に変更した後、何らかの割込みに より別のタスクに切り替わると、切り替わった後のタスクでもIPMは1になる。 chg_ipm をサポートするために、割込みハンドラの出入口処理などにオーバヘッ ドを生じている。そこで、SUPPORT_CHG_IPM というマクロにより、これらのサー ビスコールをサポートするかどうかを切り替えられるようにしている。 SUPPORT_CHG_IPM は、user_config.h の中で #define されている。 SH1/2依存の割込みマスクの変更・参照のためのサービスコールの仕様は次の通 り。 (1) chg_ipm 割込みマスクの変更 【C言語API】 ER ercd = chg_ipm(IPM ipm); 【パラメータ】 IPM ipm 設定すべき IPM の値 【リターンパラメータ】 ER ercd エラーコード 【エラーコード】 E_CTX コンテキストエラー E_PAR パラメータエラー(ipm が不正) 【機能】 IPM(Interrupt Priority Mask)を ipm で指定された値に設定する。指定した 値が 0〜14ないし0〜13以外の場合、E_PARエラーとなる。IPM を0以外 (1〜MAX_IPM-1)に設定した場合でも、ディスパッチは禁止されない。また、 設定した IPM の値は、ディスパッチ禁止後も引き継がれる。 なお、このサービスコールを用いて、IPM を MAX_IPM (すべての割込みを禁止) に設定することはできない。IPM を MAX_IPM にしたい場合には、loc_cpu を 使うべきである。 このサービスコールは、タスクコンテキストで CPUロック解除状態の時のみ呼 び出すことができる。非タスクコンテキストや CPUロック状態で呼び出した場 合には、E_CTXエラーとなる。 (2) get_ipm 割込みマスクの参照 【C言語API】 ER ercd = get_ipm(IPM *p_ipm); 【パラメータ】 なし 【リターンパラメータ】 ER ercd エラーコード IPM ipm 現在の IPM の値 【エラーコード】 E_CTX コンテキストエラー 【機能】 現在の IPM(Interrupt Priority Mask)の値を読み出し、ipm に返す。 このサービスコールは、タスクコンテキストで CPUロック解除状態の時のみ呼 び出すことができる。非タスクコンテキストや CPUロック状態で呼び出した場 合には、E_CTXエラーとなる。 2.3 CPU例外管理機能とCPU例外ハンドラ DEF_EXC で指定する割込みハンドラ番号(excno)は、SH2 での ベクタテーブル のベクタ番号を表し、そのデータ型(EXCNO)は unsigned int型に定義されてい る。DEF_EXC で、ベクタ番号として有効でない値や、CPU例外に対応しない番 号を指定した場合の動作は保証されない。 CPU例外ハンドラに渡されるp_excinfは、CPU例外発生時のコンテキストを保存 したスタックへのポインタが渡される。スタックの構造を以下に示す。 ---------------------- | PR | ---------------------- | R7 | ---------------------- | R6 | ---------------------- | R5 | ---------------------- | R4 | ---------------------- | R3 | ---------------------- | R2 | ---------------------- | R1 | ---------------------- | R0 | ---------------------- | PC | ---------------------- | SR | <-- p_excinf ---------------------- PR:Procedure Register SR:Status Register PC:Program Counter また、CPU例外発生時のPCの値はインクリメントされる。そのため、CPU例外ハ ンドラから復帰を行うと、CPU例外が発生した命令の次の命令から実行を再開 する。 2.4 スタートアップモジュール SH2依存のスタートアップモジュール(start.S)では、次の初期化処理を行う。 (A) プロセッサモードの初期化とスタックポインタの初期化 割り込みマスクを MAX_IPM に設定する。 次に、スタックポインタ(r15)を STACKTOP に設定する。ここで割込みスタッ クポインタに設定されたスタック領域は、カーネル起動後は非タスクコンテキ スト用のスタック領域として使われる。STACKTOP は、user_config.h 部で定義 することを想定している。 (B) hardware_init_hook の呼出し hardware_init_hook が 0 でない場合には、hardware_init_hook を呼び出す。 hardware_init_hook は、カーネルが起動される前に行う必要があるターゲッ ト依存の初期化を行うために用意している。hardware_init_hook がどこでも 定義されていない場合、リンカでこのシンボルを 0 に定義する(リンカスク リプト内に記述あり)。 (C) bssセクションと dataセクションの初期化 bssセクションをゼロクリアする。また、dataセクションを初期化する。 (D) software_init_hook の呼出し software_init_hook が 0 でない場合には、software_init_hook を呼び出す。 software_init_hook は、カーネルが起動される前に行う必要があるソフトウェ ア環境(具体的には、ライブラリ)依存の初期化を行うために用意している。 software_init_hook がどこでも定義されていない場合、リンカでこのシンボ ルを 0 に定義する(リンカスクリプト内に記述あり)。 (E) カーネルの起動 kernel_start へ分岐し、カーネルを起動する。kernel_start からリターンし てくることは想定していない。 2.5 割込み発生時のスタック消費量について 以下の理由により、各タスクスタックはタスク自身が使用する分に加えて最大 240バイト余分に用意する必要がある。 JSPカーネルではタスクスタックの他に割込みスタックを用意し、非タスクコ ンテキストは割込みスタックで実行される。 SH1/2は例外/割込み受付時に割込み禁止になる機構がハードウェアで用意されて いない。そのため、割込みの入口処理でソフトウェアによって割込み禁止にす る必要がある。入口処理では割込み禁止に移行するために(割込み許可の状態 で)スタックにr0,r1を待避する。(SR(Status Register)とPC(Program Counter)は割込み受付け時にハードウェアが自動的に待避を行う。) このとき、多重割込みが発生すると割り込みスタックに切り替える前に同様の フレームがスタック上に生成される。SH2は割り込みレベルが15段あるので、 最悪のタイミングで割込みが発生すると、スタックが240バイト消費される。 (4バイト×4レジスタ×15セット) 例外/割り込みのネスト回数のカウント用にカーネル内で変数intnestを用意 し、非タスクコンテキストとタスクコンテキストの判別はこの変数により 行っている。 2.6 MACHとMACL (積和レジスタ) MACH:Multiply and accumulate high register MACL:Multiply and accumulate low register MACHとMACLについては、gccに-mhitachiオプションをつけると、関数でMACHと MACLを使用する場合、スタックに保存してから使用し、関数を抜けると元に戻 すため、割込みでは保存していない。また、自らディスパッチャを呼び出し、 ディスパッチする場合は、関数呼び出しになるため、この呼び出しにまたがっ て、これらのレジスタを使うことはないため保存していない。そのためアセン ブラのコードを使用する場合もこのルールに従う必要がある。 なお、割込みからのディスパッチ(受動的ディスパッチ)では保存している。 2.7 GBR (Global Base Register) gccはGBRを使用しないため、割込みハンドラの入口では保存していない。割込 みハンドラ内でGBRを使う場合はアプリケーション側でGBRの待避/保存を行う 必要がある。また、上記のMACHとMACLと同じ理由により、自らディスパッチャ を呼び出す場合にも保存していない。なお、割込みからのディスパッチ(受動 的ディスパッチ)では保存している。 3.システム依存部の機能 3.1 システムクロックドライバ システムクロックドライバが isig_tim を呼び出す周期は、user_config.h 中 のTIC_NUME と TIC_DENO で定義されている(デフォルトでは 1ミリ秒周期)。 この定義を変更することで、isig_tim を呼び出す周期を変更することができ る。 ただし、タイマの精度が 1μ秒であるため、1μ秒単位で端数になる値を設定 した場合には、isig_tim の呼出し周期に誤差が生じることになる。 デフォルトではSH2の内蔵CMT/FRTを使用している。タイマハンドラの優先度は user_config.hでマクロTIMER_INTLVLとして定義している。(デフォルトでは4) 3.2 性能評価用システム時刻参照機能 SH1/2依存部では、性能評価用システム時刻参照機能(vxget_tim)をサポートして いる。性能評価用システム時刻の精度は 1μ秒単位であるが、タイマの現在値 を読み出すために一時的にタイマを停止させる必要があるため、vxget_tim を 呼ぶ度にシステムクロックが少しづつ遅れることになる。なお、SYSUTIM型は UD型(64ビットの符号無し整数型)に定義している。 3.3 シリアルインタフェースドライバ シリアルインタフェースドライバは、SH2内蔵のSCI(Serial Communication Interface)/SCIF(FIFO内蔵Serial CommunicationInterface)をサポートし ており、カーネルのログ出力用に使用している。シリアル割込みハンドラの 優先度は送受信およびエラー割込み共にuser_config.hでマクロSCI_INTLVL/SCI F_INTLVLとして定義している。(デフォルトでは6) 3.4 メモリマップ ・(株)北斗電子製のHSB7615IT(CPU: SH7615) 0x0000,0000 - 0x001f,ffff コード領域(2MB) 0x0400,0000 - データ領域 - 0x040f,ffff 非タスクコンテキスト用のスタック領域 データ領域と非タスクコンテキスト用スタック領域をあわせて1MB。内蔵メモ リは未使用。 ・(株)アルファプロジェクト製のAP-SH2F-6A(CPU: SH7145) 0x0000,0000 - 0x0003,ffff コード領域(256KB) 0x0040,0000 - データ領域(1MB) - 0x004f,ffff 外付けメモリ終了 0xffff,e000 - データ領域(8KB) - 0xffff,ffff 内蔵メモリ終了 3.5 サンプルプログラムの実行 ・(株)北斗電子製のHSB7615SE(CPU: SH7615) あらかじめROMに書き込まれているモニタを起動する。 Lコマンドでjsp.srecをメモリにロードする。 G 04000400でサンプルプログラムを動作させる。 サンプルプログラムのメッセージはSCIF1から出力される。 他のボードなどにおいて、ROMから実行する場合、shelf.ldとMakefile.config内の アドレスの指定に注意。 ・(株)アルファプロジェクト製のAP-SH2F-6A(CPU: SH7145) jsp.srecを付属のライターで書き込で実行する。 サンプルプログラムのメッセージはSCI1から出力される。 4.開発環境の構築 開発環境の構築方法については、GNU開発環境構築マニュアルを参照すること。 開発にはLinux(Red Hat Linux release 7.2 Kernel 2.4.7-10)を用いた。 動作確認したツールのバージョンは以下の通りである. BINUTILS : 2.14 GCC-CORE : 2.95.3 configure のオプションは--target=sh-hitachi-elfである。 また、Windows上でCygwinを用いて開発する場合は、binutilsのconfigureのオ プションに --disable-nls も指定すること。 5.制限事項 5.1 システムインターフェースレイヤのsil_dly_nse()について 実測はしていない。 5.2 実行すべきタスクがない場合の割込み待ちについて    SH1と同じ。 ディスパッチャの出口で実行すべきタスクがない(schedtsk==NULL)場合は、 sleep命令によってプロセッサを省電力モードに切り替えて割込み待ちをして いる。(cpu_sapport.Sのdispatcher_2付近を参照) 割込み許可後にsleep命令を実行しているため、割込み許可命令の実行前に割 込み要求が入っている場合(あるいは割込み許可直後、sleep命令実行前に割 込み要求が入った場合)、割込み許可命令の実行と共に割込みが受け付けられ、 その復帰後にsleepしたままになってしまう。 (reqflgのチェックに進まない。) この問題は,割込みの許可とsleep 状態への移行がアトミックに実行できない ことに起因する。SH3以降ではIPMとは別にSRのBLビットを使って割込みの禁止 /許可を制御することにより、この問題を回避できるが、SH1/2ではIPMを設定す る以外に割込みを禁止/許可する方法がなく、割込み許可(割込み待ちのIPM設 定)とsleepをアトミックに行う方法がない。 そこでSH1/2依存部では、割込み受付時にスタックに積まれた戻り番地を多重割込 みの出口処理でチェックし、戻り番地が上記のsleep命令に該当する場合は戻り 番地を1命令分(2バイト)進めることによりこの問題を回避している。 ただし、この方法では多重割込みの出口処理に数命令のオーバーヘッドが生じる。 OMIT_POWER_CONTROLマクロを定義することでsleep命令の代わりにnop命令が挿入 され、多重割込みの出口処理でのチェックルーチンは省略される。(この場合は 消費電力の点で不利になる。) 5.4.2 割込み/CPU例外の出入口処理について SH1と同じ。 SH1/2では割込み受付直後に割込み禁止になっていないため、割込みAの入口処理 中に別の割込みBが入る可能性がある。(これはハードウェアのアーキテク チャ上避けようがない。)割込みハンドラB内でタスク切り替えを起こすよう なサービスコールを呼ぶと割込みBの出口処理で別のタスクにディスパッチし てしまい、タスク2から元のタスクに戻ってくるまで、割込みAの処理が遅れて しまう。 また、割込みAがレベルトリガだと2回検出されてしまう問題もある。 これを防ぐため、スタックに積んである戻り先のIPMとtask_intmaskの値を比 較して、入口処理中に割込みが入らなかったかチェックしている。 (cpu_support.Sの_ret_int参照) SH1/2ではCPU例外を受け付けても割込みマスクは変化しないため、CPU例外の入 口処理中に割込みが入った場合、上記のような判別方法でも対処できない。そ のため、割込みの出口処理でスタックに積まれた戻り番地とCPU例外の入口処 理の番地を比較して、戻り先がCPU例外の入口処理か否かを判別処理をオプ ションで用意している。この処理はCPU例外を登録したテーブルをサーチする 処理が入るため、割り込み禁止区間が長くなる。この判別処理を有効にしたい 場合はマクロSUPPORT_CPU_EXC_ENTRY_CHECKを定義する。 タスクコンテキストで発生したCPU例外の処理は、後回しにされても割込みほ ど問題はないと考え、上記の処理はデフォルトでは無効にしている。(タスク コンテキストでのCPU例外がどのタスク内で発生するかは、割込みのようにタ イミングによるものではなく必然的なものであるため、CPU例外処理の優先順 位もそのタスクに準じるものとして判断した。) 上記のテーブルはデフォルトでCPU例外を6要因登録できるようにしているが、 アプリケーションでトラップ命令を使用し、カーネルでハンドリングする場合 はuser_config.hのNUM_EXCの値を適宜変更する。 5.4 gcc3.x対応について SH2版はgcc3.x系で動作確認はしていない。 6.その他 6.1 ディレクトリ・ファイル構成 SH2 ターゲット依存部の各ファイルの概要は次の通り。 config/sh2/ Makefile.config MakefileのSH2依存定義 cpu_config.c プロセッサ依存部の関数 cpu_config.h プロセッサ依存部の構成定義 cpu_context.h コンテキスト操作 cpu_defs.h プロセッサ依存部のアプリケーション用定義 cpu_insn.h 低レベルのプロセッサ操作ルーチン cpu_rename.def カーネルの内部識別名のリネーム定義 cpu_rename.h カーネルの内部識別名のリネーム cpu_support.S プロセッサ依存部のサブルーチン cpu_unrename.h カーネルの内部識別名のリネーム解除 makeoffset.c offset.h 生成サポートプログラム sh7145.h SH7145の定義 sh7145cmt.h SH7145内蔵cmt用タイマードライバ sh7145sci.c SH7145内蔵sci用シリアルドライバ sh7145sci.h SH7145内蔵sci用シリアルドライバ sh7615.h SH7615の定義 sh7615frt.h SH7615内蔵frt用タイマードライバ sh7615scif.c SH7615内蔵scif用シリアルドライバ sh7615scif.h SH7615内蔵scif用シリアルドライバ start.S スタートアップモジュール tool_config.h 開発環境依存部の構成定義(GNU開発環境用) tool_defs.h 開発環境依存部のアプリケーション用定義(GNU開発環境用) config/sh2/hsb7616it/ (株)北斗電子製のHSB7615IT(CPU: SH7615) Makefile.config MakefileのHSB7615ITボード依存定義 hsb7616it.h HSB7615ITのハードウェア定義 hw_serial.cfg SIOドライバのコンフィギュレーションファイル hw_serial.h SIOドライバ hw_timer.h タイマ操作ルーチン sh2.h SH2の定義 shelf.ld リンカスクリプト shelf.stub.ld リンカスクリプト(stub用) sys_config.c システム依存部の関数 sys_config.h システム依存部の構成定義 user_config.h ユーザー定義情報 sys_defs.h システム依存部のアプリケーション用定義 sys_rename.def カーネルの内部識別名のリネーム定義 sys_rename.h カーネルの内部識別名のリネーム sys_support.S システム依存部のサブルーチン sys_unrename.h カーネルの内部識別名のリネーム解除 config/sh2/apsh2f6a/ 株)アルファプロジェクト製のAP-SH2F-6A(CPU: SH7145) Makefile.config MakefileのAP-SH2F-6Aボード依存定義 apsh2f6a.h AP-SH2F-6Aのハードウェア定義 hw_serial.cfg SIOドライバのコンフィギュレーションファイル hw_serial.h SIOドライバ hw_timer.h タイマ操作ルーチン sh2.h SH2の定義 shelf.ld リンカスクリプト shelf.stub.ld リンカスクリプト(stub用) sys_config.c システム依存部の関数 sys_config.h システム依存部の構成定義 user_config.h ユーザー定義情報 sys_defs.h システム依存部のアプリケーション用定義 sys_rename.def カーネルの内部識別名のリネーム定義 sys_rename.h カーネルの内部識別名のリネーム sys_support.S システム依存部のサブルーチン sys_unrename.h カーネルの内部識別名のリネーム解除 6.2 ユーザーの設定項目 SH1/2依存部では、ユーザーの設定項目をシステム依存部の2つのファイル Makefile.configとuser_config.hにまとめてあり、ユーザーはカーネル内部に 立ち入らなくても、ある程度、設定を変更可能にしている。 ・_MACRO_ONLY   マクロ定義のみであり、アセンブラソースからインクルードしても   アセンブルエラーにならない部分を抽出するためのマクロ ・SUPPORT_CHG_IPM   2.2節参照 ・OMIT_POWER_CONTROL   5.2節参照 ・GDB_STUB   GDB stub用。 変更履歴 '10/06/25  ・cpu_insn.hのset_sr(), cpu_defs.hの_disint_()    インラインアセンブラ(ldc rn, sr命令)のclobber変数    リストにmemoryとSRのTビットを追加