第14章  システム初期化処理


本章では,RI850V4が提供しているシステム初期化処理について解説しています。

14.1 概  要

RI850V4におけるシステム初期化処理では,リセットの発生から処理プログラムに制御を移すまでに必要となる“RI850V4が処理を実行するうえで必要となるハードウエア,およびソフトウエアの初期化処理”を提供しています。

以下に,リセットの発生から処理プログラム(タスク)に制御が移るまでに実行される処理の流れを示します。

図14−1  処理の流れ(システム初期化処理)



14.2 ユーザ・オウン・コーディング部

RI850V4では,さまざまな実行環境に対応するために,システム初期化処理のうち,RI850V4が処理を実行するうえで必要となるハードウエア依存処理(ブート処理),およびRI850V4が処理を実行するうえで必要となる各種情報(システム依存情報)をユーザ・オウン・コーディング部として切り出しています。これにより,さまざまな実行環境への移植性を向上させるとともに,カスタマイズを容易なものとしています。

14.2.1 ブート処理

ブート処理は,RI850V4が処理を実行するうえで必要となる最低限のハードウエアを初期化するためにユーザ・オウン・コーディング部として切り出された初期化処理専用ルーチンであり,割り込みエントリ処理から呼び出されます。

- ブート処理の基本型
ブート処理を記述する場合,引き数を持たないvoid型の関数として記述します。
以下に,ブート処理をアセンブリ言語で記述する場合の基本型を示します。



         .public __boot
 
         .text   .cseg   text
         .align  0x2
 __boot :
         ............
         ............
 
         mov     #__kernel_start, r11    /*カーネル初期化部に制御を移す*/
         jarl    [r11], lp


- ブート処理内での処理
ブート処理は,割り込みエントリ処理からRI850V4を介在させることなく呼び出される初期化処理専用ルーチンです。このため,ブート処理を記述する際には,以下に示す注意点があります。


- 記述方法
C言語,またはアセンブリ言語で記述します。
C言語で記述するときは通常の関数と同様に記述することができます。
アセンブリ言語で記述するときは使用するコンパイラの呼び出し規約にのっとって作成してください。




- スタックの切り替え
ブート処理が開始された時点では“カーネル初期化部の実行”が行われていません。したがって,ブート処理用スタックを使用する際には,ブート処理の開始部分でスタックの設定処理(スタック・ポインタSPの設定)を記述する必要があります。


- サービス・コールの発行
ブート処理が開始された時点では“カーネル初期化部の実行”が行われていません。したがって,ブート処理では,サービス・コールの発行が禁止されています。


以下に,ブート処理として実行すべき処理の一覧を示します。

1 ) 割り込み機能の設定レジスタINTCFGの初期化

2 ) グローバル・ポインタGPの設定

3 ) エレメント・ポインタEPの設定

4 ) スタック・ポインタSPの設定

5 ) テキスト・ポインタTPの設定(コンパイラCCV850を使用している場合のみ)

6 ) .kernel_data_initセクションの初期化

7 ) 割り込み優先度の設定(EIC.EIPnに対する操作)

8 ) 割り込みベクタ方式の選択(EIC.EITBに対する操作)

9 ) 初期値なしメモリ領域(bssセクションなど)の初期化

10 ) CPUの内部ユニット(OSタイマなど),周辺コントローラの初期化(OSタイマの初期化方法については「9.2.1 基本クロック用タイマ割り込み」を参照してください)

11 ) 浮動小数点演算例外の優先度を設定(FPU搭載デバイスのみ)

12 ) システム情報テーブルの先頭アドレスをr6に設定

13 ) カーネル初期化部_kernel_startに制御を移す

備考1 割り込み機能の設定レジスタINTCFGを初期化する際には,ISPCビットに対し,ISPRを自動的に更新する旨の設定(ISPCビットに0を設定)を行ってください。

備考2 ブート処理以外でグローバル・ポインタGPの書き換えを行った場合,以後の動作は保証されません。

備考3 処理プログラム(タスク,周期ハンドラなど)でエレメント・ポインタEPの書き換えを行う場合,コンパイル・オプション-Xep=callee(プロパティ パネル → [共通オプション]タブ → [レジスタ・モード]カテゴリ → [epレジスタの扱い]で“calee-saveとして扱う”を選択)の指定が必須となります。

備考4 スタック・ポインタSPの設定は,ブート処理専用スタックを使用する場合に限り必要となります。

備考5 .kernel_data_initセクションを初期化する場合の記述例については,以下を参照してください。

- コンパイラCC-RHの場合
コンパイラCC-RHが提供しているRAMセクション領域初期化関数_INITSCT_RHを利用することにより,処理の記述を簡素化することが可能となります。
以下に,.kernel_data_initセクションの初期化をアセンブリ言語で記述する場合の記述例を示します。
 .section    ".INIT_BSEC.const", const
 .align      0x4
 .dw         #__s.kernel_data_init, #__e.kernel_data_init
 
 mov         r0, r6
 mov         r0, r7
 mov         #__s.INIT_BSEC.const, r8
 mov         #__e.INIT_BSEC.const, r9
 jarl        __INITSCT_RH, lp




- コンパイラCCV850の場合

まず,「カーネル初期化フラグ」が配置されるセクション.kernel_data_initをブート処理時に初期化するため,CLEARセクション属性を使用してリンク・ディレクティブ・ファイルに定義します。

