ベクタテーブルと例外

ベクタテーブル

ベクタテーブルとは

例外が発生した際に、処理を開始するプログラム(一般的には、「例外ハンドラ」と呼ぶ)を実行するための命令や、アドレスを保存するテーブルをベクタテーブルと呼んでいます。

ARMプロセッサのベクタテーブルとは

ARMプロセッサのベクタテーブルは、0x00000000番地に配置されますが、CP15システムコントロールレジスタのV-bit(bit 13)、またはVINITHI端子で、上位ベクタアドレス(0xFFFF0000番地)に移動させることができます。セキュリティ拡張が行われており、上位ベクタアドレスを選択していない場合は、VBAR(ベクタベースアドレスレジスタ)でベクタアドレスを変更することが可能です。

ベクタテーブルには、ARM命令(32ビット)の分岐命令を記述しますが、FIQ割り込みはベクタテーブルの最終アドレスに配置されますので、分岐命令を使用せずに、直接割り込みハンドラを記述することが可能です。

FIQ割り込みは専用レジスタが多く用意されており、割り込み処理時のスタックへのレジスタ退避復帰時間が短縮されるため、高速に処理を行うことができます。レジスタセットについては、「第4回:レジスタ」を参照ください。

ノーマルベクタオフセット 上位ベクタアドレス 例外要因
0x00 0xFFFF0000 リセット
0x04 0xFFFF0004 未定義命令例外
0x08 0xFFFF0008 スーパーバイザコール(SVC)
0x0C 0xFFFF000C プリフェッチアボート
0x10 0xFFFF0010 データアボート
0x14 0xFFFF0014 予約
0x18 0xFFFF0018 IRQ割り込み
0x1C 0xFFFF001C FIQ割り込み
....

ベクタテーブルの記述方法

割り込みベクタテーブルを作成する場合、2つの方法があります。LDR命令(リテラルプール)を使用する方法とB命令(PC相対分岐命令)を使用する方法です。B命令は、±32Mbyteの範囲内に例外ハンドラを記述することで、LDR命令よりも、高速に実行することができます。

【LDR命令(リテラルプール)を使用したベクタテーブル】

								    PRESERVE8					; 8バイト境界で境界調整されたスタックを保持
								    AREA VECTORS,CODE,READONLY	; VECTORS領域としてセクションを定義

								Vectors_Table
								    LDR   PC,Reset_Addr			; リセット例外
								    LDR   PC,Undefined_Addr		; 未定義命令例外
								    LDR   PC,SVC_Addr			; ソフトウェア割り込み
								    LDR   PC,Prefetch_Addr		; プリフェッチアボート例外
								    LDR   PC,Abort_Addr			; データアボート例外
								    B	.						; 予約ベクタテーブル
								    LDR   PC,IRQ_Addr			; IRQ割り込み
								    LDR   PC,FIQ_Addr			; FIQ割り込み
								;
								; 実行開始処理アドレス定義
								;
								Reset_Addr		DCD	Reset_Handler
												; 例外ハンドラ先頭アドレス定義
								Undefined_Addr	DCD	Undefined_Handler
												; 未定義命令例外ハンドラ先頭アドレス定義
								SVC_Addr		DCD	SVC_Handler
												; ソフトウェア割り込みハンドラ先頭アドレス定義
								Prefetch_Addr	DCD	Prefetch_Handler	
												; プリフェッチアボート例外ハンドラ先頭アドレス定義
								Abort_Addr		DCD	Abort_Handler
												; データアボート例外ハンドラ先頭アドレス定義
								IRQ_Addr		DCD	IRQ_Handler
												; IRQ割り込みハンドラ先頭アドレス定義
								FIQ_Addr		DCD	FIQ_Handler
												; FIQ割り込みハンドラ先頭アドレス定義
								

【B命令(PC相対分岐命令)を使用したベクタテーブル】

								    PRESERVE8					; 8バイト境界で境界調整されたスタックを保持
								    AREA VECTORS,CODE,READONLY	; VECTORS領域としてセクションを定義

								Vectors_Table
								    B   Reset_Handler			; リセット例外ハンドラ
								    B   Undefined_Handler		; 未定義命令例外ハンドラ
								    B   SVC_Handler				; ソフトウェア割り込みハンドラ
								    B   Prefetch_Handler		; プリフェッチアボート例外ハンドラ
								    B   Abort_Handler			; データアボート例外ハンドラ
								    B   .						; 予約ベクタテーブル
								    B   IRQ_Handler				; IRQ割り込み
								    B   FIQ_Handler				; FIQ割り込み
								

