第10章  システム構成管理機能


本章では,RI78V4が提供しているシステム構成管理機能に規程ついて解説しています。

10.1 概  要

RI78V4におけるシステム構成管理機能では,リセット割り込みの発生からタスクに制御を移すまでに必要となるシステム初期化処理,および,バージョン情報の参照処理を提供しています。

以下に,リセット割り込みの発生からタスクに制御が移るまでに実行される処理の流れを示します。

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



10.2 ブート処理

ブート処理は,RI78V4が処理を実行するうえで必要となる最低限のハードウエアを初期化するためにユーザ・オウン・コーディング部として切り出された初期化処理専用ルーチンであり,リセット割り込みが発生した際にCPUが強制的に制御を移すベクタ・テーブル・アドレスに割り付けられた割り込みエントリ処理から呼び出されます。

10.2.1 ブート処理の登録

ブート処理の登録は,リセット割り込みが発生した際にCPUが強制的に制御を移すベクタ・テーブル・アドレスに割り込みエントリ処理(ブート処理への分岐命令)を記述することにより実現されます。

ただし,割り込みエントリ処理の記述方法は,ブート処理がnear領域に割り付けられているのか,またはfar領域に割り付けられているのかにより異なります。

以下に,割り込みエントリ処理の記述例を示します。

【 near領域にブート処理を割り付ける場合 】

    .PUBLIC   _boot       ;ベクタ・テーブルのセクション設定
 _boot   .VECTOR  0x0000    ;ブート処理に制御を移す
 

【 far領域にブート処理を割り付ける場合 】

      .EXTERN    _intent_RESET     ;シンボルの外部参照宣言
 
      .SECTION   .vecttable, TEXT  ;ベクタ・テーブルのセクション設定
 _intent_RESET   .VECTOR  0x0000   ;ベクタ・テーブル・アドレスの設定
 
      .SECTION  .textf, TEXTF      ;ベクタ・テーブルの設定
 _intent_RESET:
         BR      !!_boot           ;ブート処理に制御を移す
 

10.2.2 ブート処理の基本型

ブート処理を記述する場合,引き数,および,戻り値を持たない関数(関数名:任意)として記述します。

以下に,ブート処理の基本型を示します。

         .PUBLIC  _boot
         .EXTERN  __kernel_start, _hdwinit, __init_ri_stackarea, _reset
 
         .SECTION .stack_bss, BSS        ;ブート内でスタックを使用する場合は領域確保
 _stackend:
         .DS      0x100
 _stacktop:
 
 _boot   .VECTOR  0x0000
 
         .SECTION .text, TEXT
 _boot:
         SEL     RB0                     ;レジスタ・バンクの設定
 
         MOVW    SP, #LOWW(_stacktop)    ;スタック・ポインタSPの設定
 
         CALL    !!_reset
 
 ;カーネル初期化情報のクリア
         MOVW    HL, #LOWW(STARTOF(.kernel_data_init))
         MOVW    AX, #LOWW(STARTOF(.kernel_data_init) + SIZEOF(.kernel_data_init))
         BR      $L2_KERNEL_DATA
 L1_KERNEL_DATA:
         MOV     [HL+0], #0
         INCW    HL
 L2_KERNEL_DATA:
         CMPW    AX, HL
         BNZ     $L1_KERNEL_DATA
 
         CALL    !!__init_ri_stackarea   ;RAM領域のクリア(別関数で実施)
 
         BR      !!__kernel_start        ;カーネル初期化部に制御を移す
 
         CLRW    AX
 _exit:
         BR      $exit
 

10.2.3 ブート処理内での処理

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

- 記述方法
ブート処理は,アセンブリ言語で記述します。


- スタックの切り替え
ブート処理に制御が移った時点では,“スタック・ポインタSPの設定”が実行されていません。
したがって,ブート処理専用スタックを使用する場合は,ブート処理の開始部分で“スタック・ポインタSPの設定”を記述する必要があります。



- 割り込み状態
ブート処理に制御が移った時点では,“カーネル初期化部”が実行されていません。
したがって,該当処理が完了する以前に割り込みが発生した際には,システムが暴走する可能性があります。そこで,ブート処理では,プログラム・ステータス・ワードPSWの割り込み許可フラグIEを操作して,マスカブル割り込みの受け付けを明示的に禁止してください。



- レジスタ・バンクの設定
RI78V4では,ブート処理内で_kernel_startを呼び出す以前に設定されたレジスタ・バンクから他のレジスタ・バンクへと切り替えることを禁止(RI78V4管理外の割り込み処理を除く)しています。


- サービス・コールの発行
RI78V4では,ブート処理内でサービス・コールを発行することを禁止しています。


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

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

- 割り込み許可フラグIEの設定

- 内部ユニット,周辺コントローラの初期化

- RAM領域の初期化(初期値なしメモリ領域の初期化,初期化データのコピー)

- カーネル初期化部(関数名:_kernel_start)に制御を移す

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

備考 

10.2.4 システム依存情報

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

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



 #include    <kernel_id.h>                   /*システム情報ヘッダ・ファイルの定義*/
 
 #define     KERNEL_USR_TMCNTREG 0x0180      /*I/Oアドレス*/
 #define     KERNEL_USR_TMCMPREG 0xff18      /*I/Oアドレス*/


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

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


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

- 基本クロック用タイマ情報
基本クロック用タイマのカウンタ・レジスタのI/Oアドレス,および基本クロック用タイマのコンペア・レジスタのI/Oアドレスをマクロ定義


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

10.3 初期化ルーチン