以下にリンク・ディレクティブ・ファイルの記述例を示します。

 MEMORY {
 ROM_MEMORY	: ORIGIN = 0x00007000,	LENGTH = 0x003f9000
 RAM_MEMORY	: ORIGIN = 0xfedf0000,	LENGTH = 0x00010000
 ............
 }
 
 SECTIONS {
 ............
 .kernel_data_init CLEAR			:>RAM_MEMORY
 ............
 }


上記のように定義すると,CCV850コンパイラが生成するランタイム・クリア・テーブル(__ghsbinfo_clear, __ghseinfo_clear)に.kernel_data_initのセクション情報が含まれます。以下にランタイム・クリア・テーブルに含まれるセクション領域を初期化する処理の記述例を示します。
 /* initialize memory */
 meminit(void){
  	{
  		void **b = (void **)__ghsbinfo_clear;
  		void **e = (void **)__ghseinfo_clear;
 
  		while (b < e){
  			 void *s, *n, *v;
 
 			  s = (sint8 *)(*b++);
 			  v = *b++;
 			  n = *b++;
 			  memset(s, (sint32)v, (uint32)n);
   		}
  	}
 	............


備考6 直接ベクタ方式のエントリ・ファイルを使用時に必要となるリセット・ベクタ・ベース・アドレスRBASEのRINTビット,および例外ハンドラ・ベクタ・アドレスEBASEのRINTビットに対する操作(縮小モードで動作させるか否か)は初期化ルーチンで行ってください。

備考7 EIレベル割り込みマスク・レジスタIMRmのMKnビット(または,EIMKnビット)に対する操作(EIレベル・マスカブル割り込みの受け付け許可)は初期化ルーチンで行ってください。

備考8 浮動小数点演算例外の優先度は,必ず最大カーネル管理内割り込み優先度よりも高くなるように設定してください。

14.2.2 システム依存情報

システム依存情報は,RI850V4が処理を実行するうえで必要となる各種情報をユーザ・オウン・コーディング部として切り出したヘッダ・ファイル(ファイル名:userown.h)です。

- システム依存情報の基本型
システム依存情報を記述する場合,規定されたファイル名(userown.h),規定されたマクロ名(KERNEL_USR_TMCNTREG,KERNEL_USR_BASETIME)を用いて記述します。
以下に,システム依存情報をC言語で記述する場合の基本型を示します。



 #include    <kernel_id.h>                   /*システム情報ヘッダ・ファイルの定義*/
 
 #define     KERNEL_USR_TMCNTREG 0xffec0004  /*I/Oアドレス*/
 #define     KERNEL_USR_BASETIME 250         /*1カウント当たりの時間(4MHz→250ns)*/


以下に,システム依存情報として定義すべき情報の一覧を示します。

- システム情報ヘッダ・ファイルの定義
システム・コンフィギュレーション・ファイルに対してコンフィギュレータを実行することにより出力されるシステム情報ヘッダ・ファイルのインクルード


備考 本情報の記述は,プロパティ パネル[タスク・アナライザ]タブ → [トレース]カテゴリ → [トレース・モードの選択]で“ソフトウエア・トレース・モードで,長時間統計を取得”を選択した場合に限り必要となります。

- 基本クロック用タイマ情報
カウンタ・レジスタOSTMnのI/Oアドレス(レジスタ・ベース・アドレス + 0x4),およびOSタイマの周波数から換算される1カウント当たりの時間(単位:ns)をマクロ定義


備考 本情報の記述は,プロパティ パネル[タスク・アナライザ]タブ → [トレース]カテゴリ → [トレース・モードの選択]で“ソフトウエア・トレース・モードで,トレース・チャートを取得”,または“ソフトウエア・トレース・モードで,長時間統計を取得”を選択した場合に限り必要となります。

14.3 カーネル初期化部

カーネル初期化部は,RI850V4が処理を実行するうえで必要となる最低限のソフトウエアを初期化するために用意された初期化処理専用ルーチンであり,ブート処理から呼び出されます。

なお,カーネル初期化部では,以下に示した処理が実行されます。

- 管理オブジェクトの初期化
システム・コンフィギュレーション・ファイルで定義された各種オブジェクト(タスク,セマフォなど)を初期化します。


- システム時刻の初期化
基本クロック用タイマ割り込みの例外コードtim_intnoで定義されたEIレベル・マスカブル割り込みが発生した際に基本クロック周期tim_baseを単位とした更新が行われるシステム時刻を初期化(0を設定)します。


- タスクの起動
属性(記述言語,初期起動状態など)tskatrでTA_ACTが定義されたタスクをDORMANT状態からREADY状態へと遷移させます。


- 周期ハンドラの動作開始
属性(記述言語,初期起動状態など)cycatrでTA_STAが定義された周期ハンドラを停止状態(STP状態)から動作状態(STA状態)へと遷移させます。


- 初期化ルーチンの呼び出し
初期化ルーチン情報で定義された初期化ルーチンをシステム・コンフィギュレーション・ファイルに定義した順序で呼び出します。


- スケジューラに制御を移す
READY状態へと遷移しているタスクの中から最適なタスクを選び出し,該当タスクをREADY状態からRUNNING状態へと遷移させます。


備考 カーネル初期化部は,RI850V4が提供しているシステム初期化処理に内包されています。したがって,ユーザがカーネル初期化部を記述する必要はありません。