ベクタテーブルの配置方法

ターゲットのメモリ配置設定(ROM/RAMなどの設定)は、ARMコンパイラの場合、スキャッタローディングと呼ばれる方法で設定を行います。ベクタを記述したアセンブリソースファイル「vector.s」を、セクション名「VECTORS」として設定します。詳しくは、「ARMコンパイラ armlinkユーザガイド」を参照ください。

【スキャッタローディングファイル例】

								LOAD 0x00000000 0x20000000			; 256Mbyteメモリに配置
								{ 
								    VECTORS 0x00000000
								    {
								        vector.o(VECTORS,+FIRST)	; ベクタテーブルは、0x00000000先頭から配置
								        *(+RO)						; 他のオブジェクトを配置
								    }
								…
								…
								}
								

スキャッタローディングファイルでは、ベクタテーブルをFIRST属性に設定し、VECTORSセクションをイメージの先頭に配置します。この設定方法で、ベクタテーブルは、0x00000000番地から配置されます。他のオブジェクトは、リンカ配置ルールに従って配置されます。

例外

例外発生時のプロセッサの動作

  • ●例外が発生した場合、実行中のアセンブラ命令終了後、cpsr(カレントプログラムステータスレジスタ)を該当モードのspsr(保存プログラムステータスレジスタ)に、リターンアドレスは該当モードのr14に保存されます。
  • ●プロセッサモードを変更し、例外発生要因に応じた例外が禁止されます。
  • ●ベクタテーブルの命令に従って、例外ハンドラを呼び出します。
  • ●必要に応じて、レジスタをスタックに退避します。
  • ●例外ハンドラを実行します。
  • ●スタックに退避したレジスタを復帰します。
  • ●例外発生要因に応じた復帰処理を行います。
図1

例外の優先度とは

例外には優先度が設定されており、複数の例外が同時に発生する場合は、優先度に従って処理を行います。リセット例外の優先度が一番高く、どの様な状況でも実行できます。

図2

例外要因と動作モード

例外の発生で、プロセッサの動作モードが決定すると同時に、例外禁止設定も決定されます。
IRQ/FIQ割り込みは、禁止/許可の設定ができますが、他の例外は行うことができません。
ARMコンパイラは、IRQ/FIQ割り込み制御の組み込み関数が用意されているので、C/C++言語から利用できます。

例外要因 動作モード 発生要因 例外禁止
FIQ IRQ
リセット例外 スーパーバイザ リセット入力後でリセット例外を実行します。リセット例外は最も優先度が高い例外で、例外禁止を実行できません。 × ×
未定義命令例外 未定義 未定義命令を実行した場合に発生します。 ×
SVC(スーパーバイザコール) スーパーバイザ SVC命令を実行した場合に発生します。 ×
プリフェッチアボート アボート 無効なアドレスからの命令フェッチを実行した場合に発生します。 ×
データアボート アボート 無効なアドレスからのデータのリード・ライトを実行した場合に発生します。 ×
IRQ割り込み IRQ IRQ入力された場合に発生します。 ×
FIQ割り込み IRQ IRQ入力された場合に発生します。 × ×

例外動作時のレジスタセットの動作

IRQ割り込みが発生した場合のレジスタセットの動作について説明します。

  • ●r13とr14がIRQ割り込み専用に切り替わります。
  • ●cpsrがIRQモード用のspsrに保存されます。
  • ●IRQ割り込みが禁止になります。
図3

例外からの復帰方法

例外が発生した場合、例外要因に従って動作モードのリンクレジスタに戻りアドレスが設定されます。例外から復帰する場合は、発生している例外要因に従って、リンクレジスタr14を補正しなければなりません。

【リンクレジスタ補正値一覧表】

例外要因 補正値 復帰先
SVC 0 次の命令
未定義命令例外 0 次の命令
プリフェッチアボート -4 アボートを発生させた命令
データアボート -8 アボートを発生させた命令(正確なアボートの場合)
FIQ割り込み -4 次の命令
IRQ割り込み -4 次の命令

例外復帰を行う場合は、次の動作をアトミック(*1)に行うことが必要です。

  • ●リンクレジスタr14を必要に応じて補正し、プログラムカウンタr15をコピーします。
  • ●spsrからcpsrにコピーします。
図4
  • (*1)アトミックとは、複数の操作を組み合わせた場合、システムの他の部分から見て、一つの操作になることです。