8.3.2 初期設定

初期設定ルーチンPowerON_Reset_PCは、main関数を実行する前、および実行した後に必要な手続きを記述する関数です。初期設定ルーチンの中で必要となる処理を、順番に記述します。

(1)

初期設定処理向けのPSWレジスタ初期化

初期設定処理を行うための、PSWレジスタ初期化を実施します。たとえば、初期設定処理中、割り込みを受け付けない設定にするために、PSWに対して割り込み禁止の設定をします。

リセット時のPSWは全bitゼロに初期化され、割り込み許可ビット(Iビット)も割り込み禁止状態(ゼロ)として初期化されています。

(2)

スタックポインタの初期化

スタックポインタ(USPレジスタおよびISPレジスタ)を初期化します。PowerON_Reset_PC関数に対して"#pragma entry"宣言することにより、コンパイラが自動的にISP/USP初期化コードを関数先頭に生成します。

PowerON_Reset_PC関数は、#pragma entry宣言されているため、この手続きを記述する必要はありません。

(3)

ベースレジスタに使用する汎用レジスタの初期化

コンパイラでbaseオプションを使用している場合、プログラム全体でベースアドレスとして使用する汎用レジスタを初期化する必要があります。PowerON_Reset_PC関数に対して"#pragma entry"宣言することにより、コンパイラが自動的に各レジスタへの初期化コードを関数先頭に生成します。

PowerON_Reset_PC関数は、#pragma entry宣言されているため、この手続きを記述する必要はありません。

(4)

各種制御レジスタの初期化

可変ベクタテーブルの配置アドレスを、INTBに書き込みます。その他、必要に応じて、FINTV、FPSW、BPC、BPSW、EXTBの初期化を行います。これらの初期化は、コンパイラの組み込み関数を使って行うことができます。

ただし、PSWだけは、割り込みマスク設定を維持するため、初期化はまだ行いません。

(5)

セクションの初期化処理

RAM領域セクションの初期化用ルーチン(_INITSCT)を呼び出します。未初期化データセクションはゼロ初期化されます。初期化データセクションは、ROM領域の初期値をRAM領域へコピーします。_INITSCTは、標準ライブラリとして提供されます。

初期化対象のセクションは、ユーザがセクション初期化用テーブル(DTBL,BTBL)へ記述する必要があります。_INITSCT関数が使用するセクションの先頭アドレスおよび最終アドレスを、セクションアドレス演算子を用いて設定します。

セクション初期化用テーブルのセクション名は、未初期化データ領域をC$BSEC、初期化データ領域をC$DSECで宣言します。

以下にコーディング例を示します。

 

#pragma section C C$DSEC       //セクション名をC$DSECにします
extern const struct {
    void *rom_s;               //初期化データセクションのROM上の先頭アドレスメンバ
    void *rom_e;               //初期化データセクションのROM上の最終アドレスメンバ
    void *ram_s;               //初期化データセクションのRAM上の先頭アドレスメンバ
} DTBL[] = {__sectop("D"), __secend("D"), __sectop("R")};
 
#pragma section C C$BSEC       //セクション名をC$BSECにします
extern const struct {
    void *b_s;                 //未初期化データセクションの先頭アドレスメンバ
    void *b_e;                 //未初期化データセクションの最終アドレスメンバ
} BTBL[] = {__sectop("B"), __secend("B")};

(6)

ライブラリの初期化処理

C/C++言語ライブラリ関数使用時に、必要な初期化を実施するルーチン(_INITLIB)を呼び出します。

実際に使用する機能に合わせた必要最低限の初期設定を行うために、以下の指針を参考にしてください。

-

作成した低水準インタフェースルーチンの中で初期設定が必要な場合、低水準インタフェースルーチンの仕様に合わせた初期設定(_INIT_LOWLEVEL)が必要です。

-

rand関数、strtok関数を使用する場合、標準入出力以外の初期設定(_INIT_OTHERLIB)が必要です。

 

ライブラリの初期設定を行うプログラム例を以下に示します。

#include <stdio.h>
#include <stdlib.h>
#define IOSTREAM 3	
const size_t _sbrk_size = 1024;   // ヒープ領域確保サイズの最小単位を指定します
                                  
extern char *_s1ptr;
 
#ifdef __cplusplus
extern "C" {
#endif
void _INITLIB (void)
{ 
    _INIT_LOWLEVEL();             // 低水準インタフェースルーチンの初期設定をします
    _INIT_IOLIB();                // 入出力ライブラリの初期設定をします
    _INIT_OTHERLIB();             // rand関数、strtok関数の初期設定をします
}
 
void _INIT_LOWLEVEL (void)
{                                 // 低水準ライブラリで必要な初期設定をしてください
}
 
void _INIT_OTHERLIB(void)
{
    srand(1);                     // rand関数を使用する場合の初期設定です
    _s1ptr=NULL;                  // strtok関数を使用する場合の初期設定です
}
#ifdef __cplusplus
}
#endif

注 1.

標準入出力ファイルのファイル名を指定します。この名前は、低水準インタフェースルーチン「open」で使用します。

注 2.

コンソール等対話的な装置の場合、バッファリングを行わないためのフラグを立てます。

(7)

グローバルクラスオブジェクトの初期化

C++言語のプログラム開発の場合、グローバルに宣言されたクラスオブジェクトのコンストラクタを呼び出すためのルーチン(_CALL_INIT)を呼び出します。_CALL_INITは、標準ライブラリとして提供されます。

(8)

main関数実行向けのPSW初期化

PSWレジスタを初期化します。割り込みマスクの設定も、ここで解除します。

(9)

PSWのPMビットの変更

リセット以降は特権モード(PSWのPMビットがゼロ)で動作していますが、ユーザモードに切り替えたい場合は、組み込み関数のchg_pmusrを実行します。

chg_pmusr関数にはいくつか注意事項がありますので、使用する場合は、4.2.6 組み込み関数のchg_pmusrの項目を参照ください。

(10)

ユーザプログラムの実行

main関数を実行します。

(11)

グローバルクラスオブジェクトの後処理

C++言語のプログラム開発の場合、グローバルに宣言されたクラスオブジェクトのデストラクタを呼び出すためのルーチン(_CALL_END)を呼び出します。_CALL_ENDは、標準ライブラリとして提供されます。