本書は RZ/A2M IoT-Engine向けのμT-Kernel3.0の実装仕様を記す。 対象は、トロンフォーラムから公開されているμT-Kernel 3.0(V3.00.07)のうち、RZ/A2M IoT-Engine向けの実装部分である。
以降、単にOSと称する場合はμT-Kenrel3.0を示し、本実装と称する場合、前述のソースコードの実装を示す。
実装対象のハードウェアは以下の通りである。
分類 | 名称 | 備考 |
---|---|---|
実機 | RZ/A2M IoT-Engine | UCテクノロジー製 |
搭載マイコン | RZ/A2M (R7S921053VCBG) | ルネサス エレクトロニクス製 |
RZ/A2M IoT-Engineのターゲット名および関連する識別名は以下とする。
分類 | 名称 | 対象 |
---|---|---|
ターゲット名 | _IOTE_RZA2M_ | |
対象システム | IOTE_RZA2M | RZ/A2M IoT-Engine |
対象CPU | CPU_RZA2M | RZ/A2M |
対象CPUアーキテクチャ | CPU_CORE_ARMV7A | ARMv7-A |
対象CPUコア | CPU_CORE_ACA9 | ARM Cortex-A9コア |
識別名は以下のファイルで定義される。
include/sys/sysdepend/iote_rza2m/machine.h
以下に関連するドキュメントを記す。
分類 | 名称 | 発行 |
---|---|---|
OS | μT-Kernel 3.0仕様書(Ver.3.00.01) TEF020-S004-03.00.01 |
TRONフォーラム |
OS | μT-Kernel3.0共通実装仕様書(Ver.2.00.00) TEF033-W002-2304xx |
TRONフォーラム |
T-Monitor | T-Monitor仕様書 TEF020-S002-01.00.01 |
トロンフォーラム |
デバイスドライバ | μT-Kernel 3.0 デバイスドライバ説明書(Ver.1.00.05) TEF033-W007-221007 |
トロンフォーラム |
搭載マイコン | RZ/A2Mグループ ユーザーズマニュアル ハードウェア編 | ルネサス エレクトロニクス |
1.5 ソースコード構成
機種依存定義sysdependディレクトリ下の本実装のディレクトリ構成を以下に示す。名称に(*)の点いたディレクトリが本実装の対象である。
─ sysdepend ハードウェア依存部
├ iote_rza2m RZ/A2M IoT-Engine依存部 (*)
├ :
├ <ターゲットn> ターゲットn 依存部
└ cpu CPU依存部
├ rza2m RZ/A2Mマイコン依存部 (*)
├ :
└ <CPUn> CPUn依存部
└ core コア依存部
├ armv7a ARMv7-Aコア依存部
├ :
└ <core n> コアn依存部
「ARMv7-Aコア依存部」は、ARMv7-Aコアに共通するコードであり、他の共通のコアを有するマイコンでも使用される。 「RZ/A2Mマイコン依存部」は、前述のコア依存部以外の本マイコンに固有のコードである。 「RZ/A2M IoT-Engine依存部」は、前述のコア依存部およびマイコン依存部以外のRZ/A2M IoT-Enginのハードウェアに固有のコードである。
実装対象のマイコンの基本的な仕様を以下に記す。
項目 | 内容 |
---|---|
CPUコア | ARM Cortex-A9 |
ROM | 外部 |
RAM | 内蔵4MB + 外部 |
ARM Cortex-A9コアは、プログラムの動作モードとして、特権および非特権の複数のモードを持つ。本実装では、基本的にはSVCモードを使用する。メモリ保護は行わず、常にすべてのメモリにアクセス可能とする。 よってOSが提供する保護レベルは、、すべて保護レベル0とみなす。カーネルオブジェクトに対して保護レベル1~3を指定しても保護レベル0を指定されたものとして扱う。 プロファイルTK_MEM_RNG0~TK_MEM_RNG3はすべて0が返される。
本マイコンは内部レジスタとして、汎用レジスタ(R0~R12)、SP(R13)、LR(R14)、PC(R15) 、CPSRを有する。
OSのAPI (tk_set_reg、 tk_get_reg) を用いて実行中のタスクのコンテキストのレジスタ値を操作できる。 APIで使用するマイコンのレジスタのセットは 以下のファイルにて定義される。
include/tk/sysdepend/cpu/core/armv7a/cpudef.h
(1) 汎用レジスタ
typedef struct t_regs {
VW r[13]; /* General purpose register R0-R12 */
void *lr; /* Link register R14 */
} T_REGS;
(2) 例外時に保存されるレジスタ T_EIT
typedef struct t_eit {
void *pc; /* Program counter R15 */
UW cpsr; /* Program status register */
UW taskmode; /* Task mode flag */
} T_EIT;
(3) 制御レジスタ T_CREGS
typedef struct t_cregs {
void *ssp; /* System stack pointer R13_svc */
} T_CREGS;
OSのAPIによって操作されるのは、実際にはスタック上に退避されたレジスタの値である。よって、実行中のタスクに操作することはできない(OS仕様上、自タスクへの操作、またはタスク独立部からのAPI呼出しは禁止されている)。
taskmodeレジスタは、マイコンの物理的なレジスタを割り当てず、OS内の仮想的なレジスタとして実装する。本レジスタは、メモリへのアクセス権限(保護レベル)を保持する仮想レジスタである。ただし、本実装ではプログラムは特権モードでのみ実行されるので、常に値は0となる。
省電力機能はサポートしていない。プロファイルTK_SUPPORT_LOWPOWERはFALSEである。よって、マイコンの低消費電力モードに対応する機能は持たない。
省電力機能のAPI(low_pow、off_pow)は、kernel/sysdepend/iote_rza2m/power_save.cに空関数として記述されている。本関数に適切な省電力処理を記述し、プロファイルTK_SUPPORT_LOWPOWERをTRUEに指定すれば、OSの省電力機能(tk_set_pow)は使用可能となる。
本マイコンは浮動小数演算コプロセッサ(NEON/VFP)を内蔵する。 コンフィギュレーションUSE_FPUをTRUEに指定すると、OSでFPU対応の機能が有効となり、FPUにコプロセッサ番号0が割り当てられる。 FPUが有効の場合、以下の機能が有効となる。
(1) FPUの初期化 OS起動時にコンフィギュレーションUSE_FPUが指定されている場合、FPUを有効化する。具体的には、アドバンスドSIMD拡張機能とVFP拡張機能が稼働状態となる。
(2) TA_FPU属性のタスク タスク属性にTA_FPUまたはTA_COP0が指定可能となる。本属性のタスクは、ディスパッチ時にFPUレジスタの値を保存し、FPUの仕様が可能となる。TA_FPUとTA_COP0は同じ意味である。
(3) FPU関連API コンフィギュレーションUSE_FPUが指定されている場合、FPU関連のAPI (tk_set_cop、 tk_get_cop) が使用可能となる。本APIを用いて実行中のタスクのコンテキストのFPUレジスタ値を操作できる。 FPUレジスタは以下のファイルで定義される。
include/tk/sysdepend/cpu/core/armv7a/cpudef.h
typedef struct t_copregs {
UD d[32]; /* FPU General purpose register d0-d31 */
UW fpscr; /* Floating-point Status and Control Register */
} T_COPREGS;
APIによって操作されるのは、実際にはスタック上に退避されたレジスタの値である。よって、実行中のタスクに操作することはできない(OS仕様上、自タスクへの操作、またはタスク独立部からのAPI呼出しは禁止されている)。
(4) FPU使用の際の注意点 ・タスクからのFPUの使用 TA_FPU属性のタスクはFPUの使用が可能である。非TA_FPU属性のタスクからFPUを使用しようとした場合は未定義命令例外が発生する。 タスクの実行開始時は、FPUは常に無効である。タスクのコンテキストでFPUが最初に実行されると、未定義命令例外の処理が実行され、タスクがTA_FPU属性であればFPUが有効化される。 非TA_FPU属性のタスクへのディスパッチでFPUは無効化される。また、TA_FPU属性のタスクであっても、他のタスクがFPUを使用していた場合は、いったんFPUは無効化される。ディスパッチ後にそのタスクの中でFPU命令が実行された時、未定義命令例外の処理にて再びFPUが有効化される。その際、FPUレジスタの保存と復帰が行われる。
・割込みハンドラからのFPU使用 割込みハンドラの起動時にFPUレジスタの退避は行われない。よって、原則として割込みハンドラ内のFPUの使用は禁止である。 もし割込みハンドラ内でFPUを使用する場合は、FPUの有効化およびFPUレジスタの退避を割込みハンドラにて行わなければならない。また、割込みハンドラから復帰の際にはFPUの状態およびFPUレジスタの内容を基の状態に復帰させなくてはならない。 割込みハンドラ内での意図しないFPUの使用を検出するため、割込みハンドラの高級言語ルーチンにてFPUの無効化を行うことができる。本処理はinclude/sys/sysdepend/cpu/core/armv7a/sysdef.hのINTHDR_DIS_FPUの定義で制御できる。 INTHDR_DIS_FPU=1の場合、割込みハンドラの呼び出し時にFPUは無効化される。INTHDR_DIS_FPU=0の場合はOSは何も行わない。割込みハンドラ内でFPUを使用する場合は、INTHDR_DIS_FPU=0とする必要がある。標準の定義ではINTHDR_DIS_FPU=1である。
・タイムイベントハンドラ タイムイベントハンドラにおけるFPUの使用は、割込みハンドラに準ずる。
・その他の例外ハンドラ その他の例外ハンドラの実行時には、OSはFPUに関する操作を行わない。必要に応じて、FPUの無効化やレジスタの退避などを行うこと。
ARM Cortex-A9はMMU(Memory Management Unit:メモリ管理ユニット)は有し、32bitの仮想アドレス空間で動作する。本実装では物理アドレス空間と仮想アドレス空間のアドレスを一致させている。つまり、仮想アドレスは物理アドレスと同一である。 本実装では、プログラムは一つの実行オブジェクトに静的にリンクされていることを前提とする。OSとユーザプログラム(アプリケーションなど)は静的にリンクされており、関数呼び出しが可能とする。
3.2 対象システムのメモリマップ 以下にRZ/A2M IoT-Engineのメモリマップを記す。
アドレス (上段:開始 下段:終了) |
種別 | サイズ (MByte) |
備考 |
---|---|---|---|
0x2000 0000 0x207F FFFF |
シリアルFLASH | 8 | 外部シリアルFLASH ROM (※1) |
0x4000 0000 0x407F FFFF |
HyperRAM | 8 | 外部RAM |
0x8000 0000 0x803F FFFF |
RAM | 4 | 内蔵RAM (※2) |
※1 シリアルFLASH ROMはブート時のプログラム格納用 ※2 内蔵RAMは4Mbyteのうち、先頭の128Kbyteが保持用内蔵RAM(BackUp RAM)として使用可能
本実装では、OSはマイコンの内蔵RAMのみを使用する。 OSは外部RAMを使用しなので、OS管理外のメモリとしてユーザが自由に使用することができる。 外部シリアルFLASH ROMにはブート時のプログラム(ブートローダ)が格納され、ブート時に実行される。OSを含む全てのプログラムのコードもFLASH ROMに格納されており、ブートローダによりRAM上に配置され実行される。
以下に内蔵RAMのメモリマップを示す。表中でアドレスに「-」が記載された箇所はデータのサイズによりC言語の処理系にてアドレスが決定され、OS内ではアドレスの指定は行っていない。
(1) 内蔵RAMのメモリマップ
アドレス (上段:開始 下段:終了) |
種別 | 内容 | |
---|---|---|---|
0x8000 0000 |
0x8001 FFFF | バックアップRAM領域 | 未使用 |
0x8002 0000 - |
例外ベクタテーブル | 例外や割込みのベクタテーブル リセット時のみ有効 |
|
- - |
プログラムコード | プログラムコードが配置される領域 | |
- - |
定数データ | C言語の定数データなどが配置される領域 | |
- - |
プログラムデータ | C言語の変数等が配置される領域 | |
- - |
例外スタック領域 | 例外および割込みハンドラにて使用されるスタック | |
- - |
OS管理領域(システムメモリ) | OS内部の動的メモリ管理の領域 | |
0x8030 0000 0x803F BFFF |
非キャッシュ領域 | 未使用 | |
0x803F C000 0x803F FFFF |
TTB領域 | Translation Table領域 |
内蔵RAMの先頭128KBはBackUp RAMでありOSは未使用である。 内蔵RAMの0x8030 0000番地以降は非キャッシュ領域に設定される。非キャッシュ領域のうちTTB領域以外はOSでは使用しないので、OS管理外メモリとしてユーザが自由に使用することができる。
本実装で使用するスタックには共通仕様に従い以下の種類がある。
(1) タスクスタック (2) 例外スタック (3) テンポラリスタック
上記の共通仕様のスタックの他に、その他の例外(FIQ、未定義命令、アボート)について、それぞれ独立にスタックが割り当てられる。これらのスタックのサイズはinclude/sys/sysdepend/cpu/core/armv7a/sysdef.hにて以下のように定義されている。この値を変更し、再構築することによりスタックのサイズを変更することができる。
#define FIQ_STACK_SIZE (256) /* FIQ exception stack size */
#define UND_STACK_SIZE (256) /* Undefined instruction exception stack size */
#define ABT_STACK_SIZE (256) /* Abort exception stack size */
コンフィギュレーションのUSE_IMALLOCが1の場合、動的メモリ管理に使用するシステムメモリが確保される。USE_IMALLOCが0の場合、動的メモリ管理は無効となる。USE_IMALLOCの初期値は1である。 システムメモリの領域は以下のように定められる。
(1) OS管理メモリ領域の開始アドレス コンフィギュレーションCNF_SYSTEMAREA_TOPの値が0以外の場合は、その値が開始アドレスとなる。ただし、その値がプログラムのデータ領域の最終アドレスより前の場合は、データ領域の最終アドレスの次のアドレスが開始アドレスとなる。つまり、データ領域と重複することはない。 値が0の場合、プログラムが使用しているデータ領域の最終アドレスの次のアドレスが、開始アドレスとなる。
(2) OS管理メモリ領域の終了アドレス コンフィギュレーションCNF_SYSTEMAREA_ENDの値が0以外の場合は、その値が終了アドレスとなる。ただし、その値が非キャッシュ領域の開始アドレスより後ろの場合は、非キャッシュ領域の開始アドレスの前のアドレスが終了アドレスとなる。つまり、非キャッシュ領域と重複することはない。 値が0の場合、非キャッシュ領域の開始アドレスの前のアドレスが、終了アドレスとなる。
本マイコンには以下の例外が存在する。
例外の種別 | 備考 |
---|---|
リセット | |
未定義例外 | |
SVC(スーパーバイザコール) | OSで使用 |
プリフェッチアボート | |
データアボート | |
IRQ割込み | OSの割込み管理機能で管理 |
FIQ割込み |
本マイコンは割込みコントローラとして、GIC-400(汎用割込みコントローラ)を搭載する。割込みコントローラは、IRQおよびFIQ割込みの管理を行う。 OSの割込み管理機能が管理対象とするのはIRQ割込みである。よって、本実装で割込みと言った場合は、IRQ割込みを指す。
本マイコンでは、前述の各種例外に対応する例外ハンドラのアドレスを設定したベクタテーブルを有する。 本実装では、リセット時のベクタテーブルは、以下のファイルにvector_tableとして定義される。
kernel/sysdepend/cpu/core/armv7a/vector_tbl.S
割込みコントローラは、割込み優先度を5bit(0~31)の32段階に設定できる(優先度の数字の小さい方が優先度は高い)。 外部割込みは優先度0~31が割り当て可能である。ただし本実装では、システムタイマ割込みが優先度1を使用する。よって、ユーザプログラムから使用可能な外部割込みの優先度は、通常は2~31の30段階である。
システムタイマ割込みの優先度はinclude/sys/sysdepend/cpu/rza2m/sysdef.hで以下のように定義される。
#define INTPRI_SYSTICK 1 /* interrupt priority for SysTick */
本OSの内部で使用する割込み・例外には、以下のように本マイコンの割込み・例外が割り当てられる。該当する割込み・例外は、OS以外で使用してはならない。
種類 | 割り当てられる割込み・例外 | 割込み優先度 |
---|---|---|
システムタイマ割込み | OSTMI0 (IRQ 88) | 1 |
システムコール | SVC 6 | - |
ディスパッチ要求 | SVC 7 | - |
強制ディスパッチ要求 | SVC 8 | - |
デバッグサポートコール | SVC 9 | - |
拡張SVC | SVC 10 | - |
SVCの割り当てはinclude/sys/sysdepend/cpu/core/armv7a/sysdef.hで以下のように記述される。
#define SVC_SYSCALL 6 /* micro T-Kernel system call */
#define SVC_FORCE_DISPATCH 7 /* force dispatch */
#define SVC_DISPATCH 8 /* task dispatcher */
#define SVC_DEBUG_SUPPORT 9 /* debug support function */
#define SVC_EXTENDED_SVC 10 /* Extended SVC */
ユーザプログラムは上記のSVC例外を使用してはならない。 ただし、本実装ではSVC例外はディスパッチ要求および強制ディスパッチ要求にのみ使用する。これ以外のSVC割込みは、将来の拡張に備えて定義のみが存在する。
ディスパッチ要求は、本実装ではクリティカルセクションの最後に、タスクのディスパッチが必要な場合に発行される。また、強制ディスパッチ要求は、OSの起動時とタスクの終了時に発行される。
割込みハンドラは、IRQ割込みがマスクされた状態で実行されるので、そのままでは多重割込みは受け付けない。 多重割込みに対応するには、割込みハンドラ内で割込みマスクレベルを適切な値に設定したのち、IRQ割込みを有効とする。
本実装では、クリティカルセクションはCPSRレジスタのIビットをIRQ割込み禁止に設定することにより実現する。よって、IRQ割込み以外の例外はクリティカルセクション中でもマスクされない。
μT-Kernel/OSの割込み管理機能は、割込みハンドラの管理を行う。 本実装では、対象とする割込み(割込みハンドラが定義可能な割込み)はIRQ割込みのみとし、その他の例外については対応しない。 割込みハンドラに関して以下のように定める。
割込み番号 OSの割込み管理機能が使用する割込み番号は、割込みコントローラの割込みID番号と同一とする。
割込みハンドラの呼び出し IRQ割込みが発生するとIRQ処理ルーチンが実行される。 IRQ処理ルーチンでは以下の処理が実行される。
(1) CPUの実行モードをSVCモードに変更する
(2) 割込みコントローラの割込みアクノリッジレジスタ(ICCIAR)より、発生している割込みID番号を取得する。
(3) 割込みID番号に基づき、割込みベクタテーブルknl_intvec_tblに設定されている割込みハンドラを実行する。割込みハンドラが設定されていなかった場合は、デフォルトハンドラを実行する。
TA_HLNG属性の割込みハンドラは、OSの割込み処理ルーチンを経由して呼び出される。OSの割込み処理ルーチンでは以下の処理が実行される。
(1) タスク独立部の設定 処理開始時にシステム変数knl_taskindpをインクリメントし、終了時にデクリメントする。本変数が0以上の値のとき、タスク独立部であることを示す。
(2) IRQスタックの設定 スタックを例外スタック(IRQ割込み用スタック)に変更する。
(3) FPUの無効化 FPU使用時(コンフィギュレーションUSE_FPUが有効)、割込みハンドラのFPU制御が有効(INTHDR_DIS_FPU = 1)の場合、FPUを無効化する。割込みハンドラの実行後にFPUは元の状態に戻される。 割込みハンドラのFPU制御が無効(INTHDR_DIS_FPU = 0)の場合は何も行わない。
(4) 割込みハンドラの実行 割込みID番号に基づき、テーブルknl_hll_inthdr_tblに登録されている割込みハンドラを実行する。
TA_ASM属性の割込みハンドラは、割込みベクタテーブルに直接登録される。よって、割込み発生時には、OSの割込み処理を介さずに直接ハンドラが実行される。このためTA_ASM属性の割込みハンドラからは、原則としてAPIなどのOS機能の使用が禁止される。ただし、前述のOS割込み処理ルーチンと同様の処理を行うことにより、OS機能の使用が可能となる。
デフォルトハンドラ 割込みハンドラが未登録の状態で、割込みが発生した場合はデフォルトハンドラが実行される。デフォルトハンドラは、以下のファイルにDefault_Handler関数として実装されている。
kernel/sysdepend/cpu/core/armv7a/exc_hdl.c
デフォルトハンドラは、プロファイルUSE_EXCEPTION_DBG_MSGを1に設定することにより、デバッグ用の情報を出力する。デバッグ情報は、T-Monitor互換ライブラリのコンソール出力に出力される。初期設定は1(有効)である。
必要に応じてユーザがデフォルトハンドラを記述することにより、未定義割込み発生時の処理を行うことができる。デフォルトハンドラはweak宣言がされているので、ユーザが同名の関数を作成しリンクすることにより、上書きすることができる。
μT-Kernel/SMの割込み管理機能は、CPUの割込み管理機能および割込みコントローラの制御を行う。 本機能の各APIの実装について以下に記す。
① CPU割込みの禁止(DI) CPU割込みの禁止(DI)は、CSPRレジスタのIビットをIRQ割込み禁止に設定する。
② CPU割込みの許可(EI) 割込みの許可(EI)は、CSPRレジスタのIビットの値をDI実行前に戻す。
③ CPU内割込みマスクレベルの設定(SetCpuIntLevel) CPUに本機能はないため、未実装である。
④ CPU内割込みマスクレベルの参照(GetCpuIntLevel) CPUに本機能はないため、未実装である。
① 割込みコントローラの割込み許可(EnableInt) 割込みイネーブルセットレジスタ(GICD_ISENABLER)を設定し、指定された割込みを許可する。同時に割込み優先度レジスタ(GICD_IPRIORITYR)に指定された割込み優先度を設定する。ユーザプログラムは、割込み優先度2~31を使用しなければならない。
② 割込みコントローラの割込み禁止(DisableInt) 割込みイネーブルクリアレジスタ(GICD_ICENABLER)を設定し、指定された割込みを禁止する。
③ 割込み発生のクリア(ClearInt) 割込み保留クリアレジスタ(GICD_ICPENDR)を設定し、指定された割込みが保留されていればクリアする。
④ 割込みコントローラのEOI発行(EndOfInt) 割込み終了レジスタ(GICC_EOIR)に指定された割込みの終了を設定する。
⑤ 割込み発生の検査(CheckInt) 割込み保留クリアレジスタ(GICD_ICPENDR)を参照し、割込みの発生を調べる。
⑥ 割込みモード設定(SetIntMode) 割込み構成レジスタ(GICD_ICFGR)に指定された割込みモードを設定する。 指定可能な割込みモードは、include/tk/sysdepend/cpu/rza2m/syslib.hに以下のように定義されている。
#define IM_LEVEL 0x00 /* high level detection */
#define IM_EDGE 0x01 /* Rising edge detection */
設定可能な割込みは、外部端子割込み(割込み番号480~511)である。
⑦ 割込みコントローラの割込みマスクレベル設定(SetCtrlIntLevel) 割込み優先度マスクレジスタ(GICC_PMR)に指定された割込みマスクレベルを設定する。
⑧ 割込みコントローラの割込みマスクレベル取得(GetCtrlIntLevel) 割込み優先度マスクレジスタ(GICC_PMR)から設定されている割込みマスクレベルを取得する。。
OSのクリティカルセクション中に割込み可能な割込みおよび例外は、OS管理外割込みとなる。 OS管理外割込みはOS自体の動作よりも優先して実行される。よって、OSから制御することはできない。また、OS管理外割込みの中でOSのAPIなどの機能を使用することも原則としてできない。 本実装ではクリティカルセクションはIRQ割込みが無効に設定される。よって、未定義例外、プリフェッチアボート、データアボート、FIQ割込みが、OS管理外割込みとなる。
例外のエントリルーチンはkernel/sysdepend/cpu/core/armv7a/exc_entry.Sに記述される。 本実装では、IRQ割込み以外の例外はOSの管理外である。ただし、FPU使用時(コンフィギュレーションUSE_FPUが有効)は、FPU命令実行による未定義例外はOSのFPU処理が実行される。 IRQ割込み以外の例外は、各例外のエントリルーチンから暫定的な例外ハンドラを呼び出す。暫定的な例外ハンドラは、kernel/sysdepend/cpu/core/armv7a/exc_hdl.cの以下の関数として実装されている。
例外の種別 | 関数名 |
---|---|
未定義例外 | UndefinedInst_Handler |
プリフェッチアボート | PrefetchAbort_Handler |
データアボート | DataAbort_Handler |
FIQ割込み | FIQ_Handler |
必要に応じてユーザが例外ハンドラを記述することにより、各例外に応じた処理を行うことができる。暫定的な例外ハンドラはweak宣言がされているので、ユーザが同名の関数を作成しリンクすることにより、上書きすることができる。
暫定的の例外ハンドラは、プロファイルUSE_EXCEPTION_DBG_MSGを1に設定にすることにより、デバッグ用の情報を出力する。初期設定は1(有効)である。
暫定的な例外ハンドラは、発生した例外のCPUモードで実行される。スタックは、例外毎に割り当てられた独立のスタックが使用される。
リセット処理は、マイコンのリセットベクタに登録され、マイコンのリセット時に実行される。 リセット処理はkernel/sysdepend/cpu/core/armv7a/reset_hdl.SのReset_Handlerおよびkernel/sysdepend/cpu/core/armv7a/reset_main.cのreset_main関数に記述される。
リセット処理の手順を以下に示す。
(1) ハードウェア初期化(Reset_Handler) リセット後の基本的なハードウェア(キャッシュ、MMU、FPU等)の初期化を行った後、reset_main関数を実行する。
(2) 周辺デバイス初期化(knl_startup_hw) knl_startup_hw関数を呼出し、リセット時の最小限のハードウェアの初期化を行う。 詳細は次項「周辺デバイス初期化」を参照のこと。
(3) 変数領域(data, bss)の初期化(reset_main) 共通実装仕様書を参照のこと。
(4) システムメモリ領域の確保(reset_main) 共通実装仕様書を参照のこと。
(5) L1キャッシュの初期化(L1CacheInit) L1キャッシュを初期化する。
(6) OS初期化処理(main)の実行 リセット処理を終了するOSの初期化処理(main)を実行し、リセット処理は終了する。
knl_startup_hw関数は以下のファイルに定義される。
kernel/sysdepend/iote_rza2m/hw_setting.c
knl_startup_hw関数では以下の処理が実行される。ユーザは必要に応じてknl_startup_hw関数の内容を変更してよい。
(1) CPUクロックの設定 CPUクロックの設定は以下のファイルのstartup_clock関数で行っている。
kernel/sysdepend/iote_rza2m/cpu_clock.c
本実装では以下の設定となる。
項目 | 設定 | 周波数 |
---|---|---|
CPUクロック(I) 周波数の分周率 | ×1/2倍 | 528MHz |
内部バスクロック(B) 周波数の分周率 | ×1/8倍 | 132MHz |
周辺クロック 1(P1)周波数の分周率 | ×1/16倍 | 66MHz |
上記設定は、クロックパルス発振器の周波数制御レジスタFRQCRを設定することにより行われる。FRQCRの設定値は以下のファイルで定義されている。
ファイル名:include/sys/sysdepend/cpu/rza2m/sysdef.h
#define CPG_FRQCR_INIVAL 0x1012
なお、クロックの設定を変更した場合は、OSのクロック制御やデバイスドライバの制御にも影響がある場合があるため、合わせてプログラムの変更を行わなくてはならない。
(2) 周辺モジュールのクロック供給 使用する周辺モジュールにクロックを供給する。 設定はstbcr_tblテーブルの内容に従い実行する。 stbcr_tblテーブルの要素は以下の構造体であり、レジスタのアドレスと設定値を示す。テーブルの内容を変更することにより設定を変えることができる。
typedef struct {
UW addr;
UW data;
} T_SETUP_REG;
初期値では以下のペリフェラルへのクロック供給が有効となっている。
● コンフィギュレーションUSE_SDEV_DRVが無効(0)の場合
名称 | 機能 | 用途 |
---|---|---|
SCIF4 | シリアル通信 | デバッグ用シリアル入出力 |
OSTM0, OSTM1, OSTM2 | OSタイマ | システムタイマ、物理タイマ |
● コンフィギュレーションUSE_SDEV_DRVが有効(1)の場合
名称 | 用途 |
---|---|
SCIF4 | デバッグ用シリアル入出力 |
OSTM0, OSTM1, OSTM2 | システムタイマ、物理タイマ |
A/D, RTC0, RTC1 RIIC0, RIIC3, SPIBSC |
(3) 端子機能の設定 各端子の機能設定を行う。 設定は、pmode_tblテーブルおよびpfunc_tblテーブルの内容に従い実行する。 各テーブルの要素は前述のT_SETUP_REG構造体である。テーブルの内容を変更することにより各端子の初期設定を変更することが可能である。 初期値では以下の端子の機能が設定されている。
● コンフィギュレーションUSE_SDEV_DRVが無効(0)の場合
I/Oポート名 | 機能名 | 用途 |
---|---|---|
P90 | TxD4 | デバッグ用シリアル入出力(T-Monitor) |
P91 | RxD4 | 同上 |
● コンフィギュレーションUSE_SDEV_DRVが有効(1)の場合
I/Oポート名 | 機能名 | 用途 |
---|---|---|
P90 | TxD4 | デバッグ用シリアル入出力(T-Monitor) |
P91 | RxD4 | 同上 |
P50 | AN000 | アナログ入力 |
P51 | AN001 | アナログ入力 |
P52 | AN002 | アナログ入力 |
P90 | SCIFA.TxD4 | デバッグ用シリアル入出力(T-Monitor) |
P91 | SCIFA.RxD4 | 同上 |
PD0 | RIIC0.SCL | デバイスドライバ(I2C) |
PD1 | RIIC0.SDA | 同上 |
PD6 | RIIC3.SCL | 同上 |
PD7 | RIIC3.SDA | 同上 |
OS初期化処理は共通部のmain関数で実行される。 main関数から以下の対象システムに依存する処理が実行される。
(1) デバイスの初期化 knl_init_device main関数より呼び出され、デバイスドライバの登録に先立ち、必要なハードウェアの初期化を行う。 デバイスの初期化は以下のファイルにknl_init_device関数として実装される。
kernel/sysdepend/iote_rza2m/devinit.c
なお、本実装ではknl_init_device関数内の処理は記述されてないので、ユーザは必要に応じてknl_init_device関数に処理を記述すること。
(2) 割込み初期化 (knl_init_interrupt) 割込みの初期化を行う。 以下のファイルにknl_init_interrupt関数として定義される。
kernel/sysdepend/cpu/core/armv7a/interrupt.c
(3) システムタイマ初期化 (knl_start_hw_timer) システムタイマのハードウェアに依存した初期化を行う。以下のファイルにknl_start_hw_timerインライン関数として定義される。
kernel/sysdepend/cpu/core/armv7a/sys_timer.h
本インライン関数では、OSTM0タイマをコンフィギュレーションCNF_TIMER_PERIODで指定したシステムタイマの割込み周期で割込みが発生するように設定を行っている。
初期タスクの処理は共通部のinit_task_main関数で実行される。 init_task_main関数から以下の対象システムに依存する処理が実行される。
(1) デバイスの実行(knl_start_device) デバイスドライバの登録、実行を行う。本処理は以下のファイルにknl_start_device関数として定義される。
kernel/sysdepend/iote_rza2m/devinit.c
コンフィギュレーションUSE_SDEV_DRVが有効(1)の場合、以下の基本的なデバイスドライバが登録される。
デバイス名 | 機能 |
---|---|
sere | シリアル通信(SCIFA4) |
iicd | I2C通信(RIIC3) |
adca | A/Dコンバータ(AN000) |
コンフィギュレーションUSE_SDEV_DRVが無効(0)の場合、デバイスドライバの登録は行われない(初期値は無効(0))。
ユーザが使用するデバイスドライバを変更する場合は、必要に応じて上記の関数の処理を変更する必要がある。
終了処理と再起動処理は共通部のshutdown_system関数で実行される。shutdown_system関数からハードウェアに依存する処理が呼び出される。
(1) デバイスの終了処理 knl_finish_device knl_start_deviceと対となるデバイスの終了処理を実行する。 knl_finish_device関数は以下のファイルに定義される。
kernel/sysdepend/iote_rza2m/devinit.c
なお、本実装ではknl_finish_device関数内の処理は記述されてないので、ユーザは必要に応じてknl_finish_device関数に処理を記述すること。
(2) ハードウェア停止処理(knl_shutdown_hw) ハードウェアをすべて停止し、マイコンを終了状態とする。本関数の処理でシステムは終了する。 knl_shutdown_hw関数は以下のファイルに定義される。
kernel/sysdepend/iote_rza2m/hw_setting.c
なお、本実装では割込みを無効とし無限ループを行っている。ユーザは必要に応じてknl_shutdown_hw関数の内容を変更してよい。
(3) ハードウェア再起動(knl_restart_hw) ハードウェアの再起動処理を行う。knl_restart_hw関数は以下のファイルに定義される。
kernel/sysdepend/iote_rza2m/hw_setting.c
なお、本実装では再起動には対応していないので、処理のひな型のみを記述している。knl_restart_hw関数はエラーを返して終了し、システムは終了するようになっている。ユーザは必要に応じて、knl_restart_hw関数に再起動処理を記述すること。
(4) システムタイマ終了処理 (knl_terminate_hw_timer) システムタイマのハードウェアに依存した終了化を行う。以下のファイルにknl_terminate_hw_timerインライン関数として定義される。
kernel/sysdepend/cpu/core/armv7a/sys_timer.h
本インライン関数では、OSTM0タイマを停止し、タイマ割込みも発生しないようにする。
本マイコンに依存するタスクの仕様を以下に記す。
タスク属性のハードウェア依存仕様を以下に示す。
属性 | 可否 | 説明 |
---|---|---|
TA_COP0 | 〇 | FPU(TA_FPUと同じ) |
TA_COP1 | × | 対応無し |
TA_COP2 | × | 対応無し |
TA_COP3 | × | 対応無し |
TA_FPU | 〇 | FPU(TA_COP0と同じ) |
タスクの処理ルーチンの実行開始時の各レジスタの状態は以下である。これ以外のレジスタの値は不定である。
レジスタ | 値 | 補足 |
---|---|---|
PRIMASK | 0 | 割込み許可 |
R0 | 第一引数 stacd | タスク起動コード |
R1 | 第二引数 *exinf | タスク拡張情報 |
R13(SP) | タスクスタックの先頭アドレス |
スタック上に保存されるタスクのコンテキスト情報を以下に示す。
(1) FPUレジスタを保存しない場合 SPSRからR0までのレジスタの値はディスパッチ時の例外により保存される。R4からR11のレジスタの値はディスパッチャにより保存される。
High Address +---------------+
| SPSR_xxx |
| R14_xxx(LR) | Return address
| R14_svc(LR) |
| R12(IP) |
| R0-R3 |
+---------------+ Save by Exception entry process.
| R5 - R11 |
ssp -> | R4 |
Low Address +---------------+
(2) FPUレジスタを保存する場合 タスクスタック領域の先頭にFPUコンテキスト領域を確保し、FPUのレジスタの値を保存する。FPUレジスタの保存は、ディスパッチ時にFPUを使用しているタスクが変更になる際に行われる。 FPUコンテキスト領域は以下の構造体として定義される。
typedef struct {
UW rsv; // リザーブ
UW fpscr; // fpscrレジスタ
UD d[32]; // FPUレジスタ D0~D31
} FPUContext;
その他のレジスタについては、TA_FPU属性以外のタスクと同様である。
本実装では、マイコン内蔵のOSタイマ(OSTM0)をシステムタイマとして使用する。 システムタイマのティック時間は、1ミリ秒から50ミリ秒の間で設定できる。 ティック時間の標準の設定値は10ミリ秒である。
本実装ではタイムイベントハンドラの実行中はすべての割込みを許可される。
マイコン内蔵のOSタイマ(OSTM1~OSTM2)を使用して2個の物理タイマが実装されている。OSタイマは32ビットタイマである。 OSタイマには以下のように物理タイマ番号が1から割り当てられる。
物理タイマ番号 | 対応するタイマ |
---|---|
1 | OSTM1 |
2 | OSTM2 |
OSタイマは物理タイマ以外の用途にも使用可能である。その場合は物理タイマAPIを呼び出さなければよい(API StartPhysicalTimerにてOSタイマは物理タイマに初期化される)。
物理タイマ(OSタイマ)のカウントクロックはP1クロックである。本実装では周波数33MHzとなる。
物理タイマはその内部処理において、各タイマの割込みを使用する。
物理タイマ番号 | 対応する割込み | 割込み番号 |
---|---|---|
1 | OSTMI1割込み | 89 |
2 | OSTMI2割込み | 90 |
各割込みの優先度はに以下のファイルに定義される。割込み優先度は必要に応じて変更可能である。
include/sys/sysdepend/cpu/rza2m/sysdef.h ``` #define INTPRI_OSTM1 5 #define INTPRI_OSTM2 5 ```
T-Monitor互換ライブラリのAPIによるコンソール入出力の仕様を以下に示す。
項目 | 内容 |
---|---|
デバイス | 内蔵シリアルI/F (SCIFA4) |
ボーレート | 115200bps |
データ形式 | data 8bit, stop 1bit, no parity |
版数 | 日付 | 内容 |
---|---|---|
2.00.01 | 2024.04.01 | ・誤記修正 |
2.00.00 | 2023.12.01 | ・内容および構成の全面見直 |
1.00.03 | 2022.10.15 | ・誤字修正 |
1.00.02 | 2022.10.07 | ・μT-Kernelおよび関連仕様書バージョン更新 ・誤記修正(ARMv7M → ARMv7A) |
1.00.01 | 2021.11.15 | ・1.4 関連ドキュメント バージョン番号等を更新 |
1.00.00 | 2021.08.27 | ・初版 |
以上