初期化ルーチンは,ユーザの実行環境に依存したハードウエア(周辺コントローラなど)を初期化するためにユーザ・オウン・コーディング部として切り出された初期化処理専用ルーチンであり,カーネル初期化部から呼び出されます。

10.3.1 初期化ルーチンの登録

RI78V4では,初期化ルーチンの登録方法を“カーネル初期化部において静的に登録する”に限定しています。

したがって,RI78V4では,初期化ルーチンを処理プログラムからサービス・コールを発行するなどして動的に登録することはできません。

- 静的な登録
初期化ルーチンの静的な登録は,規定された関数名init_handlerで初期化ルーチンを記述することにより実現されます。
RI78V4では,カーネル初期化部において,該当シンボル情報をもとに初期化ルーチンの登録処理を実行し,管理対象とします。



10.3.2 初期化ルーチンの登録解除

RI78V4では,カーネル初期化部において静的に登録された初期化ルーチンを処理プログラムからサービス・コールを発行するなどして動的に登録解除することはできません。

10.3.3 初期化ルーチンの基本型

初期化ルーチンを記述する場合,引き数を持たないvoid型の関数(関数名:init_handler)として記述します。

以下に,初期化ルーチンの基本型を示します。

【 C言語で記述する場合 】

 #include        <kernel.h>              /*標準ヘッダ・ファイルの定義*/
 #include        <kernel_id.h>           /*システム情報ヘッダ・ファイルの定義*/
 
 void
 init_handler ( void )
 {
         ............                    /*初期化ルーチンの本体処理*/
         ............
 
         return;                         /*初期化ルーチンの終了*/
 }
 

【 アセンブリ言語で記述する場合】

 $INCLUDE   (kernel.inc)            ;標準ヘッダ・ファイルの定義
 $INCLUDE   (kernel_id.inc)         ;システム情報ヘッダ・ファイルの定義
 
         .PUBLIC _init_handler
 
         .SECTION .textf, TEXTF
 _init_handler:
         ............               ;初期化ルーチンの本体処理
         ............
 
         RET                        ;初期化ルーチンの終了
 

10.3.4 初期化ルーチン内での処理

RI78V4では,初期化ルーチンに制御を移す際に“独自の前処理”を,初期化ルーチンから制御を戻す際にも“独自の後処理”を実行しています。

このため,初期化ルーチンを記述する際には,以下に示す注意点があります。

- 記述方法
初期化ルーチンは,「10.3.3 初期化ルーチンの基本型」で示された関数形式でC言語,またはアセンブリ言語を用いて記述します。


- スタックの切り替え
RI78V4では,初期化ルーチンに制御を移す際に“システム・スタックへの切り替え処理”を,初期化ルーチンから制御を戻す際に“切り替え先のカーネル初期化部用スタックへの切り替え処理”を実行しています。
したがって,ユーザは,初期化ルーチン内でスタックの切り替えに関する処理を記述する必要はありません。



- 割り込み状態
RI78V4では,初期化ルーチンに制御を移す際に“マスカブル割り込みの受け付けが禁止された状態”としています。
なお,初期化ルーチンに制御が移った時点では,カーネル初期化部の処理が完了していません。
したがって,初期化ルーチン内で明示的にマスカブル割り込みの受付けを許可した際には,システムが暴走する可能性があります。そこで,RI78V4では,初期化ルーチン内でマスカブル割り込みの受け付けを許可することを禁止しています。




- サービス・コールの発行
RI78V4では,初期化ルーチン処理内でサービス・コールを発行することを禁止しています。


以下に,初期化ルーチンとして実行すべき処理の一覧を示します。

- 内部ユニット,周辺コントローラの初期化

- RAM領域の初期化(初期値なしメモリ領域の初期化,初期化データのコピー)

- カーネル初期化部に制御を戻す

10.4 カーネル初期化部

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

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

- メモリ領域の確保

- 管理オブジェクトの生成/登録

- 初期化ルーチンの呼び出し

- スケジューラに制御を移す

備考 カーネル初期化部は,RI78V4が提供する機能の一部です。したがって,ユーザは,カーネル初期化部の処理内容を記述する必要はありません。

10.5 バージョン情報の参照

バージョン情報の参照は,以下に示したサービス・コールを処理プログラムから発行することにより実現されます。

- ref_ver
RI78V4のバージョン情報(メーカ・コードなど)をパラメータpk_rverで指定された領域に格納します。
以下に,本サービス・コールの記述例を示します。


 #include        <kernel.h>              /*標準ヘッダ・ファイルの定義*/
 #include        <kernel_id.h>           /*システム情報ヘッダ・ファイルの定義*/
 
 void
 func_task ( VP_INT exinf )
 {
         T_RVER  pk_rver;                /*データ構造体の宣言*/
         UH      maker;                  /*変数の宣言*/
         UH      prid;                   /*変数の宣言*/
         UH      spver;                  /*変数の宣言*/
         UH      prver;                  /*変数の宣言*/
         UH      prno[4];                /*変数の宣言*/
 
         ............
         ............
 
         ref_ver ( &pk_rver );           /*バージョン情報の参照*/
 
         maker = pk_rver.maker;          /*メーカ・コードの獲得*/
         prid = pk_rver.prid;            /*識別番号の獲得*/
         spver = pk_rver.spver;          /*バージョン番号の獲得*/
         prver = pk_rver.prver;          /*バージョン番号の獲得*/
         prno[0] = pk_rver.prno[0];      /*版数の獲得*/
         prno[1] = pk_rver.prno[1];      /*メモリ・モデルの獲得*/
 
         ............
         ............
 }
 

備考 バージョン情報T_RVERについての詳細は,「12.5.9 バージョン情報」を参照してください。