RealView Compilation Tools - ARM Information Center

RealView Compilation Tools
®
バージ ョ ン 3.1
デベロ ッ パガ イ ド
Copyright © 2007 ARM Limited. All rights reserved.
ARM DUI 0203HJ
RealView Compilation Tools
デベロ ッ パガ イ ド
Copyright © 2002-2007 ARM Limited. All rights reserved.
リ リ ース情報
本書には以下の変更が加え ら れてい ます。
変更履歴
日付
発行
機密保持ス テー タ ス
変更
2002 年 8 月
A
非機密扱い
第 1.2 版
2003 年 1 月
B
非機密扱い
第 2.0 版
2003 年 9 月
C
非機密扱い
RVDS v2.0 リ リ ース (第 2.0.1 版)
2004 年 1 月
D
非機密扱い
RVDS v2.1 リ リ ース (第 2.1 版)
2004 年 12 月
E
非機密扱い
RVDS v2.2 リ リ ース (第 2.2 版)
2005 年 5 月
F
非機密扱い
RVDS v2.2 SP1 リ リ ース (第 2.2 版)
2006 年 3 月
G
非機密扱い
RVDS 3.0 リ リ ース (第 3.0 版)
2007 年 3 月
H
非機密扱い
RVDS v3.1 ( リ リ ース 3.1)
著作権
®
ま たは ™ のマー ク が付いた言葉お よ び ロ ゴは、 ARM Limited が所有す る 登録商標ま たは商標で
す。 本書に記載 さ れてい る 他の製品名は、 各社の所有す る 商標です。
本書に記載 さ れてい る 情報の全部ま たは一部、 な ら びに本書で紹介す る 製品は、 著作権所有者の
文書に よ る 事前の許可を得ない限 り 、 転用 ・ 複製す る こ と を禁 じ ます。
本書に記載 さ れてい る 製品は、 今後 も 継続的に開発 ・ 改良の対象 と な り ます。 本書に含ま れ る 製
品お よ びその利用方法についての情報は、 ARM が利用者の利益のために提供す る も のです。 し た
が っ て当社では、 製品の市販性ま たは利用の適切性を含め、 暗示的 ・ 明示的に関係な く 一切の責
任を負い ません。
本書は、 本製品の利用者をサポー ト す る こ と だけ を目的 と し てい ます。 本書に記載 さ れてい る 情
報の使用、 情報の誤 り ま たは省略、 あ る いは本製品の誤使用に よ っ て発生 し たいかな る 損失 ・ 損
傷について も 、 ARM Limited は一切責任を負い ません。
ARM と い う 用語が使用 さ れてい る 場合は、 "ARM ま たは必要に応 じ てその子会社 " を指 し ます。
機密保持ス テー タ ス
本書は非機密扱いであ り 、 本書を使用、 複製、 お よ び開示す る 権利は、 ARM お よ び ARM が本書
を提供 し た当事者 と の間で締結 し た契約の条項に基づいた ラ イ セ ン ス の制限に よ り 異な り ます。
製品ス テー タ ス
本書の情報は最終版であ り 、 開発済み製品に対応 し てい ます。
Web ア ド レ ス
http://www.arm.com
ii
Copyright © 2007 ARM Limited. All rights reserved.
ARM DUI 0203HJ
目次
RealView Compilation Tools
デベロ ッ パガ イ ド
序章
本書について ................................................................................................... x
フ ィ ー ド バ ッ ク ............................................................................................ xiv
第1章
は じ めに
1.1
1.2
第2章
組み込み ソ フ ト ウ ェ アの開発
2.1
2.2
2.3
2.4
2.5
2.6
ARM DUI 0203HJ
RVCT について ............................................................................................. 1-2
ARM プ ロ セ ッ サを タ ーゲ ッ ト と し た開発 .................................................... 1-3
組み込み ソ フ ト ウ ェ アの開発について ........................................................ 2-2
タ ーゲ ッ ト シス テムが存在 し ない場合の RealView Compilation Tools
のデ フ ォル ト の動作 ..................................................................................... 2-4
タ ーゲ ッ ト ハー ド ウ ェ アに合わせた C ラ イ ブ ラ リ のカ ス タ マ イ ズ ........... 2-12
タ ーゲ ッ ト ハー ド ウ ェ アに合わせた イ メ ージの メ モ リ マ ッ プの
カ ス タ マ イ ズ .............................................................................................. 2-16
リ セ ッ ト と 初期化 ....................................................................................... 2-28
メ モ リ マ ッ プに関する その他の注意事項 ................................................... 2-38
Copyright © 2007 ARM Limited. All rights reserved.
v
第3章
位置非依存 コ ー ド と デー タ の記述
3.1
3.2
3.3
第4章
ARM と Thumb のイ ン タ ーワー ク
4.1
4.2
4.3
4.4
第5章
プ ロ セ ッ サ例外について ............................................................................. 6-3
プ ロ セ ッ サ状態の判断 ................................................................................. 6-7
例外の開始 と 終了 ........................................................................................ 6-9
例外処理 ..................................................................................................... 6-15
例外ハン ド ラのイ ン ス ト ール .................................................................... 6-16
SVC ハン ド ラ ............................................................................................. 6-22
割 り 込みハン ド ラ ...................................................................................... 6-32
リ セ ッ ト ハン ド ラ ...................................................................................... 6-44
未定義命令ハン ド ラ ................................................................................... 6-45
プ リ フ ェ ッ チアボー ト ハン ド ラ ................................................................. 6-46
デー タ アボー ト ハン ド ラ ........................................................................... 6-47
シ ス テムモー ド .......................................................................................... 6-49
Handling Cortex-M3 Processor ExceptionsCortex-M3 プ ロ セ ッ サ例
外処理
7.1
7.2
7.3
7.4
7.5
7.6
7.7
7.8
7.9
vi
イ ン ラ イ ン アセ ン ブ ラ と 組み込みアセ ン ブ ラの使用 .................................. 5-2
アセ ン ブ リ コ ー ド から C グローバル変数へのア ク セス ............................... 5-4
C++ から の C ヘ ッ ダ フ ァ イルの使用 ............................................................ 5-6
C、 C++、 およびアセ ン ブ リ 言語間の呼び出 し ........................................... 5-8
プ ロ セ ッ サ例外処理
6.1
6.2
6.3
6.4
6.5
6.6
6.7
6.8
6.9
6.10
6.11
6.12
第7章
イ ン タ ーワー ク について ............................................................................. 4-2
アセ ン ブ リ 言語のイ ン タ ーワー ク ............................................................... 4-8
C と C++ のイ ン タ ーワー ク と ベニア .......................................................... 4-15
ベニア を使用 し たアセ ン ブ リ 言語のイ ン タ ーワー ク ................................ 4-20
C、 C++、 およびアセ ン ブ リ 言語の混用
5.1
5.2
5.3
5.4
第6章
位置非依存 ................................................................................................... 3-2
読み出 し 専用の位置非依存 .......................................................................... 3-4
読み出 し - 書き込みの位置非依存 ................................................................. 3-7
Cortex-M3 プ ロ セ ッ サ例外について ............................................................ 7-2
例外テーブルの書き込み ........................................................................... 7-11
例外ハン ド ラの書き込み ........................................................................... 7-13
例外テーブルの配置 ................................................................................... 7-14
シ ス テム制御空間レ ジ ス タ の設定 ............................................................. 7-15
個別の IRQ の設定 ...................................................................................... 7-17
スーパーバイザ コ ール ............................................................................... 7-18
シ ス テム タ イ マ .......................................................................................... 7-20
他の ARM プ ロ セ ッ サ用に記述 さ れた例外処理コ ー ド の移植 .................... 7-22
Copyright © 2007 ARM Limited. All rights reserved.
ARM DUI 0203HJ
第8章
デバ ッ グ通信チ ャ ネル
8.1
8.2
8.3
8.4
8.5
付録 A
セ ミ ホス テ ィ ング
A.1
A.2
A.3
A.4
ARM DUI 0203HJ
デバ ッ グ通信チ ャ ネルについて ................................................................... 8-2
タ ーゲ ッ ト のデー タ 転送 .............................................................................. 8-3
デバ ッ グ通信のポー リ ン グ .......................................................................... 8-4
割 り 込み駆動型デバ ッ グ通信 ....................................................................... 8-8
Thumb 状態か らのア ク セス .......................................................................... 8-9
セ ミ ホス テ ィ ン グについて ......................................................................... A-2
セ ミ ホス テ ィ ン グの実装 ............................................................................. A-6
セ ミ ホス テ ィ ン グオペ レーシ ョ ン ............................................................... A-8
デバ ッ グエージ ェ ン ト イ ン タ ラ ク シ ョ ン SVC .......................................... A-27
Copyright © 2007 ARM Limited. All rights reserved.
vii
viii
Copyright © 2007 ARM Limited. All rights reserved.
ARM DUI 0203HJ
序章
本章では、 『RealView Compilation Tools デベ ロ ッ パガ イ ド 』 (本書) について概
説 し ます。 本章は以下のセ ク シ ョ ン か ら 構成 さ れてい ます。
•
•
ARM DUI 0203HJ
本書について (ページ x)
フ ィ ー ド バ ッ ク (ページ xiv)
Copyright © 2007 ARM Limited. All rights reserved.
ix
序章
本書について
本書には、 ARM® フ ァ ミ リ の Reduced Instruction Set Computing (RISC) プ ロ
セ ッ サ用の コ ー ド を開発す る 際に発生す る 特定の問題に関す る 情報が記載 さ
れてい ます。 本書の各章の説明、 お よ び使用す る サン プルは、 RealView®
Compilation Tools (RVCT) の最新 リ リ ース を使用 し て コ ー ド を開発 し てい る
こ と を前提 と し てい ます。
対象読者
本書は、 ARM アーキ テ ク チ ャ ベース の コ ー ド を記述 し てい る すべての開発者
を対象 と し てい ます。 本書の内容は、 『RealView Compilation Tools エ ッ セ ン
シ ャ ルガ イ ド 』 で説明 さ れてい る ARM 開発ツールを熟知 し た経験豊富な ソ
フ ト ウ ェ ア開発者を対象に書かれてい ます。
本書の構成
本書は以下の章か ら 構成 さ れてい ます。
第 1 章 は じ めに
RVCT の概要について説明 し ます。
第 2 章 組み込み ソ フ ト ウ ェ アの開発
RVCT を使用 し て組み込みアプ リ ケーシ ョ ン を開発す る 方法につ
いて説明 し ます。 タ ーゲ ッ ト シ ス テ ム が存在 し ない場合の RVCT
のデフ ォ ル ト の動作について、 お よ び C ラ イ ブ ラ リ と イ メ ージ
の メ モ リ マ ッ プ を タ ーゲ ッ ト シ ス テ ムに合わせて カ ス タ マ イ ズ
す る 方法について も 説明 し ます。
第 3 章 位置非依存 コ ー ド と デー タ の記述
ARM アーキ テ ク チ ャ 向けプ ロ シージ ャ コール標準 (AAPCS) を
使用す る 位置非依存 コ ー ド と デー タ を記述す る 方法について説
明 し ます。
第 4 章 ARM と Thumb の イ ン タ ーワー ク
Thumb 命令セ ッ ト を実装す る プ ロ セ ッ サ用の コ ー ド を記述す る
際に ARM 状態 と Thumb 状態を切 り 替え る 方法について説明 し
ます。
x
Copyright © 2007 ARM Limited. All rights reserved.
ARM DUI 0203HJ
序章
第 5 章 C、 C++、 お よ びアセ ンブ リ 言語の混用
C、 C++、 お よ び ARM アセ ン ブ リ 言語の混合 コ ー ド を記述す る
方法について説明 し ます。 ま た、 C お よ び C++ 言語か ら ARM の
イ ン ラ イ ン アセ ン ブ ラ と 組み込みアセ ン ブ ラ を使用す る 方法に
ついて も 説明 し ます。
第 6 章 プ ロ セ ッ サ例外処理
Cortex-M1 プ ロ セ ッ サ ま たは Cortex-M3 プ ロ セ ッ サ以外の ARM
プ ロ セ ッ サでサポー ト さ れてい る 各種例外の処理方法について
説明 し ます。
第 7 章 Handling Cortex-M3 Processor ExceptionsCortex-M3 プ ロ セ ッ サ例外処理
Cortex-M3 プ ロ セ ッ サでサポー ト さ れてい る 各種例外の処理方法
について説明 し ます。
第 8 章 デバ ッ グ通信チ ャ ネル
デバ ッ グ通信チ ャ ネル (DCC) の使用方法について説明 し ます。
付録 A セ ミ ホ ス テ ィ ン グ
セ ミ ホ ス テ ィ ン グ メ カ ニズ ムについて説明 し ます。 セ ミ ホ ス
テ ィ ン グに よ り 、 ARM タ ーゲ ッ ト 上で実行 さ れ る コ ー ド は
ARM デバ ッ ガ を実行 し てい る ホ ス ト コ ン ピ ュ ー タ 上の I/O 機能
を使用で き ます。
本書では、 ARM ソ フ ト ウ ェ アがデフ ォ ル ト の場所に イ ン ス ト ール さ れてい る
こ と を前提 と し てい ます。 例えば、 Windows 環境でのデフ ォ ル ト の場所は
volume:\Program Files\ARM にな り ます。 パ ス名を参照す る 際、 install_directory
の部分を こ の場所に読み替え て下 さ い。 例えば、 本書では、
install_directory\Documentation\... の よ う なパ ス名が使用 さ れます。 ARM ソ フ
ト ウ ェ ア を別の場所に イ ン ス ト ール し た場合は、 フ ァ イ ルパ ス の見方を変え
る 必要があ り ます。
表記規則
本書では以下の表記規則を使用 し てい ます。
ARM DUI 0203HJ
monospace
コ マ ン ド 、 フ ァ イ ル名、 プ ロ グ ラ ム名、 ソ ース コ ー ド な ど、
キーボー ド か ら 入力可能な テ キ ス ト を示 し てい ます。
monospace
コ マ ン ド ま たはオプシ ョ ン に使用可能な略語を示 し ます。 コ マ ン
ド 名ま たはオプシ ョ ン名をすべて入力す る 代わ り に、 下線部分
の文字だけ を入力す る こ と がで き ます。
Copyright © 2007 ARM Limited. All rights reserved.
xi
序章
monospace italic
コ マ ン ド ま たは関数の引数で、 特定の値に置 き 換え る こ と が可
能な も のを示 し てい ます。
monospace bold
サン プル コ ー ド 以外に使用 さ れ る 言語キー ワー ド を示 し てい ま
す。
italic
重要事項、 重要用語、 相互参照、 引用箇所を斜体で記載 し てい
ます。
bold
メ ニ ュ ー名な ど のユーザ イ ン タ フ ェース要素を太字で記載 し て
い ます。 ま た、 適宜記述 リ ス ト 内の重要箇所 と ARM プ ロ セ ッ サ
の信号名に も 太字を用いてい ます。
参考資料
こ こ では、 ARM プ ロ セ ッ サ フ ァ ミ リ の コ ー ド 開発に関す る 補足情報を記載 し
た ARM Limited お よ び各社の出版物を紹介 し ます。
ARM は自社出版物の定期的な更新 ・ 修正を行っ てい ます。 最新の正誤表、 追
補表、 ARM に関す る FAQ については、 http://www.arm.com を ご覧下 さ い。
ARM の出版物
本書では、 ARM フ ァ ミ リ のプ ロ セ ッ サ向けアプ リ ケーシ ョ ン開発に関す る 一
般的な情報を提供 し てい ます。 他の コ ン ポーネ ン ト の詳細については、 以下
の RVCT 付属マニ ュ アルを参照 し て下 さ い。
•
•
•
•
•
•
•
『RVCT エ ッ セ ン シ ャ ルガ イ ド 』 (ARM DUI 0202J)
『RVCT コ ンパ イ ラ ユーザガ イ ド 』 (ARM DUI 0205J)
『RVCT コ ンパ イ ラ リ フ ァ レ ン ス ガ イ ド 』 (ARM DUI 0348J)
『RVCT ラ イ ブ ラ リ / 浮動小数点サポー ト ガ イ ド 』 (ARM DUI 0349J)
『RVCT リ ン カ / ユーテ ィ リ テ ィ ガ イ ド 』 (ARM DUI 0206J)
『RVCT アセ ンブ ラ ガ イ ド 』 (ARM DUI 0204J)
『RealView Development Suite 用語集』 (ARM DUI 0324J)
Base Standard、 ソ フ ト ウ ェ ア イ ン タ フ ェース、 お よ び ARM でサポー ト さ れて
い る 標準の詳細については、 install_directory\Documentation\Specifications\...
を参照 し て下 さ い。
xii
Copyright © 2007 ARM Limited. All rights reserved.
ARM DUI 0203HJ
序章
特定の ARM 製品に関す る 情報については、 以下のマニ ュ アルを参照 し て下
さ い。
•
『ARM6-M アーキ テ ク チ ャ リ フ ァ レ ン ス マニ ュ アル』 (ARM DDI 0419)
•
『ARM7-M アーキ テ ク チ ャ リ フ ァ レ ン ス マニ ュ アル』 (ARM DDI 0403)
•
『ARM アーキ テ ク チ ャ リ フ ァ レ ン ス マニ ュ アル』 (ARMv7-A お よ び
ARMv7-R エデ ィ シ ョ ン) (ARM DDI 0406)
•
『ARM Architecture Reference Manual Thumb®-2 Supplement』 (ARM DDI 0308)
•
『ARM Architecture Reference Manual Security Extensions Supplement』 (ARM
DDI 0309)
•
『ARM Architecture Reference Manual Thumb-2 Execution Environment
Supplement』 (ARM DDI 0376)
•
『ARM Architecture Reference Manual Advanced SIMD Extension and VFPv3
Supplement』 (ARM DDI 0268)
•
『ARM Reference Peripheral Specification』 (ARM DDI 0062)
•
お使いのハー ド ウ ェ アデバ イ ス の ARM デー タ シー ト ま たはテ ク ニ カル
リ フ ァ レ ン ス マニ ュ アル
他の出版物
ARM アーキ テ ク チ ャ の一般的な情報については、 以下の出版物を参照 し て下
さ い。
Andrew N. Sloss, Dominic Symes and Chris Wright, ARM System Developer's Guide:
Designing and Optimizing System Software (2004). Morgan Kaufmann, ISBN
1-558-60874-5.
ARM プ ロ セ ッ サ コ ア を使用す る SoC (System-on-Chip) 設計者お よ び ARM
を使用 し て作業す る エ ン ジニ ア を対象 と し た手引 き 書については、 以下の出
版物を参照 し て下 さ い。
Steve Furber, ARM system-on-chip architecture (2nd edition, 2000). Addison Wesley,
ISBN 0-201-67519-6.
ARM DUI 0203HJ
Copyright © 2007 ARM Limited. All rights reserved.
xiii
序章
フ ィ ードバッ ク
ARM Limited では、 RealView Compilation Tools お よ び本書に関す る フ ィ ー ド
バ ッ ク をお待ち し てお り ます。
RealView Compilation Tools に関する フ ィ ー ド バ ッ ク
RVCT に関 し て問題があ る 場合は、 購入元にお問い合わせ下 さ い。 こ の と き 、
迅速かつ適切な対応を さ せて頂 く ために、 以下の情報を ご用意下 さ い。
•
お名前 と 会社名
•
製品のシ リ アル番号
•
製品の リ リ ース情報
•
プ ラ ッ ト フ ォ ームの詳細 (ハー ド ウ ェ アプ ラ ッ ト フ ォ ーム、 オペレー
テ ィ ン グ シ ス テ ムの種類 と バージ ョ ン な ど)
•
問題を再現す る サ イ ズの小 さ な独立 し たサン プル コ ー ド
•
操作の目的 と 実際の動作に関す る 詳 し い説明
•
使用 し た コ マ ン ド ( コ マ ン ド ラ イ ン オプシ ョ ン を含む)
•
問題を例示す る サ ンプル出力
•
ツールのバージ ョ ン情報 (バージ ョ ン番号、 日付を含む)
本書に関する フ ィ ー ド バ ッ ク
本書に関す る ご意見につ き ま し ては、 以下の内容を記載 し た電子 メ ールを
[email protected] ま でお送 り 下 さ い。
•
•
•
•
マニ ュ アル名
文書番号
問題のあ る ページ番号
問題点の簡潔な説明
補足すべ き 点や改善すべ き 点についてのご提案 も お待ち し てお り ます。
xiv
Copyright © 2007 ARM Limited. All rights reserved.
ARM DUI 0203HJ
第 1章
は じ めに
本章では、 本書について概説 し 、 RealView® Compilation Tools (RVCT) を使用
し た コ ー ド の開発方法に関す る 説明を始め ます。 本章は以下のセ ク シ ョ ン か
ら 構成 さ れてい ます。
•
RVCT について (ページ 1-2)
•
ARM DUI 0203HJ
ARM プ ロ セ ッ サを タ ーゲ ッ ト と し た開発 (ページ 1-3)
Copyright © 2007 ARM Limited. All rights reserved.
1-1
は じ めに
1.1
RVCT について
RVCT は、 サポー ト ド キ ュ メ ン ト と サン プルを備え た アプ リ ケーシ ョ ン ス
イ ー ト で構成 さ れてお り 、 ARM® フ ァ ミ リ の RISC プ ロ セ ッ サ用アプ リ ケー
シ ョ ン のプ ロ グ ラ ミ ン グ を実現 し ます。 RVCT を使用す る と 、 C、 C++、 お よ
び ARM アセ ンブ リ 言語でプ ロ グ ラ ム を ビル ド で き ます。
本書では、 ARM ベース のシ ス テ ム用の コ ー ド を開発す る 際の具体的な問題に
ついて説明 し ます。 本書の各章の説明、 お よ び本書で使用す る サン プルは、
RVCT の最新 リ リ ース を使用 し て コ ー ド を開発 し てい る こ と を前提 と し てい
ます。
以前の リ リ ース の RVCT か ら ア ッ プグ レー ド す る 場合は、 『RealView
Compilation Tools エ ッ セ ン シ ャ ルガ イ ド 』 を読んで、 こ の リ リ ース の新機能 と
拡張機能について確認 し て下 さ い。
RVCT を初めて使用す る 場合は、 『RealView Compilation Tools エ ッ セ ン シ ャ ル
ガ イ ド 』 を読んで、 ARM ツールの概要 と 、 ARM ツールを開発プ ロ ジ ェ ク ト
で使用す る 方法の概要を確認 し て下 さ い。
RVCT の以前の リ リ ース の詳細については、 『RealView Compilation Tools エ ッ
セ ン シ ャ ルガ イ ド 』 の付録 A を参照 し て下 さ い。
ARM アセ ンブ ラ 、 コ ンパ イ ラ 、 お よ びサポー ト し てい る ソ フ ト ウ ェ アに関す
る 情報が記載 さ れた、 RVCT 付属マニ ュ アルの他のマニ ュ アルの一覧につい
ては、 ARM の出版物 (ページ xii) を参照 し て下 さ い。
1.1.1
サン プルの使用方法
本書では、 RealView Development Suite に収録 さ れてい る サン プルを参照 し ま
す。 こ れ ら は、 メ イ ンサ ンプルデ ィ レ ク ト リ の
install_directory\RVDS\Examples にあ り ます。 付属のサン プルの概要について
は、 『RealView Compilation Tools エ ッ セ ン シ ャ ルガ イ ド 』 を参照 し て下 さ い。
1-2
Copyright © 2007 ARM Limited. All rights reserved.
ARM DUI 0203HJ
は じ めに
1.2
ARM プ ロ セ ッ サを タ ーゲ ッ ト と し た開発
本書では、 一般的な ARM プ ロ グ ラ ミ ン グ作業に関す る 情報 と サン プル コ ー
ド 、 お よ び ARM アーキ テ ク チ ャ で作業 し てい る 開発者向けの情報を提供 し
ます。 こ のセ ク シ ョ ンは以下のサブセ ク シ ョ ン か ら 構成 さ れてい ます。
1.2.1
組み込み ソ フ ト ウ ェ アの開発
ARM アーキ テ ク チ ャ ベース のシ ス テ ム用に記述 さ れ る 多 く のアプ リ ケーシ ョ
ンは、 ROM に保持 さ れ、 リ セ ッ ト 時に実行 さ れ る 組み込みアプ リ ケーシ ョ ン
です。 組み込みオペレーテ ィ ン グ シ ス テ ム を記述す る 際、 ま たはオペレー
テ ィ ン グ シ ス テ ムに依存せずに リ セ ッ ト か ら 実行 さ れ る 組み込みアプ リ ケー
シ ョ ン を記述す る 際には、 以下の よ う な場合に注意す る 必要があ り ます。
•
ROM がア ド レ ス 0x0000 に配置 さ れ る よ う に初期化 し た後、 RAM を ア ド
レ ス 0x0000 に リ マ ッ プす る な ど、 ア ド レ ス の リ マ ッ プ を行 う 場合
•
環境 と アプ リ ケーシ ョ ン を初期化す る 場合
•
組み込み実行可能 イ メ ージ を リ ン ク し 、 特定の メ モ リ 位置に コ ー ド と
デー タ を配置す る 場合
通常、 ARM コ アでは、 リ セ ッ ト 時にア ド レ ス 0x0000 か ら 命令の実行を開始 し
ます。 つま り 、 組み込みシ ス テ ムの場合、 シ ス テ ムの リ セ ッ ト 時に ROM がア
ド レ ス 0x0000 に存在 し てい る 必要があ り ます。 し か し 、 通常 ROM は RAM に
比べて低速で、 多 く の場合 メ モ リ 幅は 8 ビ ッ ト ま たは 16 ビ ッ ト し かあ り ませ
ん。 こ れは、 例外処理の速度に影響 し ます。 ア ド レ ス 0x0000 に ROM が存在す
る と 、 例外ベ ク タ を変更で き ません。 通常は、 ROM を RAM に リ マ ッ プ し 、
起動後に例外ベ ク タ を ROM か ら RAM に コ ピーす る と い う 方法を使用 し ま
す。 詳細については、 ROM/RAM の リ マ ッ プ (ページ 2-30) を参照 し て下 さ
い。
リ セ ッ ト 後、 組み込みアプ リ ケーシ ョ ン ま たはオペレーテ ィ ン グ シ ス テ ム で
は、 以下の よ う にシ ス テ ム を初期化す る 必要があ り ます。
•
例外ベ ク タ 、 ス タ ッ ク 、 I/O ペ リ フ ェ ラ ルな ど の実行環境を初期化す る 。
•
非ゼ ロ の書 き 込み可能デー タ の初期値を書 き 込み可能デー タ 領域に コ
ピー し 、 ZI デー タ 領域を ゼ ロ 初期化す る な ど の方法でアプ リ ケーシ ョ ン
を初期化す る 。
詳細については、 初期化シーケ ン ス (ページ 2-28) を参照 し て下 さ い。
ARM DUI 0203HJ
Copyright © 2007 ARM Limited. All rights reserved.
1-3
は じ めに
組み込みシ ス テ ム では、 複雑な メ モ リ の コ ン フ ィ グ レーシ ョ ン を実装す る こ
と が よ く あ り ます。 例えば、 組み込みシ ス テ ム では、 割 り 込みハン ド ラ やス
タ ッ ク な ど、 パフ ォ ーマ ン ス を重視 し た コ ー ド には高速な 32 ビ ッ ト RAM を
使用 し 、 アプ リ ケーシ ョ ン の RW デー タ には低速な 16 ビ ッ ト RAM を使用 し 、
通常のアプ リ ケーシ ョ ン コ ー ド には ROM を使用す る こ と がで き ます。 リ ン カ
の分散 ロ ー ド メ カ ニズ ム を使用す る と 、 複雑な シ ス テ ム に適 し た実行可能 イ
メ ージ を作成で き ます。 例えば、 分散 ロ ー ド 記述フ ァ イ ルでは、 個々の コ ー
ド 領域 と デー タ 領域の ロ ー ド ア ド レ ス と 実行ア ド レ ス を指定で き ます。 一連
のサン プル と 、 セ ミ ホ ス テ ィ ン グ な ど、 組み込みアプ リ ケーシ ョ ンに影響す
る 他の問題については、 「第 2 章 組み込み ソ フ ト ウ ェ アの開発」 を参照 し て
下 さ い。
1.2.2
ARM コ ー ド と Thumb コ ー ド のイ ン タ ーワー ク
Thumb 16 ビ ッ ト 命令セ ッ ト を サポー ト す る ARM プ ロ セ ッ サ用の コ ー ド を記
述 し てい る 場合は、 必要に応 じ て ARM コ ー ド と Thumb コ ー ド を混用で き ま
す。 C ま たは C++ コ ー ド を記述 し てい る 場合は、--apcs /interwork オプシ ョ ン
を使用 し て コ ンパ イ ルを実行す る 必要があ り ます。 リ ン カでは、 ARM 関数が
Thumb 状態か ら 呼び出 さ れ る か、 Thumb 関数が ARM 状態か ら 呼び出 さ れ る
と 、 それを検出 し 、 呼び出 し と 復帰のシーケ ン ス を変更す る か、 ま たは イ ン
タ ー ワ ー ク ベニ ア を挿入 し て必要に応 じ てプ ロ セ ッ サ状態を変更 し ます。
注
Thumb 関数への絶対ア ド レ ス を使用す る 場合は、 Thumb 状態の関数へのポ イ
ン タ (ページ 4-18) を参照 し て下 さ い。
アセ ン ブ リ 言語 コ ー ド を記述 し てい る 場合、 Procedure Call Standard for the
ARM Architecture (AAPCS) の イ ン タ ー ワー ク バ リ ア ン ト に準拠す る 必要があ
り ます。 タ ーゲ ッ ト アーキ テ ク チ ャ のバージ ョ ンに応 じ て、 プ ロ セ ッ サ状態
を変更す る 方法は複数あ り ます。 詳細については、 「第 4 章 ARM と Thumb の
イ ン タ ーワー ク 」 を参照 し て下 さ い。
1.2.3
C、 C++、 およびアセ ン ブ リ 言語の混用
別々に コ ンパ イ ルお よ びアセ ン ブル さ れた C、 C++、 お よ び ARM アセ ン ブ リ
言語モジ ュ ールを プ ロ グ ラ ム で混用す る こ と がで き ます。C コ ー ド ま たは C++
コ ー ド 内に、 アセ ンブ リ 言語で記述 さ れた小 さ なルーチン を含め る こ と がで
き ます。 こ れ ら のルーチンは、 ARM コ ンパ イ ラ の イ ン ラ イ ン アセ ン ブ ラ ま た
は組み込みアセ ン ブ ラ を使用 し て コ ンパ イ ル さ れ ます。 ただ し 、 イ ン ラ イ ン
アセ ン ブ ラ ま たは組み込みアセ ンブ ラ を使用 し てい る 場合は、 記述で き る ア
1-4
Copyright © 2007 ARM Limited. All rights reserved.
ARM DUI 0203HJ
は じ めに
セ ンブ リ 言語 コ ー ド に対 し て多 く の制限があ り ます。 こ れ ら の制限について
は、 『コ ンパ イ ラ ユーザガ イ ド 』 の 「第 6 章 イ ン ラ イ ン アセ ンブ ラ と 組み込
みアセ ンブ ラ の使用」 に記載 さ れてい ます。
ま た、 「第 5 章 C、 C++、 お よ びアセ ンブ リ 言語の混用」 では、 C、 C++、 お
よ びアセ ンブ リ 言語の各モジ ュ ール間でデー タ を呼び出す方法に関す る 一般
的なガ イ ド ラ イ ン と サ ンプルを提供 し てい ます。
1.2.4
プ ロ セ ッ サ例外処理
ARM プ ロ セ ッ サでは、 以下の例外 タ イ プ を認識 し ます。
リ セッ ト
プ ロ セ ッ サ リ セ ッ ト ピ ンがアサー ト さ れ る と 発生 し ます。 こ の例
外は、 起動が通知 さ れた場合ま たはプ ロ セ ッ サ を起動 さ れた状
態にす る ために リ セ ッ ト が行われた場合だけに発生 し ます。 ソ フ
ト リ セ ッ ト は、 リ セ ッ ト ベ ク タ 0x0000 に分岐 さ せ る こ と に よ っ
て実行で き ます。
未定義命令
実行中の命令が、 プ ロ セ ッ サや接続 さ れてい る ど の コ プ ロ セ ッ
サに も 認識 さ れない場合に発生 し ます。
スーパーバ イ ザ コ ール (SVC、 以前は SWI)
ユーザ定義の割 り 込み命令です。 スーパーバ イ ザ コ ールに よ り 、
例えば、 ユーザモー ド で実行中のプ ロ グ ラ ムが、 スーパーバ イ
ザモー ド で実行 さ れ る RTOS 関数な ど の特権操作を要求で き ま
す。
プ リ フ ェ ッ チアボー ト
プ ロ セ ッ サが、 不正な ア ド レ ス か ら プ リ フ ェ ッ チ さ れた命令を
実行 し よ う と し た と き に発生 し ます。 不正な ア ド レ ス と は、 メ モ
リ が存在 し ないア ド レ ス か、 ま たは現在のモー ド でプ ロ セ ッ サ
か ら ア ク セ ス で き ない と メ モ リ 管理サブシ ス テ ムが判断 し た ア
ド レ ス を指 し ます。
デー タ アボー ト デー タ 転送命令に よ っ て不正な ア ド レ ス での ロ ー ド ま たは ス
ト アが試行 さ れた場合に発生 し ます。
割 り 込み (IRQ)
プ ロ セ ッ サ外部割 り 込み要求ピ ン が LOW でアサー ト さ れ、 CPSR
内の I ビ ッ ト が ク リ ア さ れてい る と き に発生 し ます。
ARM DUI 0203HJ
Copyright © 2007 ARM Limited. All rights reserved.
1-5
は じ めに
高速割 り 込み (FIQ)
プ ロ セ ッ サ外部高速割 り 込み要求ピ ンが LOW でアサー ト さ れ、
CPSR 内の F ビ ッ ト が ク リ ア さ れてい る と き に発生 し ます。 通常、
こ の例外は、 割 り 込みレ イ テ ン シ を最小限に保つ必要があ る 場
合に使用 さ れ ます。
高速割 り 込みは Cortex-M1 ま たは Cortex-M3 プ ロ セ ッ サでは利用
で き ません。 ま た、 すべての割 り 込みにはプ ロ グ ラ ム可能な優
先度レベルがあ り ます。 詳細については、 「第 7 章 Handling
Cortex-M3 Processor ExceptionsCortex-M3 プ ロ セ ッ サ例外処理」 を
参照 し て下 さ い。
通常、 例外処理を オペレーテ ィ ン グ シ ス テ ムに頼 ら ない組み込みアプ リ ケー
シ ョ ン な ど のアプ リ ケーシ ョ ン を記述す る 場合には、 例外 タ イ プご と のハン
ド ラ を記述す る 必要があ り ます。
SVC や IRQ 割 り 込みな ど、 1 つの例外の種類に複数の発生源があ る よ う な場
合には、 各発生源の例外ハン ド ラ をチ ェ イ ンす る こ と がで き ます。
Thumb 命令を サポー ト す る 大部分のプ ロ セ ッ サは、 例外を受け取 る と ARM
状態に切 り 替わ り ます。 ARM コ ー ド で例外ハン ド ラ を記述す る か、 ま たはベ
ニ ア を使用 し て Thumb 状態に切 り 替え る こ と がで き ます。 詳細については、
復帰ア ド レ ス と 復帰命令 (ページ 6-12) を参照 し て下 さ い。
Cortex-M1 お よ び Cortex-M3 プ ロ セ ッ サでは ARM 命令はサポー ト さ れてお ら
ず、 例外処理時には Thumb 状態の ま ま にな り ます。
Thumb-2 命令をサポー ト す る 他のプ ロ セ ッ サは Thumb 状態への切 り 替えが可
能で、 Thumb-2 コ ー ド 全体を構成す る ハン ド ラ を実行で き ます。 例外を入力
す る ための ARM ま たは Thumb 状態の選択は、 CP15 レ ジ ス タ 1 の TE ビ ッ ト
を使用 し て行い ます。 こ れは、 TEINIT 入力を コ ア HIGH と 結合す る こ と に
よ っ て、 リ セ ッ ト 時に設定で き ます。 詳細については、 プ ロ セ ッ サのテ ク ニ
カル リ フ ァ レ ン ス マニ ュ アルを参照 し て下 さ い。
1-6
Copyright © 2007 ARM Limited. All rights reserved.
ARM DUI 0203HJ
は じ めに
1.2.5
AAPCS の使用
Procedure Call Standard for the ARM Architecture (AAPCS) では、 個々に コ ンパ
イ ルお よ びアセ ンブル さ れたモジ ュ ールを連携 さ せ る ために従 う 必要があ る
レ ジ ス タ の使用方法 と ス タ ッ ク の規則を定義 し てい ます。 base standard に基づ
いたバ リ ア ン ト は多数あ り ます。 ARM コ ンパ イ ラ では、 常に特定の AAPCS
バ リ ア ン ト に準拠 し た コ ー ド を生成 し ます。 リ ン カでは、 必要に応 じ て、 リ
ン ク す る 適切な C ま たは C++ ラ イ ブ ラ リ を選択 し ます。
ARM プ ロ セ ッ サ用の コ ー ド を開発す る 際は、 適切な AAPCS バ リ ア ン ト を選
択す る 必要があ り ます。 以下に例を示 し ます。
•
ARM 状態ま たは Thumb 状態 と 相互作用す る コ ー ド を記述 し てい る 場合
は、 コ ンパ イ ラ と アセ ンブ ラ で --apcs /interwork オプシ ョ ン を選択す る
必要があ り ます。
•
C ま たは C++ で コ ー ド を記述 し てい る 場合は、 各 コ ンパ イ ル済みモ
ジ ュ ールに対 し て互換性のあ る AAPCS オプシ ョ ン を選択す る 必要があ
り ます。
•
アセ ン ブ リ 言語で独自のルーチン を記述 し てい る 場合は、 適切な
AAPCS バ リ ア ン ト に準拠す る 必要があ り ます。
詳細については、 install_directory\Documentation\Specifications\... にあ る
Procedure Call Standard for the ARM Architecture (aapcs.pdf) を参照 し て下 さ い。
注
C と アセ ンブ リ 言語を混用 し てい る 場合は、 AAPCS の内容を よ く 理解す る よ
う に し て下 さ い。
1.2.6
従来のオブ ジ ェ ク ト お よび ラ イ ブ ラ リ と の互換性
以前の リ リ ース の RVCT か ら ア ッ プグ レー ド す る 場合は、 『RealView
Compilation Tools エ ッ セ ン シ ャ ルガ イ ド 』 の 「相違点」 の章を読んで、 RVCT
の新 し い リ リ ース と 以前の リ リ ース と の間の互換性について確認 し て下 さ い。
ARM DUI 0203HJ
Copyright © 2007 ARM Limited. All rights reserved.
1-7
は じ めに
1-8
Copyright © 2007 ARM Limited. All rights reserved.
ARM DUI 0203HJ
第 2章
組み込みソ フ ト ウ ェ アの開発
本章では、 タ ーゲ ッ ト シ ス テ ムが存在す る 場合 と 存在 し ない場合の、
RealView® Compilation Tools (RVCT) に よ る 組み込みアプ リ ケーシ ョ ン の開発
方法について説明 し ます。 本章は以下のセ ク シ ョ ン か ら 構成 さ れてい ます。
•
•
•
組み込み ソ フ ト ウ ェ アの開発について (ページ 2-2)
タ ーゲ ッ ト シ ス テ ムが存在 し ない場合の RealView Compilation Tools のデ
フ ォ ル ト の動作 (ページ 2-4)
タ ーゲ ッ ト ハー ド ウ ェ アに合わせた C ラ イ ブ ラ リ のカ ス タ マ イ ズ
(ページ 2-12)
•
•
•
ARM DUI 0203HJ
タ ーゲ ッ ト ハー ド ウ ェ アに合わせた イ メ ージの メ モ リ マ ッ プのカ ス タ マ
イ ズ (ページ 2-16)
リ セ ッ ト と 初期化 (ページ 2-27)
メ モ リ マ ッ プに関す る その他の注意事項 (ページ 2-37)
Copyright © 2007 ARM Limited. All rights reserved.
2-1
組み込みソ フ ト ウ ェ アの開発
2.1
組み込みソ フ ト ウ ェ アの開発について
ほ と ん ど の組み込みアプ リ ケーシ ョ ンは、 まず、 最終製品で使用可能な リ
ソ ース と は異な る リ ソ ース を使用 し たプ ロ ト タ イ プ環境で開発 さ れ ます。 そ
のため、 組み込みアプ リ ケーシ ョ ン を、 開発環境やデバ ッ グ環境の機能に依
存す る 環境か ら タ ーゲ ッ ド ハー ド ウ ェ ア上で ス タ ン ド ア ロ ン で実行 さ れ る シ
ス テ ム に移行す る プ ロ セ ス を考慮す る こ と が重要です。
RVCT を使用 し て組み込み ソ フ ト ウ ェ ア を開発す る 場合は、 以下の点を考慮
す る 必要があ り ます。
2.1.1
•
ハー ド ウ ェ アが C ラ イ ブ ラ リ で ど の よ う に使用 さ れ る かについて。
•
C ラ イ ブ ラ リ の一部の機能がデバ ッ グ環境の リ ソ ース を使用 し て実行 さ
れ る こ と 。 こ の よ う な機能を使用す る 場合は、 タ ーゲ ッ ト ハー ド ウ ェ ア
を利用す る よ う に再実装す る 必要があ り ます。
•
RVCT には、 特定の タ ーゲ ッ ト の メ モ リ マ ッ プに関す る 情報が保持 さ れ
ていない こ と 。 イ メ ージの メ モ リ マ ッ プは、 タ ーゲ ッ ト ハー ド ウ ェ アの
メ モ リ レ イ ア ウ ト に合わせて カ ス タ マ イ ズす る 必要があ り ます。
•
組み込みアプ リ ケーシ ョ ンは、 メ イ ン アプ リ ケーシ ョ ン を実行す る 前
に、 何 ら かの初期化を実行す る 必要があ る こ と 。 完全な初期化シーケ ン
ス には、 ユーザが実装す る コ ー ド に加え て、 RVCT C ラ イ ブ ラ リ の初期
化ルーチンが必要 と な り ます。
サン プル コ ー ド
本章で取 り 上げ る ト ピ ッ ク を分か り やす く 説明す る ため、 関連す る サン プル
プ ロ ジ ェ ク ト が提供 さ れてい ます。 本章で説明す る Dhrystone ビル ド の コ ー ド
は、 メ イ ンサン プルデ ィ レ ク ト リ の ...\emb_sw_dev にあ り ます。 各ビル ド は
別々のデ ィ レ ク ト リ にあ り 、 本章で順に説明 し てい る 技法のサン プル と し て
使用で き ます。 各ビル ド に固有の情報については、 以下のセ ク シ ョ ン を参照
し て下 さ い。
ビル ド 1 のサンプル コー ド (ページ 2-11)
•
•
•
•
•
ビル ド
ビル ド
ビル ド
ビル ド
2 のサンプル コー ド (ページ 2-14)
3 のサンプル コー ド (ページ 2-23)
4 のサンプル コー ド (ページ 2-36)
5 のサンプル コー ド (ページ 2-38)
Dhrystone ベンチマー ク プ ロ グ ラ ムは、 こ れ ら のサン プルプ ロ ジ ェ ク ト の基本
と な っ てい ます。 Dhrystone プ ロ グ ラ ム には、 本章で説明す る 概念の多 く が反
映 さ れてい る ため、 こ のプ ロ グ ラ ム が選択 さ れてい ます。
2-2
Copyright © 2007 ARM Limited. All rights reserved.
ARM DUI 0203HJ
組み込みソ フ ト ウ ェ アの開発
こ れ ら のサン プルプ ロ ジ ェ ク ト は、 ARM® Integrator™ 開発プ ラ ッ ト フ ォーム上
で実行で き る よ う にカ ス タ マ イ ズ さ れてい ます。 ただ し 、 サン プルで示 さ れ
る 基本原理は、 すべての タ ーゲ ッ ト ハー ド ウ ェ アに当ては ま り ます。
注
本章で注目す る のは、 Dhrystone プ ロ グ ラ ム自体ではな く 、 完全な ス タ ン ド ア
ロ ン シ ス テ ム で こ のプ ロ グ ラ ム を実行で き る よ う にす る ために必要な手順で
す。 ベンチマー ク ツール と し ての Dhrystone の使用方法の詳細については、
『Application Note 93 - Benchmarking with ARMulator®』 を参照 し て下 さ い。 ARM
アプ リ ケーシ ョ ン ノ ー ト は、 ARM Web サ イ ト http://www.arm.com の
「Documentation」 ページにあ り ます。
Integrator 上での Dhrystone ビル ド の実行
本章で説明す る Dhrystone のビル ド を Integrator 上で実行す る には、 以下の操
作を行 う 必要があ り ます。
•
ROM/RAM の リ マ ッ プ を実行 し ます。 リ マ ッ プ を実行す る には、 ス イ ッ
チ 1 お よ び 4 を オ ン に設定 し てブー ト モニ タ を起動 し 、 ボー ド を リ セ ッ
ト し ます。
•
top_of_memory を 0x40000 に設定す る か、 DIMM メ モ リ モジ ュ ールを装着
し ます。 こ の操作が行われない と 、 ス タ ッ ク (デフ ォ ル ト の設定
0x80000) を有効な メ モ リ と し て使用で き ない場合があ り ます。
ARM DUI 0203HJ
Copyright © 2007 ARM Limited. All rights reserved.
2-3
組み込みソ フ ト ウ ェ アの開発
2.2
タ ーゲ ッ ト シ ス テムが存在 し ない場合の RealView Compilation Tools のデ
フ ォル ト の動作
組み込みアプ リ ケーシ ョ ンの ソ フ ト ウ ェ ア開発に着手す る 際に、 ユーザが
タ ーゲ ッ ト ハー ド ウ ェ アの技術的な仕様全体を把握 し ていない場合があ り ま
す。 例えば、 タ ーゲ ッ ト のペ リ フ ェ ラ ルデバ イ ス、 メ モ リ マ ッ プ、 さ ら にプ
ロ セ ッ サ自体について も 、 詳細を把握 し ていない場合があ り ます。
こ の よ う な詳細を把握 し ていな く て も ソ フ ト ウ ェ ア開発を進め ら れ る よ う に、
RealView Compilation Tools には、 ユーザがアプ リ ケーシ ョ ン コ ー ド の ビル ド
と デバ ッ グ をす ぐ に開始で き る よ う にす る デフ ォ ル ト の動作が用意 さ れてい
ます。 デフ ォ ル ト のビル ド か ら 完全な ス タ ン ド ア ロ ンのアプ リ ケーシ ョ ンへ
の移行に必要な手順を理解す る ために も 、 こ のデフ ォ ル ト の動作を知っ てお
く こ と が重要です。
2-4
Copyright © 2007 ARM Limited. All rights reserved.
ARM DUI 0203HJ
組み込みソ フ ト ウ ェ アの開発
2.2.1
セ ミ ホス テ ィ ン グ
ARM C ラ イ ブ ラ リ では、 ホ ス ト のデバ ッ グ環境に よ っ て、 い く つかの ISO C
言語の機能がサポー ト さ れ ます。 こ の機能を提供す る メ カ ニズ ムは、 セ ミ ホ
ス テ ィ ン グ と 呼ばれます。
ARMv7 シ ス テ ム では、 セ ミ ホ ス テ ィ ン グは BKPT 命令を使用 し て実装 さ れ ま
す。 以前の ARM シ ス テ ム では、 SVC 命令を使用 し て、 定義 さ れた一連の スー
パーバ イ ザ コ ール (SVC) 操作に よ っ てセ ミ ホ ス テ ィ ン グが実装 さ れます。
セ ミ ホ ス テ ィ ン グが実行 さ れ る と 、 デバ ッ グエージ ェ ン ト に よ っ てセ ミ ホ ス
テ ィ ン グが識別 さ れ、 プ ロ グ ラ ム の実行が一時的に中断 さ れます。 その後、
セ ミ ホ ス テ ィ ン グオペレーシ ョ ン がデバ ッ グエージ ェ ン ト に よ っ て実行 さ れ
てか ら 、 コ ー ド の実行が再開 さ れ ます。 し たが っ て、 ホ ス ト 自体で実行 さ れ
る タ ス ク は、 プ ロ グ ラ ムか ら 見え ません。
図 2-1 は、 デバ ッ ガの コ ン ソ ールに ス ト リ ン グ を出力す る 、 セ ミ ホ ス テ ィ ン
グオペレーシ ョ ンの例を示 し てい ます。
Application Code
...
; Set up parameters to SVC
...
; SVC to write to
; debugger console
MOV r0, #5
SVC 0x123456
; Continue program
; execution
Code execution is halted
while the debug target
services the semihosting
operation
Code execution resumes when
the string has finished printing
図 2-1 セ ミ ホス テ ィ ングオペ レーシ ョ ンの例
注
詳細については、 付録 A セ ミ ホ ス テ ィ ン グ を参照 し て下 さ い。
ARM DUI 0203HJ
Copyright © 2007 ARM Limited. All rights reserved.
2-5
組み込みソ フ ト ウ ェ アの開発
2.2.2
C ラ イ ブ ラ リ の構造
概念上、 C ラ イ ブ ラ リ は、 ISO C 言語仕様に含まれ る 関数 と ISO C 言語仕様を
サポー ト す る 関数に分類す る こ と がで き ます。 図 2-2 にその概念を示 し ます。
Functions called by
your application,
for example, fputc()
ISO C
C Library
input/
output
Debug
Agent
error
handling
stack and
heap
setup
other
Semihosting Support
Device driver level.
Use semihosting,
for example, __sys_write()
Implemented by
the debugging
environment
図 2-2 C ラ イ ブ ラ リ の構造
ISO C 言語の機能のサポー ト には、 ホ ス ト デバ ッ グ環境に よ っ てデバ イ ス ド
ラ イ バ レベルで提供 さ れ る も の も あ り ます。
例えば、 RVCT C ラ イ ブ ラ リ では、 デバ ッ ガの コ ン ソ ール ウ ィ ン ド ウ への書
き 込みに よ っ て、 ISO C 言語の printf() フ ァ ミ リ の関数を実装 し ます。 こ の機
能は、 __sys_write() を呼び出す こ と で提供 さ れ ます。 こ の関数は、 セ ミ ホ ス
テ ィ ン グ呼び出 し を実行す る サポー ト 関数であ り 、 こ の関数に よ っ て ス ト リ
ン グが コ ン ソ ールに書 き 込ま れ ます。
2-6
Copyright © 2007 ARM Limited. All rights reserved.
ARM DUI 0203HJ
組み込みソ フ ト ウ ェ アの開発
2.2.3
デフ ォル ト の メ モ リ マ ッ プ
メ モ リ マ ッ プが記述 さ れていない イ メ ージでは、 図 2-3 に示す よ う に、 リ ン
カがデフ ォ ル ト の メ モ リ マ ッ プに従っ て コ ー ド と デー タ を配置 し ます。
Cortex-M1 と Cortex-M3 がデフ ォ ル ト の メ モ リ マ ッ プ と は異な る 固定 さ れた メ
モ リ マ ッ プ を使用 し てい る 場合で も 、 リ ン カでは Cortex-M1 モデル と
Cortex-M3 モデルに こ のデフ ォ ル ト の メ モ リ マ ッ プ を使用 し ます。 デフ ォ ル ト
の メ モ リ マ ッ プ を使用す る こ れ ら のプ ロ セ ッ サのモデルは機能 し ますが、 こ
の よ う なシ ス テ ム を ビル ド す る こ と はで き ません。 Cortex-M1 お よ び
Cortex-M3 の固定 さ れた メ モ リ マ ッ プの詳細については、 ARMv6-M お よ び
ARMv7-M メ モ リ マ ッ プ (ページ 2-25) を参照 し て下 さ い。
From
Semihosting
call
STACK
HEAP
Decided at
link time
ZI
RW
RO
0x8000
図 2-3 デ フ ォル ト の メ モ リ マ ッ プ
ARM DUI 0203HJ
Copyright © 2007 ARM Limited. All rights reserved.
2-7
組み込みソ フ ト ウ ェ アの開発
デフ ォ ル ト の メ モ リ マ ッ プは以下の よ う に記述で き ます。
2-8
•
イ メ ージは、 ア ド レ ス 0x8000 で ロ ー ド お よ び実行 さ れ る よ う に リ ン ク さ
れます。 すべての読み出 し 専用 (RO) セ ク シ ョ ンが最初に配置 さ れ、 そ
の後、 読み出 し - 書 き 込み (RW) セ ク シ ョ ン、 ゼ ロ で初期化 さ れた
(ZI) セ ク シ ョ ン の順に配置 さ れ ます。
•
ヒ ープは ZI セ ク シ ョ ン の先頭か ら 配置 さ れ る ため、 正確な位置は リ ン
ク 時に決ま り ます。
•
ス タ ッ ク ベース の位置は、 アプ リ ケーシ ョ ンの起動時のセ ミ ホ ス テ ィ ン
グオペレーシ ョ ンに よ っ て決ま り ます。 こ のセ ミ ホ ス テ ィ ン グオペレー
シ ョ ンに よ っ て返 さ れ る 値は、 デバ ッ グ環境に よ っ て異な り ます。
—
RealView ARMulator ISS (RVISS) では、 コ ン フ ィ グ レーシ ョ ン
フ ァ イ ル peripherals.ami に設定 さ れてい る 値が返 さ れ ます。 デフ ォ
ル ト は 0x08000000 です。
—
RealView ICE では、 デバ ッ ガ内部変数 top_of_memory の値が返 さ れ
ます。 デフ ォ ル ト は 0x00080000 です。
Copyright © 2007 ARM Limited. All rights reserved.
ARM DUI 0203HJ
組み込みソ フ ト ウ ェ アの開発
2.2.4
リ ン カの配置規則
リ ン カは、 図 2-4 に示す一連の規則に基づいて、 メ モ リ 内での コ ー ド と デー
タ の配置場所を決定 し ます。
section A
from file2.o
ZI
B
RW
DATA
section A
from file1.o
A
CODE
RO
図 2-4 リ ン カの配置規則
イ メ ージは、 まず属性別に配置 さ れ ます。 RO が メ モ リ の最下位ア ド レ ス に配
置 さ れ、 その後に RW、 ZI と 続 き ます。 各属性では、 コ ー ド がデー タ よ り も 優
先 さ れ ます。
次に、 入力セ ク シ ョ ンが名前のアルフ ァ ベ ッ ト 順で配置 さ れ ます。 入力セ ク
シ ョ ン の名前は、 アセ ンブ ラ の AREA デ ィ レ ク テ ィ ブに対応 し ます。
入力セ ク シ ョ ン では、 各オブジ ェ ク ト の コ ー ド と デー タ は、 リ ン カの コ マ ン
ド ラ イ ン でオブジ ェ ク ト フ ァ イ ルが指定 さ れた順序で配置 さ れます。
コ ー ド と デー タ を正確に配置す る 必要があ る 場合には、 こ れ ら の規則に頼 る
こ と はお勧め し ません。 コ ー ド と デー タ の配置を正確に制御す る には、 分散
ロ ー ド メ カ ニ ズ ム を使用す る 必要があ り ます。 詳細については、 タ ーゲ ッ ト
ハー ド ウ ェ アに合わせた イ メ ージの メ モ リ マ ッ プのカ ス タ マ イ ズ (ページ
2-16) を参照 し て下 さ い。
注
『Linker and Utilities Guide』 の分散 ロ ー ド について (ページ 5-2) を参照 し て下
さ い。
ARM DUI 0203HJ
Copyright © 2007 ARM Limited. All rights reserved.
2-9
組み込みソ フ ト ウ ェ アの開発
2.2.5
ア プ リ ケーシ ョ ンの起動
ほ と ん ど の組み込みシ ス テ ム では、 メ イ ン タ ス ク が実行 さ れ る 前に、 初期
シーケ ン ス に よ っ て シ ス テ ム のセ ッ ト ア ッ プが実行 さ れます。
図 2-5 は、 デフ ォ ル ト の初期化シーケ ン ス を示 し てい ます。
C Library
Image
entry point
USER CODE
__main
...
__scatterload
copy/decompress RW data
copy non-root code
zero uninitialized data
.
..
.
.
main()
causes the linker to
link in library
initialization code
__rt_entry
set up application stack
and heap
initialize library functions
call top-level
constructors (C++)
Exit from application
図 2-5 デ フ ォル ト の初期化シーケ ン ス
上位レベルでは、 こ の初期化シーケ ン ス を 3 つの機能ブ ロ ッ ク に分け る こ と
がで き ます。 __main は直接 __scatterload に分岐 し ます。 __scatterload では、 実
行時の イ メ ージの メ モ リ マ ッ プが設定 さ れ る のに対 し 、 __rt_entry (実行時の
エ ン ト リ ) では C ラ イ ブ ラ リ が初期化 さ れ ます。
__scatterload に よ っ て、 コ ー ド と デー タ の コ ピー、 お よ び ZI デー タ のゼ ロ 初
期化が実行 さ れ ます。 さ ら に、 必要に応 じ て、 RW デー タ が伸張 さ れます。
2-10
Copyright © 2007 ARM Limited. All rights reserved.
ARM DUI 0203HJ
組み込みソ フ ト ウ ェ アの開発
__scatterload は __rt_entry に分岐 し ます。 こ の分岐に よ り 、 アプ リ ケーシ ョ ン
の ス タ ッ ク と ヒ ープのセ ッ ト ア ッ プ、 ラ イ ブ ラ リ 関数 と その ス タ テ ィ ッ ク
デー タ の初期化、 お よ びグ ロ ーバルに宣言 さ れたオブジ ェ ク ト の コ ン ス ト ラ
ク タ の呼び出 し (C++ のみ) が実行 さ れ ます。
その後、 __rt_entry は、 アプ リ ケーシ ョ ンのエ ン ト リ であ る main() に分岐 し ま
す。 メ イ ン アプ リ ケーシ ョ ン の実行が終了す る と 、 __rt_entry に よ っ て ラ イ ブ
ラ リ がシ ャ ッ ト ダ ウ ン さ れ、 制御がデバ ッ ガに戻 さ れ ます。
関数 ラ ベル main() には特別な意味があ り ます。 main() 関数が存在す る こ と に よ
り 、 リ ン カは __main お よ び __rt_entry 内の初期化 コ ー ド を リ ン ク し ます。
main() 関数が存在 し ない場合は、 初期化シーケ ン ス が リ ン ク さ れず、 その結
果、 標準 C ラ イ ブ ラ リ の一部の機能がサポー ト さ れな く な り ます。 起動シ ン
ボルが __main と は異な る 代替の C ラ イ ブ ラ リ の使用方法の詳細については、
『Linker and Utilities Guide』 の イ メ ージ内容の制御 (ページ 2-18) にあ る
--[no_]startup シ ン ボ ル を参照 し て下 さ い。
2.2.6
ビル ド 1 のサン プル コ ー ド
ビル ド 1 は、 Dhrystone ベンチマー ク のデフ ォ ル ト の ビル ド です。 つま り 、 ビ
ル ド 1 は こ のセ ク シ ョ ン で説明 し た RVCT のデフ ォ ル ト の動作に準拠 し てい
ます。 詳細については、 Integrator 上での Dhrystone ビル ド の実行 (ページ 2-3)
と 、 メ イ ンサン プルデ ィ レ ク ト リ ...\emb_sw_dev\build1 にあ る サ ンプルビル ド
の フ ァ イ ルを参照 し て下 さ い。
ARM DUI 0203HJ
Copyright © 2007 ARM Limited. All rights reserved.
2-11
組み込みソ フ ト ウ ェ アの開発
2.3
タ ーゲ ッ ト ハー ド ウ ェ アに合わせた C ラ イ ブ ラ リ のカ ス タ マ イ ズ
デフ ォ ル ト では、 C ラ イ ブ ラ リ はセ ミ ホ ス テ ィ ン グ を利用 し てデバ イ ス ド ラ
イ バ レベルの機能を提供 し 、 ホ ス ト コ ン ピ ュ ー タ を入出力デバ イ ス と し て使
用で き る よ う に し ます。 開発時に使用す る ハー ド ウ ェ アには、 完成時のシ ス
テ ムに備わ る 入出力機能がすべて用意 さ れてい る と は限 り ません。
2.3.1
C ラ イ ブ ラ リ の タ ーゲ ッ ト 変更
タ ーゲ ッ ト ハー ド ウ ェ ア を利用 し 、 C ラ イ ブ ラ リ の実装を優先 し て イ メ ージ
に自動的に リ ン ク さ れ る C ラ イ ブ ラ リ 関数を独自に実装す る こ と がで き ます。
図 2-6 は、 C ラ イ ブ ラ リ の タ ーゲ ッ ト 変更 と 呼ばれ る こ のプ ロ セ ス を示 し て
い ます。
ISO C
ISO C
User
Code
C Library
Retarget
Debug
Agent
Input/
Output
Input/
Output
Semihosting
Support
Target
Hardware
図 2-6 C ラ イ ブ ラ リ の タ ーゲ ッ ト 変更
例えば、 UART な ど のペ リ フ ェ ラ ル I/O デバ イ ス があ る 場合、 デバ ッ ガの コ ン
ソ ールへの書 き 込みを行 う 、 ラ イ ブ ラ リ で実装 さ れた fputc() を、 UART に出
力す る 実装でオーバー ラ イ ド す る こ と が必要な場合があ り ます。 こ の fputc()
の実装は最終 イ メ ージに リ ン ク さ れ る ため、 printf() フ ァ ミ リ のすべての関数
が UART への出力を行い ます。
2-12
Copyright © 2007 ARM Limited. All rights reserved.
ARM DUI 0203HJ
組み込みソ フ ト ウ ェ アの開発
例 2-1 は、 fputc() の実装例を示 し てい ます。 こ の例では、 fputc() の入力文字
パ ラ メ ー タ がシ リ アル出力関数 sendchar() に転送 さ れます。 こ のシ リ アル出
力関数は、 別の ソ ース フ ァ イ ルで実装 さ れてい る と 仮定 し てい ます。 こ の よ
う に、 fputc() は、 タ ーゲ ッ ト に依存す る 出力 と C ラ イ ブ ラ リ 標準出力関数の
間の抽象レ イ ヤ と し て機能 し ます。
例 2-1 fputc() の実装
extern void sendchar(char *ch);
int fputc(int ch, FILE *f)
{
/* e.g. write a character to an UART */
char tempch = ch;
sendchar(&tempch);
return ch;
}
2.3.2
C ラ イ ブ ラ リ のセ ミ ホス テ ィ ン グの無効化
ス タ ン ド ア ロ ンのアプ リ ケーシ ョ ン では、 セ ミ ホ ス テ ィ ン グオペレーシ ョ ン
がサポー ト さ れない可能性があ り ます。 そのため、 C ラ イ ブ ラ リ のセ ミ ホ ス
テ ィ ン グ関数がアプ リ ケーシ ョ ン に リ ン ク さ れない よ う にす る 必要があ り ま
す。
セ ミ ホ ス テ ィ ン グ を使用す る 関数が C ラ イ ブ ラ リ か ら リ ン ク さ れない よ う に
す る には、 シ ン ボル __use_no_semihosting を イ ン ポー ト す る 必要があ り ます。
こ の イ ン ポー ト は、 以下の よ う に、 プ ロ ジ ェ ク ト の C ソ ース フ ァ イ ル ま たは
アセ ン ブ ラ ソ ース フ ァ イ ルで行 う こ と がで き ます。
•
C モジ ュ ールでは、 以下の よ う に #pragma デ ィ レ ク テ ィ ブ を使用 し ます。
#pragma import(__use_no_semihosting)
•
アセ ン ブ ラ モジ ュ ールでは、 以下の よ う に IMPORT デ ィ レ ク テ ィ ブ を使用
し ます。
IMPORT __use_no_semihosting
セ ミ ホ ス テ ィ ン グ を使用す る 関数が リ ン ク さ れた状態の ま ま の場合は、 リ ン
カに よ っ てエ ラ ーが レ ポー ト さ れ ます。
ARM DUI 0203HJ
Copyright © 2007 ARM Limited. All rights reserved.
2-13
組み込みソ フ ト ウ ェ アの開発
こ の よ う な関数を特定す る には、--verbose オプシ ョ ン を使用 し て リ ン ク を実行
し ます。 その結果、 C ラ イ ブ ラ リ 関数の場合には __I_use_semihosting の タ グが
付け ら れます。 以下に例を示 し ます。
Loading member sys_exit.o from c_a__un.l.
definition: _sys_exit
reference : __I_use_semihosting
こ れ ら の関数 ( こ の例では _sys_exit) は、 ユーザが実装す る 必要があ り ます。
注
アプ リ ケーシ ョ ン コ ー ド 内で使用 さ れてい る セ ミ ホ ス テ ィ ン グ関数は、 リ ン
カに よ っ て レ ポー ト さ れ ません。 エ ラ ーが発生す る のは、 セ ミ ホ ス テ ィ ン グ
関数が C ラ イ ブ ラ リ か ら リ ン ク さ れてい る 場合のみです。
セ ミ ホ ス テ ィ ン グ を使用す る C ラ イ ブ ラ リ 関数の リ ス ト については、「付録 A
セ ミ ホ ス テ ィ ン グ 」 を参照 し て下 さ い。
2.3.3
ビル ド 2 のサン プル コ ー ド
Dhrystone ベンチマー ク のビル ド 2 では、 ク ロ ッ ク 処理お よ びス ト リ ン グ入出
力に、 Integrator プ ラ ッ ト フ ォ ームのハー ド ウ ェ ア を使用 し てい ます。 こ のサ
ン プルビル ド の フ ァ イ ルは、 メ イ ンサ ンプルデ ィ レ ク ト リ
...\emb_sw_dev\build2 にあ り ます。
ビル ド 2 では、 ビル ド 1 のサン プルプ ロ ジ ェ ク ト に以下の変更が加え ら れて
い ます。
C ラ イ ブ ラ リ の タ ーゲ ッ ト 変更
タ ーゲ ッ ト が変更 さ れた ISO C 関数の レ イ ヤが追加 さ れ ま し た。
例えば、 標準 I/O 関数 と ク ロ ッ ク 機能に加え、 特別なエ ラ ー通知
機能 と プ ロ グ ラ ム終了機能が含まれてい ます。
タ ーゲ ッ ト に依存す る デバ イ ス ド ラ イ バ
タ ーゲ ッ ト ハー ド ウ ェ アのペ リ フ ェ ラ ル と 直接対話す る デバ イ
ス ド ラ イ バの レ イ ヤが追加 さ れ ま し た。
詳細については、 Integrator 上での Dhrystone ビル ド の実行 (ページ 2-3) を参
照 し て下 さ い。
2-14
Copyright © 2007 ARM Limited. All rights reserved.
ARM DUI 0203HJ
組み込みソ フ ト ウ ェ アの開発
シ ン ボル __use_no_semihosting は、 こ のプ ロ ジ ェ ク ト に イ ン ポー ト さ れてい ま
せん。 こ れは、 アプ リ ケーシ ョ ンの ス タ ッ ク と ヒ ープの位置を セ ッ ト ア ッ プ
す る C ラ イ ブ ラ リ の初期化中に、 セ ミ ホ ス テ ィ ン グ呼び出 し が実行 さ れ る た
めです。 ス タ ッ ク と ヒ ープのセ ッ ト ア ッ プにおけ る タ ーゲ ッ ト 変更の詳細に
ついては、 ス タ ッ ク と ヒ ープの配置 (ページ 2-21) を参照 し て下 さ い。
注
出力を確認す る には、 端末ま たは端末エ ミ ュ レー タ を シ リ アルポー ト A に接
続す る 必要があ り ます。 こ のシ リ アルポー ト は、 38400 ボー、 パ リ テ ィ な し 、
ス ト ッ プ ビ ッ ト 1、 お よ びフ ロ ー制御な し に設定す る 必要があ り ます。 端末
は、 入力行の終わ り に改行を追加 し 、 入力 さ れた文字を ロ ーカルに反映す る
よ う に設定す る 必要があ り ます。
ARM DUI 0203HJ
Copyright © 2007 ARM Limited. All rights reserved.
2-15
組み込みソ フ ト ウ ェ アの開発
2.4
タ ーゲ ッ ト ハー ド ウ ェ アに合わせた イ メ ージの メ モ リ マ ッ プのカ ス タ マ イズ
セ ミ ホ ス テ ィ ン グ機能がサポー ト さ れない最終的な組み込みシ ス テ ム では、
デフ ォ ル ト の メ モ リ マ ッ プが使用 さ れない可能性があ り ます。 通常、 タ ー
ゲ ッ ト ハー ド ウ ェ アでは、 複数の メ モ リ デバ イ ス が異な る ア ド レ ス範囲に配
置 さ れてい ます。 こ の よ う なデバ イ ス を最大限に活用す る には、 ロ ー ド 時 と
実行時にそれぞれの メ モ リ ビ ュ ーを使用す る 必要があ り ます。
2.4.1
分散ロー ド
分散 ロ ー ド に よ り 、 分散 ロ ー ド 記述フ ァ イ ル と 呼ばれ る テ キ ス ト の記述フ ァ
イ ル内で、 ロ ー ド 時 と 実行時の メ モ リ 内の コ ー ド と デー タ の位置を指定で き
ます。 こ の フ ァ イ ルは、 コ マ ン ド ラ イ ン で --scatter オプシ ョ ン を使用す る と 、
リ ン カに渡 さ れます。 以下に例を示 し ます。
armlink --scatter scat.txt file1.o file2.o
分散 ロ ー ド 記述フ ァ イ ルでは、 メ モ リ 領域を ア ド レ ス指定す る こ と に よ り 、
ロ ー ド 時 と 実行時におけ る コ ー ド と デー タ の必要な位置を リ ン カに示 し ます。
分散ロー ド 領域
分散 ロ ー ド 領域は以下の 2 つのカ テ ゴ リ に分類 さ れ ます。
•
リ セ ッ ト 時 と ロ ー ド 時にアプ リ ケーシ ョ ン コ ー ド と デー タ を保持す る
ロ ー ド 領域。
•
アプ リ ケーシ ョ ンの実行中に コ ー ド と デー タ を保持す る 実行領域。 アプ
リ ケーシ ョ ンの起動中に、 各 ロ ー ド 領域か ら 1 つま たは複数の実行領域
が作成 さ れ ます。
イ メ ージ内のすべての コ ー ド と デー タ は、 1 つの ロ ー ド 領域 と 1 つの実行領域
に保持 さ れ ます。
起動中、 __main 内の C ラ イ ブ ラ リ 初期化 コ ー ド に よ っ て、 イ メ ージの ロ ー ド
ビ ュ ーか ら 実行ビ ュ ーに移動す る 必要のあ る コ ー ド と デー タ の コ ピーお よ び
ゼ ロ 初期化が実行 さ れ ます。
2-16
Copyright © 2007 ARM Limited. All rights reserved.
ARM DUI 0203HJ
組み込みソ フ ト ウ ェ アの開発
2.4.2
分散ロー ド 記述 フ ァ イルの構文
分散 ロ ー ド 記述フ ァ イ ルの構文には、 分散 ロ ー ド 自体に用意 さ れてい る 機能
が反映 さ れてい ます。 図 2-7 は、 こ の フ ァ イ ルの構文を示 し てい ます。
name of region
start address
MY_REGION 0x0000
{
contents of region
}
0x2000
optional length
parameter
図 2-7 分散ロー ド 記述フ ァ イルの構文
領域は、 ヘ ッ ダ タ グで定義 さ れ ます。 ヘ ッ ダ タ グには、 少な く と も 領域の名
前 と 開始ア ド レ ス が含まれてい ますが、 必要に応 じ て、 最大長や さ ま ざ ま な
属性を追加で き ます。
領域の内容は領域の タ イ プに よ っ て異な り ます。
•
ロ ー ド 領域には、 少な く と も 1 つの実行領域が含まれてい る 必要があ り
ます。 実際には、 各 ロ ー ド 領域に複数の実行領域が含まれてい る こ と が
一般的です。
•
領域が EMPTY 属性で宣言 さ れてい る 場合を除いて、 実行領域には、 少な
く と も 1 つの コ ー ド セ ク シ ョ ン ま たはデー タ セ ク シ ョ ンが含ま れてい る
必要があ り ます。 通常、 EMPTY で宣言 さ れていない領域には、 ソ ース フ ァ
イ ルま たは ラ イ ブ ラ リ オブジ ェ ク ト フ ァ イ ルが含まれてい ます。 ワ イ ル
ド カー ド (*) 構文を使用す る と 、 分散 ロ ー ド 記述フ ァ イ ル内で指定 さ
れていない特定の属性を含むすべてのセ ク シ ョ ン を グループ化で き ま
す。
注
分散 ロ ー ド 記述フ ァ イ ルの構文の詳細については、 『Linker and Utilities Guide』
の 「第 5 章 分散 ロ ー ド 記述フ ァ イ ルの使用」 を参照 し て下 さ い。
ARM DUI 0203HJ
Copyright © 2007 ARM Limited. All rights reserved.
2-17
組み込みソ フ ト ウ ェ アの開発
2.4.3
分散ロー ド 記述 フ ァ イルの例
図 2-8 は、 単純な分散 ロ ー ド の例を示 し てい ます。
0x18000
Load View
Execute View
Fill
with
zeros
RAM
0x18000
ZI
RAM
RW
0x10000
0x10000
Copy/
decompress
0x4000
0x4000
ROM
ROM
RW
RO
RO
0x0000
0x0000
図 2-8 単純な分散ロー ド の例
こ の例では、 ア ド レ ス 0x0000 で始ま り 、 すべての コ ー ド と デー タ を含む 1 つ
の ロ ー ド 領域を使用 し てい ます。 こ の ロ ー ド 領域か ら 2 つの実行領域が作成 さ
れ ます。 1 つの実行領域には、 RO のすべての コ ー ド と デー タ が含ま れてい ま
す。 こ の領域は、 ロ ー ド 時のア ド レ ス と 同 じ ア ド レ ス で実行 さ れ ます。 も う 1
つの領域は、 ア ド レ ス 0x10000 で始ま り 、 すべての RW デー タ と ZI デー タ を
含んでい ます。
例 2-2 は、 図 2-8 の メ モ リ マ ッ プ を記述 し た記述フ ァ イ ルを示 し てい ます。
例 2-2 単純な分散ロー ド 記述フ ァ イル
ROM_LOAD 0x0000 0x4000
{
ROM_EXEC 0x0000 0x4000; Root region
{
2-18
Copyright © 2007 ARM Limited. All rights reserved.
ARM DUI 0203HJ
組み込みソ フ ト ウ ェ アの開発
* (+RO); All code and constant data
}
RAM 0x10000 0x8000
{
* (+RW, +ZI); All non-constant data
}
}
2.4.4
分散ロー ド 記述 フ ァ イルでのオブ ジ ェ ク ト の配置
ほ と ん ど の イ メ ージでは、 例 2-2 (ページ 2-18) に示 し た よ う に、 すべての属
性を 1 つに ま と め る のではな く 、 特定の コ ー ド セ ク シ ョ ン と デー タ セ ク シ ョ
ンの配置を制御 し ます。 セ ク シ ョ ン の配置は、 ワ イ ル ド カー ド 構文だけに頼
る のではな く 、 記述フ ァ イ ル内で各オブジ ェ ク ト を直接指定す る こ と に よ っ
て制御で き ます。
注
記述フ ァ イ ルの実行領域内のオブジ ェ ク ト の順序が、 出力 イ メ ージ内のオブ
ジ ェ ク ト の順序に影響す る こ と はあ り ません。 各実行領域には、 リ ン カの配
置規則 (ページ 2-9) で説明 し た リ ン カの配置規則が適用 さ れ ます。
標準的な リ ン カの配置規則を オーバー ラ イ ド す る には、 分散 ロ ー ド の +FIRST
デ ィ レ ク テ ィ ブお よ び +LAST デ ィ レ ク テ ィ ブ を使用で き ます。 例 2-3 は、 実行
領域の先頭にベ ク タ テーブルを配置す る 分散 ロ ー ド 記述フ ァ イ ルを示 し てい
ます。 こ の例では、 vectors.o 内のエ リ ア Vect がア ド レ ス 0x0000 に配置 さ れ ま
す。
例 2-3 セ ク シ ョ ンの配置
ROM_LOAD 0x0000 0x4000
{
ROM_EXEC 0x0000 0x4000
{
vectors.o (Vect, +FIRST)
* (+RO)
}
; more exec regions...
}
ARM DUI 0203HJ
Copyright © 2007 ARM Limited. All rights reserved.
2-19
組み込みソ フ ト ウ ェ アの開発
分散 ロ ー ド 記述フ ァ イ ル内でのオブジ ェ ク ト の配置の詳細については、
『Linker and Utilities Guide』 の 「第 5 章 分散 ロ ー ド 記述フ ァ イ ルの使用」 を参
照 し て下 さ い。
2.4.5
ルー ト 領域
ルー ト 領域 と は、 ロ ー ド ア ド レ ス が実行ア ド レ ス と 同 じ 実行領域の こ と です。
各分散 ロ ー ド 記述フ ァ イ ルには、 少な く と も 1 つのルー ト 領域が必要です。
分散 ロ ー ド では、 実行領域の作成 (例えば、 コ ー ド と デー タ の コ ピーやゼ ロ
初期化) に関与す る コ ー ド と デー タ は別の場所に コ ピーで き ない と い う 制約
があ り ます。 そのため、 ルー ト 領域には以下のセ ク シ ョ ン が含まれてい る 必
要があ り ます。
•
コ ー ド と デー タ を コ ピーす る コ ー ド を保持す る __main.o お よ び
__scatter*.o
•
•
伸張を実行す る __dc*.o
コ ピーま たは伸張 さ れ る コ ー ド と デー タ のア ド レ ス を保持す る
Region$$Table セ ク シ ョ ン
上記のセ ク シ ョ ンは、 InRoot$$Sections を使用 し て記述で き ます。
上記のセ ク シ ョ ンは読み出 し 専用 と し て定義 さ れ る ため、 * (+RO) ワ イ ル ド
カー ド 構文でグループ化 さ れます。 そのため、 * (+RO) が非ルー ト 領域で指定
さ れてい る 場合は、 上記のセ ク シ ョ ン をルー ト 領域で明示的に宣言す る 必要
があ り ます。 こ れは 例 2-4 に示 し てい ます。
例 2-4 ルー ト 領域の指定
ROM_LOAD 0x0000 0x4000
{
ROM_EXEC 0x0000 0x4000
{
vectors.o (Vect, +FIRST)
* (InRoot$$Sections)
}
RAM 0x10000 0x8000
{
* (+RO, +RW, +ZI)
2-20
; root region
;
;
;
;
Vector table
All library sections that must be in a
root region, for example, __main.o,
__scatter*.o, __dc*.o, and * Region$$Table
; all other sections
Copyright © 2007 ARM Limited. All rights reserved.
ARM DUI 0203HJ
組み込みソ フ ト ウ ェ アの開発
}
}
__main.o、 __scatter.o、 __dc*.o、 お よ び Region$$Table がルー ト 領域に含まれて
いない場合は、 リ ン カに よ っ て以下のエ ラ ー メ ッ セージが生成 さ れます。
2.4.6
ス タ ッ ク と ヒ ープの配置
分散 ロ ー ド に よ り 、 コ ー ド と 静的に割 り 当て ら れたデー タ の位置を イ メ ージ
内で指定で き ます。 アプ リ ケーシ ョ ンの ス タ ッ ク と ヒ ープは、 C ラ イ ブ ラ リ の
初期化中にセ ッ ト ア ッ プ さ れ ます。 ス タ ッ ク と ヒ ープの位置は、
__user_initial_stackheap() 関数を再実装す る こ と に よ っ て カ ス タ マ イ ズで き ま
す。 あ る いは、 ARM_LIB_HEAP お よ び ARM_LIB_STACK と い う 実行領域を使用で き ま
す。 詳細については、 『Linker and Utilities Guide』 の分散 ロ ー ド 記述フ ァ イ ルを
使用 し た ス タ ッ ク と ヒ ープの指定 (ページ 5-3) を参照 し て下 さ い。
2.4.7
ラ ン タ イ ム メ モ リ モデル
2 つの ラ ン タ イ ム メ モ リ モデルが用意 さ れてい ます。 ど ち ら の ラ ン タ イ ム メ モ
リ モデルで も 、 ス タ ッ ク はチ ェ ッ ク さ れずに拡大 し ます。
注
Integrator シ ス テ ム では、 ど ち ら のモデル も 使用で き ます。
1 領域モデル
デフ ォ ル ト の 1 領域モデル では、 アプ リ ケーシ ョ ンの ス タ ッ ク と ヒ ープが、
同 じ メ モ リ 領域内で互いに向か っ て拡大 し ます。 こ の場合の ヒ ープは、 新 し
い ヒ ープ空間が割 り 当て ら れ る と (例えば、 malloc() が呼び出 さ れ る と )、 ス
タ ッ ク ポ イ ン タ の値に照 ら し 合わせてチ ェ ッ ク さ れます。
図 2-9 (ページ 2-22) と 例 2-5 (ページ 2-22) は、 単純な 1 領域モデルを実装す
る __user_initial_stackheap() の例を示 し てい ます。 こ のモデルでは、 ス タ ッ
ク がア ド レ ス 0x40000 か ら 下方に拡大 し 、 ヒ ープが 0x20000 か ら 上方に拡大 し
ます。
こ のルーチンは、 適切な値を レ ジ ス タ r0 と r1 に ロ ー ド し てか ら 呼び出 し
ルーチンに復帰 し ます。 1 領域モデルでは ヒ ープ リ ミ ッ ト が使用 さ れないた
め、 レ ジ ス タ r2 は変更 さ れ ません。 レ ジ ス タ r3 は使用 さ れ ません。
ARM DUI 0203HJ
Copyright © 2007 ARM Limited. All rights reserved.
2-21
組み込みソ フ ト ウ ェ アの開発
SB
HB
STACK
0x40000
HEAP
0x20000
図 2-9 1 領域モデル
例 2-5 1 領域モデルのルーチ ン
EXPORT __user_initial_stackheap
__user_initial_stackheap
LDR r0, =0x20000 ;HB
LDR r1, =0x40000 ;SB
; r2 not used (HL)
; r3 not used
MOV pc, lr
2 領域モデル
シ ス テ ム設計では、 ス タ ッ ク と ヒ ープ を個別の メ モ リ 領域に配置す る こ と が
必要にな る 場合があ り ます。
例えば、 高速 RAM の一部を ス タ ッ ク 専用に予約 し てお く 場合があ る と し ま
す。 2 領域モデル を使用す る こ と を リ ン カに通知す る には、 アセ ン ブ ラ の
IMPORT デ ィ レ ク テ ィ ブ を使用 し て、 シ ン ボル __use_two_region_memory を イ ン
ポー ト す る 必要があ り ます。 こ のシ ン ボルを イ ン ポー ト す る と 、 ヒ ープは、
__user_initial_stackheap() に よ っ て設定 さ れてい る 専用の ヒ ープ リ ミ ッ ト と 照
ら し 合わせてチ ェ ッ ク さ れ ます。
図 2-10 (ページ 2-23) と 例 2-6 (ページ 2-23) は、 2 領域モデルの実装例を示
し てい ます。
こ の例では、 ヒ ープが 0x28000000 か ら 0x28080000 ま で上方に拡大 し 、 ス タ ッ ク
が 0x40000 か ら 下方に拡大 し ます。
2-22
Copyright © 2007 ARM Limited. All rights reserved.
ARM DUI 0203HJ
組み込みソ フ ト ウ ェ アの開発
HL
HB
SB
0x28080000
HEAP
0x28000000
STACK
0x40000
図 2-10 2 領域モデル
例 2-6 2 領域モデルのルーチ ン
IMPORT __use_two_region_memory
EXPORT __user_initial_stackheap
__user_initial_stackheap
LDR r0, =0x28000000 ;HB
LDR r1, =0x40000 ;SB
LDR r2, =0x28080000 ;HL
; r3 not used
MOV pc, lr
2.4.8
ビル ド 3 のサン プル コ ー ド
ビル ド 3 のサン プルでは、 分散 ロ ー ド が実装 さ れ、 再実装 さ れた
__user_initial_stackheap() が含まれてい ます。 こ のサン プルビル ド の フ ァ イ ル
は、 メ イ ンサン プルデ ィ レ ク ト リ ...\emb_sw_dev\build3 にあ り ます。
ビル ド 3 では、 ビル ド 2 のサン プルプ ロ ジ ェ ク ト に以下の変更が加え ら れて
い ます。
分散 ロ ー ド
単純な分散 ロ ー ド 記述フ ァ イ ルが リ ン カに渡 さ れます。
ARM DUI 0203HJ
Copyright © 2007 ARM Limited. All rights reserved.
2-23
組み込みソ フ ト ウ ェ アの開発
タ ーゲ ッ ト が変更 さ れた __user_initial_stackheap()
1 領域モデル と 2 領域モデルの ど ち ら を実装す る か を選択で き ま
す。 デフ ォ ル ト の ビル ド では、 1 領域モデルが使用 さ れ ます。 2 領
域モデルの実装は、 アセ ン ブルす る 際に TWO_REGION_MODEL を定義
す る こ と に よ っ て選択で き ます。
C ラ イ ブ ラ リ のセ ミ ホ ス テ ィ ン グの無効化
イ メ ージに C ラ イ ブ ラ リ のセ ミ ホ ス テ ィ ン グ関数が存在 し ない
ため、 シ ン ボル __use_no_semihosting が ビル ド 3 に イ ン ポー ト さ れ
ます。
注
clock() にセ ミ ホ ス テ ィ ン グが使用 さ れない よ う にす る ため、
Integrator AP 上の リ アル タ イ ム ク ロ ッ ク (RTC) を読み出す よ う
に タ ーゲ ッ ト が変更 さ れます。 こ の分解能は 1 秒であ る ため、
Dhrystone では正確な結果が得 ら れません。 こ の メ カ ニズ ムは、
ビル ド 4 ( ビル ド 4 のサンプル コ ー ド (ページ 2-36) 参照) で改
善 さ れてい ます。
こ のビル ド を Integrator AP 上で実行す る には、 ROM/RAM の リ マ ッ プ を実行
す る 必要があ り ます。 リ マ ッ プ を実行す る には、 ス イ ッ チ 1 お よ び 4 を オ ンに
設定 し てブー ト モニ タ を起動 し ます。
詳細については、 Integrator 上での Dhrystone ビル ド の実行 (ページ 2-3) を参
照 し て下 さ い。
注
ARM7 コ アベース の タ ーゲ ッ ト を使用 し てい る 場合は、 すべてのベ ク タ
キ ャ ッ チ と セ ミ ホ ス テ ィ ン グ を無効にす る 必要があ り ます。 無効に し ない場
合は、 デバ ッ ガに よ っ て、 ア ド レ ス 0x0 と 0x1C 間で実行 さ れた命令は例外 と
し て解釈 さ れ、 ダ イ ア ロ グボ ッ ク ス に こ の解釈が レ ポー ト さ れ ます。 ベ ク タ
キ ャ ッ チ と セ ミ ホ ス テ ィ ン グ を無効にす る 方法の詳細については、 デバ ッ ガ
のマニ ュ アルを参照 し て下 さ い。
2-24
Copyright © 2007 ARM Limited. All rights reserved.
ARM DUI 0203HJ
組み込みソ フ ト ウ ェ アの開発
2.4.9
ARMv6-M お よび ARMv7-M メ モ リ マ ッ プ
以前の ARM コ アの大部分 と は異な り 、 ARMv6-M お よ び ARMv7-M プ ロ セ ッ
サ をベース に し たデバ イ ス の メ モ リ マ ッ プの全体的な レ イ ア ウ ト は固定 さ れ
てい ます。 そのため、 上記のプ ロ セ ッ サ をベース に し た さ ま ざ ま な シ ス テ ム
の間では、 ソ フ ト ウ ェ アのポー ト 指定が容易にな り ます。
表 2-1 は、 上記の メ モ リ マ ッ プの主要な部分を示 し てい ます。
表 2-1
メ モ リ 領域
説明
ア ク セス経路
ア ド レ ス範囲
コー ド
標準のフ ラ ッ シ ュ SRAM ま たは ROM
ICode お よ び Dcode
バス
0x00000000-0x1FFFFFFF
SRAM
オンチ ッ プ SRAM、 ビ ッ ト バン ド 機能
付き
シ ス テ ムバ ス
0x20000000-0x3FFFFFFF
ペ リ フ ェ ラル
標準のペ リ フ ェ ラ ル、 ビ ッ ト バン ド 機
能付 き
シ ス テ ムバ ス
0x40000000-0x5FFFFFFF
外部 RAM
外部 メ モ リ
シ ス テ ムバ ス
0x60000000-0x9FFFFFFF
外部デバ イ ス
外部ペ リ フ ェ ラ ルま たは共有 メ モ リ
シ ス テ ムバ ス
0xA0000000-0xDFFFFFFF
専用ペ リ フ ェ ラ ル
バス
シ ス テ ムデバ イ ス (表 2-3 (ページ
2-26) 参照)
シ ス テ ムバ ス
0xE0000000-0xE00FFFFF
ベン ダ固有
-
-
0xE0100000-0xfFFFFFFF
SRAM 領域 と ペ リ フ ェ ラ ル領域にはそれぞれ、 ビ ッ ト バン ド 機能が付いてい
ます。 ビ ッ ト バン ド 領域の各ビ ッ ト には、 ビ ッ ト バン ド エ イ リ ア ス と 呼ばれ
る 異な る ア ド レ ス で個々にア ク セ ス で き ます。 例えば、 0x20000001 で ワ ー ド の
ビ ッ ト [13] にア ク セ スす る には、 ア ド レ ス 0x2200002D を使用で き ます。
ARM DUI 0203HJ
Copyright © 2007 ARM Limited. All rights reserved.
2-25
組み込みソ フ ト ウ ェ アの開発
表 2-2 は、 SRAM メ モ リ 領域 と ペ リ フ ェ ラ ル メ モ リ 領域内の ビ ッ ト バン ド 領
域 と エ イ リ ア ス を示 し てい ます。
表 2-2
メ モ リ 領域
説明
ア ド レ ス範囲
SRAM
ビ ッ ト バン ド 領域
0x20000000-0x200FFFFF
ビ ッ ト バン ド エ イ リ ア
ス
0x22000000-0x23FFFFFF
ビ ッ ト バン ド 領域
0x40000000-0x400FFFFF
ビ ッ ト バン ド エ イ リ ア
ス
0x42000000-0x43FFFFFF
ペ リ フ ェ ラル
表 2-3 は、 専用ペ リ フ ェ ラ ルバ ス メ モ リ 領域内の各部を示 し てい ます。
表 2-3
メ モ リ 領域
説明
ア ド レ ス範囲
専用ペ リ フ ェ ラ ルバス、 外部
ITM
0xE0000000-0xE0000FFF
DWT
0xE0001000-0xE0001FFF
FPB
0xE0002000-0xE0002FFF
予約
0xE0003000-0xE000DFFF
シ ス テ ム制御領域
0xE000E000-0xE000EFFF
予約
0xE000F000-0xE003FFFF
TPIU
0xE0040000-0xE0040FFF
ETM
0xE0041000-0xE0041FFF
外部 PPB
0xE0042000-0xE00FEFFF
ROM の表
0xE00FF000-0xE00FFFFF
専用ペ リ フ ェ ラ ルバス、 内部
2-26
Copyright © 2007 ARM Limited. All rights reserved.
ARM DUI 0203HJ
組み込みソ フ ト ウ ェ アの開発
2.5
リ セ ッ ト と 初期化
本章では こ れ ま で、 C ラ イ ブ ラ リ 初期化ルーチンへのエ ン ト リ ポ イ ン ト
__main で実行が開始 さ れ る と 想定 し て き ま し た。 実際には、 タ ーゲ ッ ト ハー ド
ウ ェ ア上の組み込みアプ リ ケーシ ョ ンに よ っ て、 起動時に何 ら かのシ ス テ ム
レベルの初期化が実行 さ れます。 こ のセ ク シ ョ ン では、 こ の よ う な シ ス テ ム
レベルの初期化について詳 し く 説明 し ます。
2.5.1
初期化シーケ ン ス
図 2-11 は、 ARM アーキ テ ク チ ャ ベース の組み込みシ ス テ ム で考え ら れ る 初
期化シーケ ン ス を示 し てい ます。
C Library
USER CODE
2
__main
3
..
.
__scatterload
copy/decompress RW data
copy non-root code
zero uninitialized data
.
.
.
5
4
__rt_entry
initialize library
functions
call top-level
constructors (C++)
..
.
reset handler
initialize stack pointers
configure MMU/MPU
setup cache/enable
TCM
1
Image
entry point
.
__user_initial_stackheap()
set up application stack
and heap
.
$Sub$$main()
enable caches and
interrupts
6
Exit from application
8
.
main()
causes the linker to link
in library initialization
code
7
図 2-11 初期化シーケ ン ス
リ セ ッ ト ハン ド ラ は、 シ ス テ ムの起動直後に実行 さ れ ます。 $Sub$$main() と い
う コ ー ド ブ ロ ッ ク は、 メ イ ン アプ リ ケーシ ョ ン に入 る 直前に実行 さ れ ます。
リ セ ッ ト ハン ド ラ は、 アセ ン ブ ラ で コ ーデ ィ ン グ さ れた小 さ なモジ ュ ールで
あ り 、 シ ス テ ムの リ セ ッ ト 時に実行 さ れます。 リ セ ッ ト ハン ド ラ は、 少な く
と も 、 アプ リ ケーシ ョ ンが実行 さ れてい る モー ド の ス タ ッ ク ポ イ ン タ を初期
化 し ます。 キ ャ ッ シ ュ 、 密結合 メ モ リ (TCM)、 メ モ リ 管理ユニ ッ ト
ARM DUI 0203HJ
Copyright © 2007 ARM Limited. All rights reserved.
2-27
組み込みソ フ ト ウ ェ アの開発
(MMU)、 メ モ リ 保護ユニ ッ ト (MPU) な ど の ロ ーカルの メ モ リ シ ス テ ム を
使用す る コ アの場合は、 こ の初期化プ ロ セ ス の段階で何 ら かの設定を行 う 必
要があ り ます。 通常、 実行後に リ セ ッ ト ハン ド ラ が __main に分岐 し て、 C ラ イ
ブ ラ リ 初期化シーケ ン ス を開始 し ます。
割 り 込みの有効化な ど、 シ ス テ ムの初期化にはい く つかの コ ン ポーネ ン ト が
あ り 、 一般的には C ラ イ ブ ラ リ 初期化 コ ー ド の実行終了後に実行 さ れます。
こ れ ら の処理は、 $Sub$$main() と い う コ ー ド ブ ロ ッ ク で、 メ イ ン アプ リ ケー
シ ョ ン が実行 さ れ る 直前に実行 さ れます。
初期化シーケ ン ス の さ ま ざ ま な コ ン ポーネ ン ト の詳細については、 「ベ ク タ
テーブル」 を参照 し て下 さ い。
2.5.2
ベ ク タ テーブル
すべての ARM シ ス テ ムには、 ベ ク タ テーブル があ り ます。 ベ ク タ テーブル
は、 初期化シーケ ン ス の一部ではあ り ませんが、 例外を処理す る ために必要
です。
注
こ のセ ク シ ョ ン の内容は、 ARMv6-M プ ロ セ ッ サ ま たは ARMv7-M プ ロ セ ッ サ
には適用 さ れ ません。 こ れ ら のプ ロ セ ッ サのベ ク タ テーブルの詳細について
は、 ベ ク タ テーブル (ページ 7-6) を参照 し て下 さ い。
例 2-7 の コ ー ド では、 他のモジ ュ ールで コ ーデ ィ ン グ さ れてい る さ ま ざ ま な
例外ハン ド ラ を イ ン ポー ト し ます。 ベ ク タ テーブルは、 例外ハン ド ラ への分
岐命令の リ ス ト です。
FIQ ハン ド ラ は、 ア ド レ ス 0x1C に直接配置 さ れます。 こ れに よ り 、 FIQ ハン ド
ラ への分岐を実行す る 必要がな く な る ため、 FIQ 応答時間が最適化 さ れます。
例 2-7 ベ ク タ テーブルのコ ー ド
PRESERVE8
AREA Vectors, CODE, READONLY
IMPORT Reset_Handler
; import other exception handlers
; ...
ENTRY
B
Reset_Handler
B
Undefined_Handler
B
SVC_Handler
2-28
Copyright © 2007 ARM Limited. All rights reserved.
ARM DUI 0203HJ
組み込みソ フ ト ウ ェ アの開発
B
B
NOP
B
B
Prefetch_Handler
Abort_Handler
; Reserved vector
IRQ_Handler
FIQ_Handler
END
注
ベ ク タ テーブルは、 ラ ベル ENTRY でマー ク さ れてい ます。 こ の ラ ベルに よ っ
て、 こ の コ ー ド がエ ン ト リ ポ イ ン ト であ る 可能性が リ ン カに通知 さ れ る ため、
リ ン ク 時に イ メ ージか ら 削除 さ れ る こ と はあ り ません。 ただ し 、--entry リ ン カ
オプシ ョ ン を使用 し て、 イ メ ージ内で使用 さ れ る エ ン ト リ ポ イ ン ト の う ちの
1 つを実際のエ ン ト リ ポ イ ン ト と し て選択す る 必要があ り ます。 『Linker and
Utilities Guide』 の イ メ ージ内容の制御 (ページ 2-18) を参照 し て下 さ い。
2.5.3
ROM/RAM の リ マ ッ プ
ユーザは、 最初に実行 さ れ る 命令のア ド レ ス 0x0000 に ど の よ う な メ モ リ を配
置す る のか を検討す る 必要があ り ます。
注
こ のセ ク シ ョ ン では、 ARM コ アに よ る 命令フ ェ ッ チが 0x0000 で開始 さ れ る こ
と を想定 し てい ます。 こ のア ド レ ス は、 ARM コ アベース シ ス テ ムの標準で
す。 ただ し 、 一部の ARM コ アでは、 命令フ ェ ッ チを 0xFFFF0000 か ら 開始す る
よ う に設定で き ます。
起動時にはア ド レ ス 0x0000 に有効な命令が存在 し てい る 必要があ る ため、 リ
セ ッ ト 時に不揮発性 メ モ リ が 0x0000 に配置 さ れ る よ う にす る 必要があ り ます。
1 つの方法 と し ては、 ROM を 0x0000 に配置す る こ と がで き ます。 ただ し 、 こ
の設定にはい く つかの欠点があ り ます。 一般的に、 ROM へのア ク セ ス速度は
RAM よ り も 遅いため、 例外ハン ド ラ へ分岐す る 際に過度のパフ ォ ーマ ン スペ
ナルテ ィ が発生す る 場合には、 シ ス テ ム で問題が発生す る こ と があ り ます。
ま た、 ROM にベ ク タ テーブルを配置す る と 、 実行時にそのベ ク タ テーブルを
変更で き な く な り ます。
図 2-12 (ページ 2-30) は、 別の方法を示 し てい ます。 ROM はア ド レ ス 0x10000
に配置 さ れ ますが、 こ の メ モ リ は リ セ ッ ト 時に メ モ リ コ ン ト ロ ー ラ に よ っ て
0 にエ イ リ ア ス さ れ ます。 リ セ ッ ト 後、 リ セ ッ ト ハン ド ラ 内の コ ー ド は ROM
の実ア ド レ ス に分岐 し ます。 その後、 メ モ リ コ ン ト ロ ー ラ に よ っ て、 エ イ リ
ARM DUI 0203HJ
Copyright © 2007 ARM Limited. All rights reserved.
2-29
組み込みソ フ ト ウ ェ アの開発
ア ス さ れた ROM が削除 さ れ る ため、RAM がア ド レ ス 0x0000 に配置 さ れ ます。
__main では、 ベ ク タ テーブルが 0x0000 にあ る RAM に コ ピー さ れ る ため、 例外
を処理す る こ と がで き ます。
1
2
3
0x18000
0x18000
ROM
ROM
0x10000
Reset Handler
Reset Handler
Branch
to real
ROM
0x4000
0x10000
0x4000
Remove
Alias
Aliased
ROM
0x0000
Reset Handler
RAM
Reset Handler
Reset Handler
Vectors
0x0000
図 2-12 ROM/RAM の リ マ ッ プ
例 2-8 は、 ARM アセ ンブ ラ モジ ュ ールで ROM/RAM の リ マ ッ プ を実装す る 方
法を示 し てい ます。 こ こ に示 さ れてい る 定数は Integrator プ ラ ッ ト フ ォ ームに
固有の も のですが、 ROM/RAM の リ マ ッ プ を同様の方法で実装す る ど のプ
ラ ッ ト フ ォ ーム に も 同 じ 方法を使用で き ます。
例 2-8 ROM/RAM の リ マ ッ プ
; --- Integrator CM control reg
CM_ctl_reg
EQU 0x1000000C
Remap_bit
EQU 0x04
; Address of CM Control Register
; Bit 2 is remap bit of CM_ctl
ENTRY
; Code execution starts here on reset
2-30
Copyright © 2007 ARM Limited. All rights reserved.
ARM DUI 0203HJ
組み込みソ フ ト ウ ェ アの開発
; On reset, an alias of ROM is at 0x0, so jump to 'real' ROM.
LDR
pc, =Instruct_2
Instruct_2
; Remap by setting Remap bit of the CM_ctl register
LDR
r1, =CM_ctl_reg
LDR
r0, [r1]
ORR
r0, r0, #Remap_bit
STR
r0, [r1]
; RAM is now at 0x0.
; The exception vectors must be copied from ROM to RAM (in __main)
; Reset_Handler follows on from here
最初の命令は、 エ イ リ ア ス さ れた ROM か ら 実際の ROM へのジ ャ ン プです。
こ の命令を実行で き る のは、 ラ ベル Instruct_2 が実際の ROM ア ド レ ス に配置
さ れてい る ためです。
こ の ス テ ッ プの後、 Integrator コ アモジ ュ ールの制御レ ジ ス タ の リ マ ッ プ ビ ッ
ト を反転す る こ と に よ っ て、 ROM のエ イ リ ア ス が削除 さ れ ます。
通常、 こ の コ ー ド は、 シ ス テ ムの リ セ ッ ト 直後に実行 さ れ ます。 リ マ ッ プは、
C ラ イ ブ ラ リ 初期化 コ ー ド が実行 さ れ る 前に完了す る 必要があ り ます。
注
MMU が搭載 さ れてい る シ ス テ ム では、 シ ス テ ム の起動時に MMU の設定に
よ っ て リ マ ッ プ を実装で き ます。
2.5.4
ロー カル メ モ リ のセ ッ ト ア ッ プに関する注意事項
多 く の ARM コ アには、 MMU や MPU な ど のオ ンチ ッ プ メ モ リ シ ス テ ム が搭
載 さ れてい ます。 通常、 こ れ ら のデバ イ ス は、 シ ス テ ム の起動時にセ ッ ト
ア ッ プお よ び有効に さ れ ます。 そのため、 ロ ーカル メ モ リ シ ス テ ム を搭載す
る コ アの初期化シーケ ン ス には、 特別な配慮が必要です。
本章で説明 し て き た よ う に、 __main の C ラ イ ブ ラ リ 初期化 コ ー ド では、 イ
メ ージの実行時 メ モ リ マ ッ プがセ ッ ト ア ッ プ さ れ ます。 そのため、 プ ロ セ ッ
サ コ アの ラ ン タ イ ム メ モ リ ビ ュ ーは、 __main への分岐の前にセ ッ ト ア ッ プす
る 必要があ り ます。 つま り 、 MMU ま たは MPU は、 リ セ ッ ト ハン ド ラ 内で
セ ッ ト ア ッ プお よ び有効にす る 必要があ り ます。
ARM DUI 0203HJ
Copyright © 2007 ARM Limited. All rights reserved.
2-31
組み込みソ フ ト ウ ェ アの開発
ま た、 一般的に、 コ ー ド と デー タ は TCM に分散 ロ ー ド さ れ る ため、 TCM も
__main への分岐の前 (通常は MMU ま たは MPU のセ ッ ト ア ッ プの前) に有効
にす る 必要があ り ます。 TCM が有効にな っ てい る 場合には、 TCM に よ っ てマ
ス ク さ れ る メ モ リ にア ク セ スす る 必要がない と い う こ と に注意す る 必要があ
り ます。
ま た、 __main への分岐の前にキ ャ ッ シ ュ が有効に さ れた場合は、 キ ャ ッ シ ュ
コ ヒ ーレ ン シに関す る 問題 も 発生 し ます。 __main の コ ー ド は、 実質的には命令
をデー タ と し て処理 し 、 コ ー ド 領域を ロ ー ド ア ド レ ス か ら 実行ア ド レ ス に コ
ピー し ます。 その結果、 一部の命令はデー タ キ ャ ッ シ ュ 内にキ ャ ッ シ ュ さ れ
る 可能性があ り 、 その場合、 こ れ ら の命令が命令パ ス か ら 見え な く な り ます。
こ の よ う な コ ヒ ーレ ン シの問題を回避す る には、 C ラ イ ブ ラ リ 初期化シーケ
ン ス の実行が完了 し た後にキ ャ ッ シ ュ を有効に し ます。
2.5.5
分散ロー ド と メ モ リ のセ ッ ト ア ッ プ
ROM/RAM の リ マ ッ プ ま たは MMU の設定のいずれかで リ セ ッ ト 時の コ アの
メ モ リ ビ ュ ーが変更 さ れ る シ ス テ ム では、 分散 ロ ー ド 記述フ ァ イ ルで リ マ ッ
プが実行 さ れた後の イ メ ージの メ モ リ マ ッ プ を記述す る 必要があ り ます。
例 2-9 に示す記述フ ァ イ ルは、 ROM/RAM の リ マ ッ プ (ページ 2-29) で示 し た
リ マ ッ プ後の例に関連 し てい ます。
例 2-9
ROM_LOAD 0x10000 0x8000
{
ROM_EXEC 0x10000 0x8000
{
reset_handler.o (+RO, +FIRST)
...
}
RAM 0x0000 0x4000
{
vectors.o (+RO, +FIRST)
; executed on hard reset
; vector table copied
; from ROM to RAM at zero
...
}
}
2-32
Copyright © 2007 ARM Limited. All rights reserved.
ARM DUI 0203HJ
組み込みソ フ ト ウ ェ アの開発
ロ ー ド 領域 ROM_LOAD は、 リ マ ッ プが行われた後の コ ー ド と デー タ の ロ ー ド ア
ド レ ス を示すため、 0x10000 に配置 さ れます。
2.5.6
ス タ ッ ク ポ イ ン タ の初期化
リ セ ッ ト ハン ド ラ は、 少な く と も 、 アプ リ ケーシ ョ ン で使用 さ れ る 実行モー
ド の ス タ ッ ク ポ イ ン タ に初期値を割 り 当て る 必要があ り ます。
例 2-10 では、 ス タ ッ ク が stack_base に配置 さ れ ます。 こ のシ ン ボルにはハー
ド コ ーデ ィ ン グ さ れた ア ド レ ス を指定す る こ と がで き ます。 ま たは、 別のア
セ ンブ ラ ソ ース フ ァ イ ルで定義 し 、 分散 ロ ー ド 記述フ ァ イ ルに よ っ て配置す
る こ と も で き ます。 こ の方法の詳細については、 『Linker and Utilities Guide』 の
分散 ロ ー ド 記述フ ァ イ ルを使用 し た ス タ ッ ク と ヒ ープの指定 (ページ 5-3) を
参照 し て下 さ い。
例 2-10 ス タ ッ ク ポ イ ン タ の初期化
Len_FIQ_Stack
EQU
256
Len_IRQ_Stack
EQU
256
:
Reset_Handler
:
; stack_base could be defined above, or located in a scatter file
LDR
r0, stack_base ;
; Enter each mode in turn and set up the stack pointer
MSR
CPSR_c, #Mode_FIQ:OR:I_Bit:OR:F_Bit
MOV
sp, r0
MSR
SUB
MOV
CPSR_c, #Mode_IRQ:OR:I_Bit:OR:F_Bit
r0, r0, #Len_FIQ_Stack
sp, r0
MSR
SUB
MOV
; Leave
CPSR_c, #Mode_SVC:OR:I_Bit:OR:F_Bit
r0, r0, #Len_IRQ_Stack
sp, r0
core in SVC mode
例 2-10 では、 FIQ モー ド お よ び IRQ モー ド に 256 バ イ ト の ス タ ッ ク を割 り 当
ててい ますが、 他の実行モー ド に も 同 じ よ う に割 り 当て る こ と がで き ます。
ス タ ッ ク ポ イ ン タ を セ ッ ト ア ッ プす る には、 割 り 込みを無効に し て各モー ド
に入 り 、 ス タ ッ ク ポ イ ン タ に適切な値を割 り 当て ます。
ARM DUI 0203HJ
Copyright © 2007 ARM Limited. All rights reserved.
2-33
組み込みソ フ ト ウ ェ アの開発
リ セ ッ ト ハン ド ラ でセ ッ ト ア ッ プ さ れ る ス タ ッ ク ポ イ ン タ の値は、 C ラ イ ブ
ラ リ 初期化 コ ー ド に よ り 、 パ ラ メ ー タ と し て __user_initial_stackheap() に自
動的に渡 さ れ ます。 そのため、 こ の値は __user_initial_stackheap() に よ っ て変
更す る こ と はで き ません。
例 2-11 は、 例 2-10 (ページ 2-33) で示 し た ス タ ッ ク ポ イ ン タ のセ ッ ト ア ッ プ
に使用で き る __user_initial_stackheap() の実装を示 し てい ます。
例 2-11
IMPORT heap_base
EXPORT __user_initial_stackheap
__user_initial_stackheap
; heap base could be hard-coded, or placed by description file
LDR
r0,=heap_base
; r1 contains SB value
BX
lr
2.5.7
ハー ド ウ ェ アの初期化
一般的には、 シ ス テ ム初期化 コ ー ド はすべて メ イ ン アプ リ ケーシ ョ ン か ら 切
り 離 し た方が有効です。 ただ し 、 キ ャ ッ シ ュ や割 り 込みの有効化な ど、 シ ス
テ ムの初期化のい く つかの コ ン ポーネ ン ト は、 C ラ イ ブ ラ リ 初期化 コ ー ド の
実行後に実行 さ れ る 必要があ り ます。
$Sub お よ び $Super と い う 関数 ラ ッ パシ ン ボルを使用す る と 、 メ イ ン アプ リ
ケーシ ョ ンに入 る 直前に実行 さ れ る ルーチン を (効果的に) 挿入で き ます。
こ の メ カ ニズ ム に よ り 、 ソ ース コ ー ド を変更す る こ と な く 、 関数を拡張で き
ます。
例 2-12 (ページ 2-35) は、 こ の $Sub お よ び $Super の使用方法を示 し てい ます。
リ ン カは、 main() への関数呼び出 し を、 $Sub$$main() への呼び出 し に置 き 換え
ます。 こ こ か ら キ ャ ッ シ ュ を有効にす る ルーチン と 割 り 込みを有効にす る 別
のルーチン を呼び出す こ と がで き ます。
こ の コ ー ド は、$Super$$main() を呼び出す こ と で、実際の main() に分岐 し ます。
2-34
Copyright © 2007 ARM Limited. All rights reserved.
ARM DUI 0203HJ
組み込みソ フ ト ウ ェ アの開発
注
詳細については、 『Linker and Utilities Guide』 の $Super$$ と $Sub$$ を使用 し た
シ ン ボル定義のオーバー ラ イ ド (ページ 4-22) を参照 し て下 さ い。
例 2-12 $Sub と $Super の使用方法
extern void $Super$$main(void);
void $Sub$$main(void)
{
cache_enable();
int_enable();
$Super$$main();
}
2.5.8
// enables caches
// enables interrupts
// calls original main()
実行モー ド に関する注意事項
メ イ ン アプ リ ケーシ ョ ン を ど のモー ド で実行す る か を検討す る 必要があ り ま
す。 選択す る モー ド に よ っ て、 シ ス テ ムの初期化の実装方法が異な り ます。
起動時に リ セ ッ ト ハン ド ラ お よ び $Sub$$main の両方で実装す る 可能性のあ る
多 く の機能は、 特権モー ド で実行す る 場合に し か使用で き ません。 例えば、
オ ンチ ッ プ メ モ リ の操作や割 り 込みの有効化な ど が挙げ ら れ ます。
アプ リ ケーシ ョ ン を特権モー ド で実行す る 場合、 こ れは問題にな り ません。
リ セ ッ ト ハン ド ラ を終了す る 前に適切なモー ド に変更す る よ う に し て下 さ い。
アプ リ ケーシ ョ ン を ユーザモー ド で実行す る 場合は、 必要な タ ス ク を特権
モー ド で実行 し た 後 に し かユーザモー ド に変更で き ません。 通常、 こ の変更
は $Sub$$main() で行われます。
注
__user_initial_stackheap() では、 アプ リ ケーシ ョ ン モー ド の ス タ ッ ク を セ ッ ト
ア ッ プす る 必要があ り ます。 こ のため、 ユーザモー ド レ ジ ス タ を使用す る 、
シ ス テ ム モー ド の リ セ ッ ト ハン ド ラ を終了す る 必要があ り ます。 その後、
__user_initial_stackheap() がシ ス テ ム モー ド で実行 さ れ る ため、 ユーザモー ド
に入っ た と き に も アプ リ ケーシ ョ ンの ス タ ッ ク と ヒ ープは ま だセ ッ ト ア ッ プ
さ れた状態を維持す る こ と がで き ます。
ARM DUI 0203HJ
Copyright © 2007 ARM Limited. All rights reserved.
2-35
組み込みソ フ ト ウ ェ アの開発
2.5.9
ビル ド 4 のサン プル コ ー ド
ビル ド 4 のサン プルは、 Integrator プ ラ ッ ト フ ォ ーム上で ス タ ン ド ア ロ ン で実
行で き ます。 こ のサ ンプルビル ド の フ ァ イ ルは、 メ イ ンサン プルデ ィ レ ク ト
リ ...\emb_sw_dev\build4 にあ り ます。
ビル ド 4 では、 ビル ド 3 のサン プルプ ロ ジ ェ ク ト に以下の変更が加え ら れて
い ます。
ベ ク タ テーブル
ベ ク タ テーブルがプ ロ ジ ェ ク ト に追加 さ れ、 分散 ロ ー ド 記述
フ ァ イ ルに よ っ て配置 さ れま し た。
リ セ ッ ト ハン ド ラ
リ セ ッ ト ハン ド ラ が init.s に追加 さ れ ま し た。 ARM926EJ-S™ の
ビル ド には、 TCM と MMU のセ ッ ト ア ッ プ を それぞれ行 う 2 つ
のモジ ュ ールが含まれてい ます。 こ れ ら のモジ ュ ールは、 任意の
コ ア を搭載 し た Integrator シ ス テ ム で実行 さ れ る ARM7TDMI® の
ビル ド には含ま れてい ません。 ROM/RAM の リ マ ッ プは、 リ セ ッ
ト の直後に行われ ます。
$Sub$$main()
ARM926EJ-S のビル ド では、 メ イ ン アプ リ ケーシ ョ ン に入 る 前
に、 キ ャ ッ シ ュ が $Sub$$main() 内で有効に さ れます。
組み込み記述フ ァ イ ル
リ マ ッ プ後の メ モ リ ビ ュ ーを反映す る 、 組み込み記述フ ァ イ ル
が使用 さ れてい ます。
こ れ ら の ビル ド 両方の ビル ド フ ァ イ ルでは、 ア ド レ ス 0x24000000 に存在す る
Integrator AP のアプ リ ケーシ ョ ン用フ ラ ッ シ ュ メ モ リ へのダ ウ ン ロ ー ド に適 し
たバ イ ナ リ フ ァ イ ルが生成 さ れ ます。
Integrator AP マザーボー ド 上の タ イ マ を使用 し て、 正確な タ イ マが実装 さ れて
い ます。 こ の タ イ マに よ っ て IRQ が生成 さ れ、 10 ミ リ 秒ご と にカ ウ ン タ を イ
ン ク リ メ ン ト す る ハン ド ラ が イ ン ス ト ール さ れ ます。
2-36
Copyright © 2007 ARM Limited. All rights reserved.
ARM DUI 0203HJ
組み込みソ フ ト ウ ェ アの開発
2.6
メ モ リ マ ッ プに関する その他の注意事項
こ れ ま でのセ ク シ ョ ン では、 分散 ロ ー ド 記述フ ァ イ ルでの コ ー ド と デー タ の
配置について説明 し て き ま し た。 ただ し 、 タ ーゲ ッ ト ハー ド ウ ェ アのペ リ
フ ェ ラ ルの位置 と 、 ス タ ッ ク リ ミ ッ ト と ヒ ープ リ ミ ッ ト は、 ソ ース フ ァ イ ル
ま たはヘ ッ ダ フ ァ イ ルでハー ド コ ーデ ィ ン グ さ れてい る こ と を前提 と し てい
ま し た。 タ ーゲ ッ ト の メ モ リ マ ッ プに関す る すべての情報を記述フ ァ イ ルに
保存 し て、 ソ ース コ ー ド か ら 絶対ア ド レ スへのすべての参照を削除す る こ と
をお勧め し ます。
2.6.1
分散ロー ド 記述 フ ァ イルでの タ ーゲ ッ ト のペ リ フ ェ ラ ルの配置
通常、 ペ リ フ ェ ラ ルレ ジ ス タ のア ド レ ス は、 プ ロ ジ ェ ク ト の ソ ース フ ァ イ ル
ま たはヘ ッ ダ フ ァ イ ルにハー ド コ ーデ ィ ン グ さ れてい ます。 ま た、 ペ リ フ ェ
ラ ルレ ジ ス タ にマ ッ プ さ れ る 構造体を宣言 し 、 こ れ ら の構造体を記述フ ァ イ
ルに配置す る こ と も で き ます。
例えば、 32 ビ ッ ト の メ モ リ マ ッ プ レ ジ ス タ を 2 つ使用す る タ イ マペ リ フ ェ ラ
ルが タ ーゲ ッ ト に実装 さ れてい る と し ます。 例 2-13 は、 こ れ ら の レ ジ ス タ に
マ ッ プ さ れ る C の構造体を示 し てい ます。
例 2-13 ペ リ フ ェ ラルレ ジ ス タ へのマ ッ プ
__attribute__ ((zero_init)) struct {
volatile unsigned ctrl;
volatile unsigned tmr;
} timer_regs;
/* timer control */
/* timer value
*/
こ の構造体を メ モ リ マ ッ プ内の特定のア ド レ ス に配置す る には、 こ の構造体
を保持す る 新 し い実行領域を作成 し ます。
例 2-14 (ページ 2-38) に示す記述フ ァ イ ルでは、 timer_regs 構造体が
0x40000000 に配置 さ れ ます。
レ ジ ス タ の内容は、 アプ リ ケーシ ョ ンの起動時にゼ ロ に初期化 し ない こ と が
重要です。 ゼ ロ に初期化 さ れ る と シ ス テ ムの状態が変更 さ れ る 場合があ り ま
す。 実行領域に UNINIT 属性を指定す る と 、 その領域内の ZI デー タ がゼ ロ で初
期化 さ れ る の を防 ぐ こ と がで き ます。
ARM DUI 0203HJ
Copyright © 2007 ARM Limited. All rights reserved.
2-37
組み込みソ フ ト ウ ェ アの開発
例 2-14 マ ッ プ さ れた構造体の配置
ROM_LOAD 0x24000000 0x04000000
{
; ...
TIMER 0x40000000 UNINIT
{
timer_regs.o (+ZI)
}
; ...
}
2.6.2
ビル ド 5 のサン プル コ ー ド
ビル ド 5 のサン プル コ ー ド はビル ド 4 と 同 じ ですが、 すべての タ ーゲ ッ ト メ
モ リ マ ッ プ情報が分散 ロ ー ド 記述フ ァ イ ルに記述 さ れてい ます。
分散 ロ ー ド 記述フ ァ イ ルのシ ン ボル
ス タ ッ ク 、 ヒ ープ、 お よ びペ リ フ ェ ラ ルを配置す る ためのシ ン
ボルがアセ ン ブ ラ モジ ュ ール内で宣言 さ れてい ます。
更新 さ れた分散 ロ ー ド 記述フ ァ イ ル
ビル ド 4 の組み込み記述フ ァ イ ルが、 ス タ ッ ク 、 ヒ ープ、 デー タ
TCM、 お よ びペ リ フ ェ ラ ルを配置す る よ う に更新 さ れてい ます。
こ のサン プルビル ド の フ ァ イ ルは、 メ イ ンサ ンプルデ ィ レ ク ト リ
...\emb_sw_dev\build5 にあ り ます。
2-38
Copyright © 2007 ARM Limited. All rights reserved.
ARM DUI 0203HJ
第 3章
位置非依存 コ ー ド と デー タ の記述
本章では、 ARM アーキ テ ク チ ャ 向けプ ロ シージ ャ コ ール標準 (AAPCS) を使
用す る 位置非依存 コ ー ド と デー タ を記述す る 方法について説明 し ます。 本章
は以下のセ ク シ ョ ン か ら 構成 さ れてい ます。
•
•
•
ARM DUI 0203HJ
位置非依存 (ページ 3-2)
読み出 し 専用の位置非依存 (ページ 3-4)
読み出 し - 書 き込みの位置非依存 (ページ 3-7)
Copyright © 2007 ARM Limited. All rights reserved.
3-1
位置非依存コ ー ド と デー タ の記述
3.1
位置非依存
ARM® 命令セ ッ ト お よ び Thumb® 命令セ ッ ト では、 ど ち ら も PC 相対命令 (例
えば、 BL) を使用す る こ と に よ っ て、 位置非依存 コ ー ド (つま り 、 再配置可
能な コ ー ド ) がサポー ト さ れます。
注
こ れは、 リ ン カに よ っ て作成 さ れ る イ メ ージの種類であ る 再配置可能な ELF
と は異な り ます。
再配置可能な アセ ンブ ラ コ ー ド を記述す る こ と はで き ますが、 コ ー ド にア ド
レ ス定数を含め る こ と はで き ません。 コ ー ド の参照に使用す る リ テ ラ ルア ド
レ ス は、 PC 相対のオ フ セ ッ ト であ る 必要があ り ます。 ア ド レ ス にア ク セ スす
る 前に、 ADD 命令を使用 し て PC が追加 さ れ ます。
コ ー ド と デー タ は、 ど ち ら も 位置非依存にす る こ と がで き ます。
•
コ ー ド を異な る ア ド レ ス で実行で き る よ う にす る には、 コ ー ド は位置非
依存 (再配置可能) であ る 必要があ り ます。 ただ し 、 コ ー ド か ら のア ク
セ ス は、 固定ア ド レ ス の ス タ テ ィ ッ ク デー タ に限定 さ れ ます。
•
位置非依存のデー タ では、 すべてのデー タ ア ク セ ス が、 ス タ テ ィ ッ ク
ベース レ ジ ス タ sb の相対位置で行われ る 必要があ り ます。 こ れは共有 ラ
イ ブ ラ リ メ カ ニ ズ ムの実装に使用 さ れ ます。
RVCT では、 C お よ びアセ ン ブ ラ 言語におけ る 位置非依存の コ ー ド と デー タ
をサポー ト し てお り 、 再配置可能ま たは再入可能な コ ー ド を記述す る こ と が
で き ます。 ただ し 、 C++ はサポー ト さ れてい ません。 本章の残 り の部分では、
こ の方法について説明 し ます。
詳細については、 以下を参照 し て下 さ い。
3-2
•
『コ ンパ イ ラ ユーザガ イ ド 』 の 位置非依存修飾子 (ページ 2-27)
•
『 ラ イ ブ ラ リ / 浮動小数点サポー ト ガ イ ド 』 の 再入可能お よ びス レ ッ ド
セーフ コー ド の記述 (ページ 2-5)
Copyright © 2007 ARM Limited. All rights reserved.
ARM DUI 0203HJ
位置非依存コ ー ド と デー タ の記述
3.1.1
AAPCS の使用
ARM アーキ テ ク チ ャ 向けプ ロ シージ ャ コール標準 (AAPCS) は、 ARM アー
キ テ ク チ ャ のアプ リ ケーシ ョ ンバ イ ナ リ イ ン タ フ ェ ース (ABI) (Base
Standard) (BSABI) 仕様の一部です。 AAPCS に準拠 し た コ ー ド を記述す る
と 、 別々に コ ンパ イ ルお よ びアセ ン ブル し たモジ ュ ールを連動 さ せ る こ と が
で き ます。
詳細については、 install_directory\Documentation\... にあ る AAPCS 仕様を参
照 し て下 さ い。
ARM DUI 0203HJ
Copyright © 2007 ARM Limited. All rights reserved.
3-3
位置非依存コ ー ド と デー タ の記述
3.2
読み出 し 専用の位置非依存
プ ロ グ ラ ムのすべての読み出 し 専用セ グ メ ン ト が位置非依存であ る 場合、 そ
のプ ロ グ ラ ムは読み出 し 専用の位置非依存 (ROPI) と な り ます。
ROPI セ グ メ ン ト は、 位置非依存 コー ド (PIC) であ る こ と が多い も のの、 読
み出 し 専用デー タ であ る こ と も あれば、 PIC と 読み出 し 専用デー タ の組み合
わせであ る こ と も あ り ます。
注
ROPI では C++ がサポー ト さ れないため、 ROPI は AAPCS の一部ではあ り ま
せん。 ただ し 、 ROPI の C コ ー ド ま たはアセ ン ブ ラ コ ー ド は、 コ ンパ イ ラ ま た
はアセ ン ブ ラ のオプシ ョ ン --apcs /ropi を使用 し て コ ンパ イ ルす る こ と がで き
ます。
コ ー ド を メ モ リ 内の特定の場所に ロ ー ド し な く て も 済む よ う にす る には、
ROPI オプシ ョ ン を選択 し ます。 こ のオプシ ョ ンは、 以下のルーチン に使用す
る と 特に便利です。
3.2.1
•
ラ ン タ イ ム イ ベン ト に対応 し て ロ ー ド さ れ る ルーチン
•
状況に よ っ て他のルーチン と の さ ま ざ ま な組み合わせで メ モ リ に ロ ー ド
さ れ る ルーチン
•
実行中に別のア ド レ ス にマ ッ プ さ れ る ルーチン
ROPI に関連する レ ジ ス タ の使用方法
AAPCS で定義 さ れてい る よ う に、 ROPI の有無に関係な く 、 レ ジ ス タ の使用
方法は同 じ です。
詳細については、 install_directory\Documentation\Specifications\... にあ る
『Procedure Call Standard for the ARM Architecture』 (aapcs.pdf) を参照 し て下 さ
い。
3-4
Copyright © 2007 ARM Limited. All rights reserved.
ARM DUI 0203HJ
位置非依存コ ー ド と デー タ の記述
3.2.2
ROPI の C コ ー ド お よびアセ ン ブ ラ コ ー ド の記述
ROPI の C コ ー ド と アセ ン ブ ラ コ ー ド を記述す る 場合、 以下の よ う な要件があ
り ます。
•
ROPI セグ メ ン ト 内の コ ー ド か ら 、 同一 ROPI セ グ メ ン ト 内のシ ン ボルへ
の参照は、 PC 相対で行 う 必要があ り ます。 AAPCS では、 読み出 し 専用
セ グ メ ン ト 用の他のベース レ ジ ス タ は定義 さ れてい ません。 あ る ROPI
セグ メ ン ト に含まれ る 項目のア ド レ ス を、 別の ROPI セグ メ ン ト の項目
に割 り 当て る こ と はで き ません。
•
ROPI セグ メ ン ト 内の コ ー ド か ら 、 異な る ROPI セグ メ ン ト 内のシ ン ボル
への参照は、 PC 相対で行 う 必要があ り ます。 こ の よ う な 2 つのセグ メ ン
ト は、 互いに一定の相対位置 と な る よ う にす る 必要があ り ます。
•
他の ROPI セグ メ ン ト か ら の参照は、 以下の ど ち ら か を指 し てい る 必要
があ り ます。
•
3.2.3
—
絶対ア ド レ ス
—
書 き 込み可能デー タ への sb- 相対参照。 読み出 し - 書 き 込みの位置
非依存 (ページ 3-7) を参照 し て下 さ い。
ROPI セグ メ ン ト 内のシ ン ボルを ア ド レ ス指定す る 読み出 し - 書 き 込み
ワー ド は、 その ROPI セ グ メ ン ト が移動す る たびに調整す る 必要があ り
ます。
コー ドのリ ン ク
リ ン カの コ マ ン ド ラ イ ン オプシ ョ ン --ropi を使用す る と 、 読み出 し 専用の出
力セ ク シ ョ ン を含む ロ ー ド お よ び実行領域が位置非依存にな り ます。 読み出
し 専用の入力セ ク シ ョ ンは、 読み出 し 専用の位置非依存にす る 必要があ り ま
す。 詳細については、 『 リ ン カ / ユーテ ィ リ テ ィ ガ イ ド 』 を参照 し て下 さ い。
3.2.4
FPIC ア ド レ ス指定
/fpic 修飾子を使用す る と 、 相対ア ド レ ス参照がプ ロ グ ラ ム を ロ ー ド し た場所
に依存 し ない、 読み出 し 専用の位置非依存 コ ー ド が生成 さ れ ます。 コ ー ド で
System V の共有 ラ イ ブ ラ リ を使用 し てい る 場合にのみ、 相対ア ド レ ス が実装
さ れ ます。 コ ー ド で共有オブジ ェ ク ト を使用 し てい る 場合、 /fpic を指定 し て
コ ンパ イ ルす る 必要はあ り ません。
ARM DUI 0203HJ
Copyright © 2007 ARM Limited. All rights reserved.
3-5
位置非依存コ ー ド と デー タ の記述
RVCT でサポー ト さ れてい る System V 共有 ラ イ ブ ラ リ の詳細については、 『 リ
ン カ / ユーテ ィ リ テ ィ ガ イ ド 』 の 「第 6 章 BPABI お よ び System V の共有 ラ イ
ブ ラ リ と 実行可能フ ァ イ ル」 を参照 し て下 さ い。
3.2.5
サン プル コ ー ド
位置非依存 コ ー ド の記述の詳細については、 RealView Development Suite に付
属の PIC-PID サン プルを参照 し て下 さ い。 こ のサ ンプルは、 メ イ ンサ ンプル
デ ィ レ ク ト リ の install_directory\RVDS\Examples\picpid にあ り ます。
こ のサン プルは、 ROM の固定ア ド レ ス にあ る カーネル と 、 カーネルの機能を
拡張す る 各種アプ リ ケーシ ョ ン モジ ュ ールで構成 さ れてい ます。 アプ リ ケー
シ ョ ン モジ ュ ールは、 カーネルに従っ て メ モ リ に ロ ー ド さ れます。 ただ し 、
モジ ュ ールの リ ン ク 時に、 モジ ュ ールが ロ ー ド さ れ る ア ド レ ス は不明です。
つま り 、 モジ ュ ールは、 位置非依存 (ROPI、 PIC) であ る 必要があ り ます。
サン プルには、 ソ ース コ ー ド 、 メ ー ク フ ァ イ ル、 バ ッ チ フ ァ イ ル、 お よ び別
のモジ ュ ールを コ ンパ イ ル し た り リ ン ク し た り す る 方法の詳細が含まれてい
ます。 readme.txt を参照 し て下 さ い。
3-6
Copyright © 2007 ARM Limited. All rights reserved.
ARM DUI 0203HJ
位置非依存コ ー ド と デー タ の記述
3.3
読み出 し - 書き込みの位置非依存
プ ロ グ ラ ムのすべての読み出 し - 書 き 込みセ グ メ ン ト が位置非依存であ る 場
合、 そのプ ロ グ ラ ムは読み出 し - 書 き込みの位置非依存 (RWPI) と な り ま
す。
通常、 RWPI セ グ メ ン ト は位置非依存デー タ (PID) です。
RWPI は AAPCS のバ リ ア ン ト です。 コ ンパ イ ラ ま たはアセ ン ブ ラ のオプシ ョ
ン --apcs /rwpi を選択す る こ と に よ り 、 デー タ の メ モ リ 位置を決め る 必要がな
く な り ます。 こ の方法は、 再入可能ルーチン で何度 も イ ン ス タ ン ス を生成 し
なければな ら ないデー タ に使用す る と 、 特に便利です。
詳細については、 install_directory\Documentation\Specifications\... にあ る
『Procedure Call Standard for the ARM Architecture』 (aapcs.pdf) を参照 し て下 さ
い。
3.3.1
再入可能ルーチ ン
再入可能ルーチンは、 同時に複数のプ ロ セ ス で ス レ ッ ド 化 で き ます。 各プ ロ
セ ス には、 再入可能ルーチンの読み出 し - 書 き 込みセグ メ ン ト の コ ピーが保
持 さ れてい ます。 各 コ ピーは、 それぞれ異な る 値の ス タ テ ィ ッ ク ベース レ ジ
ス タ sb でア ド レ ス指定 さ れ ます。
3.3.2
RWPI に関連する レ ジ ス タ の使用方法
レ ジ ス タ r9 は、 ス タ テ ィ ッ ク ベース レ ジ ス タ sb です。 こ の レ ジ ス タ は、 外部
か ら 参照で き る ルーチンが呼び出 さ れ る と き に、 常に適切な ス タ テ ィ ッ ク
デー タ セ グ メ ン ト のベース ア ド レ ス を指 し てい る 必要があ り ます。
sb を使用 し ないルーチン では、 r9 を他の目的に使用す る こ と も で き ます。 こ
の場合は、 sb の内容をルーチンへのエ ン ト リ で保存 し 、 終了前に復元す る 必
要があ り ます。 ま た、 sb の内容は、 外部ルーチンへの呼び出 し が発生す る 前
に復元す る 必要があ り ます。
それ以外の点では、 RWPI の有無に関係な く 、 レ ジ ス タ の使用方法は同 じ で
す。
ARM DUI 0203HJ
Copyright © 2007 ARM Limited. All rights reserved.
3-7
位置非依存コ ー ド と デー タ の記述
3.3.3
位置非依存デー タ のア ド レ ス指定
RWPI セグ メ ン ト は、 ま だ使用 さ れていない間であれば再配置で き ます。
RWPI セグ メ ン ト 内のシ ン ボルのア ド レ ス は、 以下の よ う に計算 さ れます。
3.3.4
1.
リ ン カに よ っ て、 セ グ メ ン ト 内の固定位置か ら の読み出 し 専用オ フ セ ッ
ト が計算 さ れます。 便宜的に、 こ の固定位置は、 プ ロ グ ラ ムの中で最下
位ア ド レ ス が指定 さ れた RWPI セグ メ ン ト の先頭バ イ ト の位置にな り ま
す。
2.
実行時に、 こ の読み出 し 専用オ フ セ ッ ト が、 ス タ テ ィ ッ ク ベース レ ジ ス
タ sb の内容に加算 さ れ る オ フ セ ッ ト と し て使用 さ れます。
ア セ ン ブ リ 言語を使用 し た RWPI の記述
読み出 し 専用セグ メ ン ト か ら RWPI セグ メ ン ト への参照は、 sb の値を固定の
読み出 し 専用オ フ セ ッ ト に加算す る こ と に よ っ て計算 さ れます。 『アセ ンブ ラ
ガ イ ド 』 の 「デ ィ レ ク テ ィ ブ リ フ ァ レ ン ス」 の章にあ る 「DCDO」 を参照 し て下
さ い。
3.3.5
コー ドのリ ン ク
リ ン カの コ マ ン ド ラ イ ン オプシ ョ ン --rwpi を使用す る と 、 RW 出力セ ク シ ョ
ンお よ び ZI 出力セ ク シ ョ ン を含む ロ ー ド お よ び実行領域が位置非依存にな り
ます。 こ のオプシ ョ ンには、--rw-base の値が必要です。 --rw-base を指定 し ない
と 、--rw-base 0 を指定 し た と 見な さ れ ます。 通常、 書 き 込み可能な入力セ ク
シ ョ ンは、 RWPI にす る 必要があ り ます。 詳細については、 『 リ ン カ / ユーテ ィ
リ テ ィ ガ イ ド 』 の イ メ ージの メ モ リ マ ッ プ情報の指定 (ページ 2-13) を参照
し て下 さ い。
3.3.6
サン プル コ ー ド
位置非依存 コ ー ド の記述の詳細については、 RealView Development Suite に付
属の PIC-PID サン プルを参照 し て下 さ い。 こ のサ ンプルは、 メ イ ンサ ンプル
デ ィ レ ク ト リ の install_directory\RVDS\Examples\picpid にあ り ます。
こ のサン プルは、 ROM の固定ア ド レ ス にあ る カーネル と 、 カーネルの機能を
拡張す る 各種アプ リ ケーシ ョ ン モジ ュ ールで構成 さ れてい ます。 モジ ュ ール
は、 イ ン ス タ ン ス を複数生成で き て、 カーネルを経由 し て相互に呼び出 し 可
能な名前付 き サービ ス を実装 し てい ます。 サービ ス が呼び出 さ れ る と 、 カー
ネルは、 ス タ テ ィ ッ ク デー タ の イ ン ス タ ン ス を作成 し 、 サービ ス に制御を移
3-8
Copyright © 2007 ARM Limited. All rights reserved.
ARM DUI 0203HJ
位置非依存コ ー ド と デー タ の記述
し ます。 ただ し 、 その後、 サービ ス か ら カーネルを呼び出す こ と があ り ます。
つま り 、 モジ ュ ールは、 位置非依存デー タ の RWPI、 PID を保持 し てい る 必要
があ り ます。
サ ンプルには、 ソ ース コ ー ド 、 メ ー ク フ ァ イ ル、 バ ッ チフ ァ イ ル、 お よ び別
のモジ ュ ールを コ ンパ イ ル し た り リ ン ク し た り す る 方法の詳細が含ま れてい
ます。 readme.txt を参照 し て下 さ い。
ARM DUI 0203HJ
Copyright © 2007 ARM Limited. All rights reserved.
3-9
位置非依存コ ー ド と デー タ の記述
3-10
Copyright © 2007 ARM Limited. All rights reserved.
ARM DUI 0203HJ
第 4章
ARM と Thumb のイ ン タ ーワー ク
本章では、 Thumb 命令セ ッ ト を実装す る プ ロ セ ッ サ用の コ ー ド を記述す る 際
に ARM® 状態 と Thumb® 状態を切 り 替え る 方法について説明 し ます。 本章は以
下のセ ク シ ョ ン か ら 構成 さ れてい ます。
イ ン タ ーワー ク について (ページ 4-2)
•
•
•
•
ARM DUI 0203HJ
アセ ンブ リ 言語の イ ン タ ーワー ク (ページ 4-8)
C と C++ の イ ン タ ーワー ク と ベニ ア (ページ 4-14)
ベニア を使用 し た アセ ンブ リ 言語の イ ン タ ーワー ク (ページ 4-19)
Copyright © 2007 ARM Limited. All rights reserved.
4-1
ARM と Thumb のイ ン タ ーワー ク
4.1
イ ン タ ーワー ク について
イ ン タ ー ワー ク を使用す る と 、 ARM コ ー ド と Thumb コ ー ド を混用す る こ と
に よ り 、 以下の動作を実現で き ます。
•
ARM ルーチン か ら Thumb 状態の発呼側への復帰
•
Thumb ルーチン か ら ARM 状態の発呼側への復帰
つま り 、 イ ン タ ー ワ ー ク 用の コ ー ド を コ ンパ イ ルま たはアセ ン ブル し た場合、
モジ ュ ールで使用 さ れ る 命令セ ッ ト を考慮す る こ と な く 、 コ ー ド か ら 異な る
モジ ュ ールのルーチン を呼び出す こ と がで き ます。
ARM リ ン カでは、 ARM 関数がいつ Thumb 状態か ら 呼び出 さ れ、 Thumb 関数
がいつ ARM 状態か ら 呼び出 さ れ る のか を検出 し ます。 ま た ARM リ ン カでは、
必要に応 じ て、 呼び出 し 命令 と 復帰命令を変更す る か、 ま たはベニア と 呼ば
れ る 小 さ な コ ー ド セ グ メ ン ト を挿入す る こ と に よ っ て、 プ ロ セ ッ サ状態を変
更 し ます。
ARMv5T 以降のアーキ テ ク チ ャ では、 特別な命令を使用 し な く て も プ ロ セ ッ
サ状態を変更で き ます。 通常、 ARMv5T プ ロ セ ッ サでは イ ン タ ー ワー ク に よ
る オーバーヘ ッ ド はあ り ません。
注
ARMv5T 以降のアーキ テ ク チ ャ 用の コ ンパ イ ルは イ ン タ ー ワ ー ク を前提 と し
てお り 、 常に イ ン タ ー ワー ク を行 う コ ー ド を生成 し ます。 ただ し 、 ARMv5TE
用にビル ド さ れた アセ ン ブ リ コ ー ド は イ ン タ ー ワ ー ク を前提 と し ていないた
め、--apcs /interwork アセ ン ブ ラ オプシ ョ ン を使用 し て アセ ンブ リ コ ー ド を ビ
ル ド す る 必要があ り ます。
4.1.1
AAPCS の使用
ARM コ ー ド と Thumb コ ー ド は、 AAPCS の要件に準拠 し ていれば、 自由に混
在 さ せ る こ と がで き ます。 詳細については、
install_directory\Documentation\Specifications\... にあ る 『Procedure Call
Standard for the ARM Architecture』 (aapcs.pdf) を参照 し て下 さ い。
ARM アセ ンブ リ 言語モジ ュ ールを記述す る 場合は、 AAPCS に準拠 し た コ ー
ド を記述す る 必要があ り ます。 複数の ソ ース フ ァ イ ルを リ ン ク す る 場合は、
すべての フ ァ イ ルで互換性のあ る AAPCS オプシ ョ ン を使用す る 必要があ り
ます。 互換性のないオプシ ョ ン が検出 さ れ る と 、 リ ン カに よ っ てエ ラ ー メ ッ
セージが生成 さ れます。
4-2
Copyright © 2007 ARM Limited. All rights reserved.
ARM DUI 0203HJ
ARM と Thumb のイ ン タ ーワー ク
4.1.2
イ ン タ ーワー ク に適 し た状況
Thumb 命令をサポー ト す る ARM プ ロ セ ッ サ用の コ ー ド を記述す る 場合、 ア
プ リ ケーシ ョ ンの大部分が Thumb 状態で実行 さ れ る よ う に記述す る こ と がほ
と ん ど です。 こ の方法を使用す る と 、 コ ー ド 密度を最大限に向上 さ せ る こ と
がで き ます。 さ ら に、 8 ビ ッ ト 幅ま たは 16 ビ ッ ト 幅の メ モ リ を使用す る こ と
で最高のパフ ォ ーマ ン ス を得 る こ と がで き ます。 し か し 、 以下の よ う な理由
で、 アプ リ ケーシ ョ ンの一部を ARM 状態で実行す る 場合 も 考え ら れます。
速度
アプ リ ケーシ ョ ン には、 速度が重要にな る 部分があ り ます。 こ の
よ う なセ ク シ ョ ンは、 Thumb 状態 よ り も ARM 状態で実行 し た方
が効率的な場合があ り ます。 状況に よ っ ては、 1 つの ARM 命令
で、 等価な Thumb 命令を使用す る よ り も 多 く の処理を行 う こ と
がで き ます。
例えば、 小容量の高速 32 ビ ッ ト メ モ リ を実装 し てい る シ ス テ ム
があ る と し ます。 こ の メ モ リ か ら ARM コ ー ド を実行す る 場合、8
ビ ッ ト ま たは 16 ビ ッ ト の メ モ リ か ら 各命令を フ ェ ッ チす る こ と
に よ る オーバーヘ ッ ド が発生せずに済みます。
機能
Thumb 命令は、 等価な ARM 命令に比べ る と 柔軟性の点で劣 り ま
す。 ま た、 操作に よ っ ては Thumb 状態では実行で き ない も の も
あ り ます。 以下の操作を実行す る には、 ARM 状態に切 り 替え る
必要があ り ます。
•
割 り 込みの有効や無効お よ びモー ド の切 り 替え を行 う ため
の CPSR へのア ク セ ス
•
コ プ ロ セ ッ サへのア ク セ ス
•
C でサポー ト さ れていない DSP 演算命令
例外処理
プ ロ セ ッ サ例外が発生す る と 、 プ ロ セ ッ サは自動的に ARM 状態
に移行 し ます。 つま り 、 例外ハン ド ラ が後で Thumb 状態に移行
し て例外の メ イ ン処理を実行す る 場合で も 、 こ の例外ハン ド ラ
の最初の部分は ARM 命令で コ ーデ ィ ン グす る 必要があ り ます。
こ の よ う な処理の最後にハン ド ラ か ら メ イ ン アプ リ ケーシ ョ ン
に戻 る には、 プ ロ セ ッ サは ARM 状態に戻 る 必要があ り ます。
ARM DUI 0203HJ
Copyright © 2007 ARM Limited. All rights reserved.
4-3
ARM と Thumb のイ ン タ ーワー ク
ス タ ン ド ア ロ ン の Thumb プ ロ グ ラ ム
Thumb 命令をサポー ト す る ARM プ ロ セ ッ サは、 常に ARM 状態
で起動 し ます。 デバ ッ ガで単純な Thumb アセ ン ブ リ 言語プ ロ グ
ラ ム を実行す る には、 Thumb 状態への切 り 替え を実行 し てか ら
メ イ ン Thumb ルーチン を呼び出す ARM ヘ ッ ダ を追加す る 必要
があ り ます。 こ の例については、 ARM ヘ ッ ダのサンプル (ペー
ジ 4-10) を参照 し て下 さ い。
4.1.3
/interwork オプ シ ョ ンの使用
ARM コ ンパ イ ラ お よ びアセ ン ブ ラ には、--apcs /interwork オプシ ョ ン を使用で
き ます。 こ のオプシ ョ ン を設定 し た場合、 以下の よ う にな り ます。
•
コ ンパ イ ラ ま たはアセ ン ブ ラ に よ っ て、 イ ン タ ー ワー ク 属性がオブジ ェ
ク ト フ ァ イ ル内に記録 さ れます。
•
リ ン カに よ っ て、 サブルーチン エ ン ト リ に イ ン タ ーワ ー ク ベニ アが挿入
さ れ ます。
•
アセ ンブ リ 言語では、 発呼側の命令セ ッ ト 状態に復帰す る BX lr な ど の
関数終了 コ ー ド を記述す る 必要があ り ます。
•
C ま たは C++ では、 コ ンパ イ ラ に よ っ て発呼側の命令セ ッ ト 状態に復帰
す る 関数終了 コ ー ド が生成 さ れ ます。
•
C ま たは C++ では、 コ ンパ イ ラ に よ っ て間接呼び出 し ま たは仮想呼び出
し に BX 命令が使用 さ れます。
オブジ ェ ク ト フ ァ イ ルに以下のサブルーチンが含ま れてい る 場合は、--apcs
/interwork オプシ ョ ン を使用 し て下 さ い。
4-4
•
ARM コ ー ド に復帰す る 必要が生 じ る 可能性のあ る Thumb サブルーチン
•
Thumb コ ー ド に復帰す る 必要が生 じ る 可能性のあ る ARM サブルーチン
•
ARM コ ー ド の間接呼び出 し ま たは仮想呼び出 し を行 う 可能性のあ る
Thumb サブルーチン
•
Thumb コ ー ド の間接呼び出 し ま たは仮想呼び出 し を行 う 可能性のあ る
ARM サブルーチン
Copyright © 2007 ARM Limited. All rights reserved.
ARM DUI 0203HJ
ARM と Thumb のイ ン タ ーワー ク
注
モジ ュ ールの中に、 #pragma arm ま たは #pragma thumb でマー ク さ れた関数が含
まれてい る 場合は、--apcs /interwork を使用 し てそのモジ ュ ールを コ ンパ イ ル
す る 必要があ り ます。 こ れに よ り 、 関数を他方の状態か ら 正常に呼び出す こ
と がで き ます。
上記のサブルーチン が含まれていなければ、 /interwork オプシ ョ ン を使用す る
必要はあ り ません。 例えば、 オブジ ェ ク ト フ ァ イ ルは、 /interwork を必要 と せ
ず、 以下の コ ー ド で構成す る こ と がで き ます。
4.1.4
•
例外に よ る 割 り 込みが可能な Thumb コ ー ド 。 例外に よ っ てプ ロ セ ッ サが
ARM 状態に切 り 替わ る ため、 ベニ アは必要あ り ません。
•
Thumb コ ー ド か ら 例外を処理す る こ と が可能な例外処理 コ ー ド 。 こ の
コ ー ド の復帰にベニ アは必要あ り ません。
イ ン タ ーワー ク呼び出 し の検出
リ ン カでは、 直接的な ARM/Thumb イ ン タ ー ワ ー ク 呼び出 し を検出 し た と き
に、 被発呼側のルーチンが イ ン タ ー ワ ー ク 用に ビル ド さ れていない と エ ラ ー
を生成 し ます。 こ の場合、 呼び出 さ れ る 側のルーチン を イ ン タ ー ワー ク 用に
再ビル ド す る 必要があ り ます。
例 4-3 (ページ 4-15) の ARM ルーチン を、--apcs /interwork オプシ ョ ン を指定
せずに コ ンパ イ ルお よ び リ ン ク し た場合、 例 4-1 に示すエ ラ ーが生成 さ れま
す。
例 4-1
Error: L6239E: Cannot call ARM symbol 'arm_function' in non-interworking object
armsub.o from THUMB code in thumbmain.o(.text)
こ の よ う なエ ラ ーは、 ARM か ら Thumb、 ま たは Thumb か ら ARM への イ ン
タ ー ワー ク 呼び出 し が、 そのルーチンのシ ン ボル と は異な る オブジ ェ ク ト モ
ジ ュ ールか ら 検出 さ れたに も かかわ ら ず、 呼び出 さ れ る 側のルーチン が イ ン
タ ー ワー ク 用に コ ンパ イ ル さ れていない こ と を示 し ます。 こ の場合は、--apcs
/interwork を指定 し て、 こ のシ ン ボルを含むモジ ュ ールを再 コ ンパ イ ルす る 必
要があ り ます。
ARM DUI 0203HJ
Copyright © 2007 ARM Limited. All rights reserved.
4-5
ARM と Thumb のイ ン タ ーワー ク
4.1.5
リ ン カ に よ っ て生成 さ れる ベニ ア
ベニ アは、 分岐で以下が必要 と な る 場合に、 リ ン カに よ っ て自動的に挿入 さ
れ る 小 さ な コ ー ド セ グ メ ン ト です。
•
状態の切 り 替え
•
分岐命令の範囲内に収ま ら ない分岐先
ベニ アは、 次に タ ーゲ ッ ト ア ド レ ス に分岐す る 、 元の分岐の タ ーゲ ッ ト にな
り ます。
リ ン カでは、 以前の呼び出 し で生成 さ れたベニ ア を、 その後の同 じ 関数の呼
び出 し で再利用で き ます。 ただ し 、 ど ち ら のセ ク シ ョ ン か ら も それ ら の呼び
出 し に到達で き る 必要があ り ます。
ベニ ア と の イ ン タ ー ワー ク の詳細については、 以下を参照 し て下 さ い。
•
C と C++ の イ ン タ ーワー ク と ベニア (ページ 4-14)
•
ベニア を使用 し た アセ ンブ リ 言語の イ ン タ ーワー ク (ページ 4-19)
ベニアの型
ベニ アの型を以下に示 し ます。
long
任意の状態の切 り 替え を含め る こ と がで き ます。
short
状態の切 り 替えのみを実行 し ます。
inline
状態の切 り 替えのみを実行 し ますが、 ベニ アが挿入 さ れ る 関数
の先頭に追加 さ れ ます。
Veneer$$Code セ ク シ ョ ン
リ ン カでは、 ベニ ア ご と に Veneer$$Code と い う 入力セ ク シ ョ ン を作成 し ます。
*(Veneer$$Code) を使用す る と 、 分散 ロ ー ド 記述フ ァ イ ルにベニ ア コ ー ド を配
置で き ます。 ただ し 安全でない場合、 リ ン カはベニ ア コ ー ド を配置 し ません。
実行領域のア ド レ ス範囲やサ イ ズ制限に よ り 、 ベニ ア入力セ ク シ ョ ン を領域
に割 り 当て る こ と がで き ない場合があ り ます。 指定 し た領域にベニ ア を追加
で き ない場合は、 ベニ ア を生成 し た、 再配置 さ れた入力セ ク シ ョ ン を含んで
い る 実行領域にそのベニ アが追加 さ れ ます。
詳細については、 『Linker and Utilities Guide』 を参照 し て下 さ い。
4-6
Copyright © 2007 ARM Limited. All rights reserved.
ARM DUI 0203HJ
ARM と Thumb のイ ン タ ーワー ク
使用する ベニ ア数の削減
以下の こ と に注意す る と 、 使用す る ベニ アの数を最小限に抑え る こ と がで き
ます。
•
呼び出 さ れた側の関数が呼び出 し 元の範囲内に収ま る よ う に メ モ リ マ ッ
プ を構築 し ます。
•
範囲内の関数を繰 り 返 し 呼び出す こ と に よ っ てベニ ア を共有す る よ う に
し ます。
•
状態の切 り 替え を最小限に抑え ます。
ARM DUI 0203HJ
Copyright © 2007 ARM Limited. All rights reserved.
4-7
ARM と Thumb のイ ン タ ーワー ク
4.2
アセ ン ブ リ 言語のイ ン タ ーワー ク
アセ ン ブ リ 言語の ソ ース フ ァ イ ルには、 い く つかのエ リ ア を設け る こ と がで
き ます。 こ れ ら のエ リ アは ELF セ ク シ ョ ンに対応 し てい ます。 各エ リ アは、
ARM 命令 と Thumb 命令の一方ま たは両方を保持で き ます。
リ ン カ を使用 し て、 呼び出 し 元 と は異な る 命令セ ッ ト を使用す る ルーチン と
の間の呼び出 し を設定で き ます。 こ れを行 う には、 BL を使用 し てルーチン を
呼び出 し ます (ベニア を使用 し た アセ ンブ リ 言語の イ ン タ ーワー ク (ページ
4-19) 参照)。
必要であれば、 命令セ ッ ト を明示的に変更す る コ ー ド を記述す る こ と も で き
ます。 状況に よ っ ては、 こ の方法で、 サ イ ズが小 さ い コ ー ド や実行速度が速
い コ ー ド を記述で き ます。
プ ロ セ ッ サ状態の切 り 替え を行 う 命令は以下の と お り です。
•
BX (「分岐命令 と 切 り 替え命令」 参照)
•
BLX, LDR、 LDM、 お よ び POP (ARM
アーキ テ ク チ ャ v5T 以降 と の イ ン タ ー
ワー ク (ページ 4-12) 参照)
ARM お よ び THUMB デ ィ レ ク テ ィ ブ を使用 し て、 適切な命令セ ッ ト の命令を アセ
ン ブルす る よ う アセ ン ブ ラ に指定で き ます ( アセ ンブ ラ モー ド の変更 (ペー
ジ 4-9) 参照)。
4.2.1
分岐命令 と 切 り 替え命令
BX 命令は、 Thumb を サポー ト す る コ アでのみ使用で き ます。 こ の命令は、 指
定 し た レ ジ ス タ に含ま れてい る ア ド レ ス に分岐 し ます。 ア ド レ ス範囲は 4GB
です。 こ の分岐ア ド レ ス のビ ッ ト 0 の値に よ り 、 ARM 状態 と Thumb 状態の ど
ち ら で実行を継続す る かが決定 さ れ ます。 ARMv5 で使用で き る その他の命令
については、 ARM アーキ テ ク チ ャ v5T 以降 と の イ ン タ ーワー ク (ページ
4-12) を参照 し て下 さ い。
ア ド レ ス のビ ッ ト 0 を こ の方法で使用で き る のは、 以下の理由に よ り ます。
4-8
•
すべての ARM 命令が ワ ー ド 境界で整列 さ れ る ため、 ど の ARM 命令で
も ア ド レ ス の ビ ッ ト 0 と ビ ッ ト 1 は使用 さ れない。
•
すべての Thumb 命令がハーフ ワ ー ド 境界で整列 さ れ る ため、 Thumb 命
令ではア ド レ ス のビ ッ ト 0 は使用 さ れない。
Copyright © 2007 ARM Limited. All rights reserved.
ARM DUI 0203HJ
ARM と Thumb のイ ン タ ーワー ク
構文
BX の構文には以下のいずれか を使用 し ます。
Thumb
BX Rn
ARM
BX{cond} Rn
各引数には以下の意味があ り ます。
r0 ~ r15 の中で、 分岐先のア ド レ ス を保持す る レ ジ ス タ を指定
し ます。 こ の レ ジ ス タ のビ ッ ト 0 の値に よ っ て、 プ ロ セ ッ サ状態
が以下の よ う に決定 さ れます。
Rn
ビ ッ ト 0 が設定 さ れてい る 場合は、 分岐ア ド レ ス にあ る 命
令が Thumb 状態で実行 さ れ ます。
•
ビ ッ ト 0 が ク リ ア さ れてい る 場合は、 分岐ア ド レ ス にあ る
命令が ARM 状態で実行 さ れ ます。
任意の条件 コ ー ド を指定 し ます。 条件実行で き る のは ARM バー
ジ ョ ン の BX のみです。
cond
4.2.2
•
アセ ン ブ ラ モー ド の変更
ARM アセ ン ブ ラ では、 Thumb コ ー ド と ARM コ ー ド の両方を アセ ン ブルで き
ます。 --thumb オプシ ョ ン を指定 し て呼び出 さ ない限 り 、 アセ ンブ ラ はデフ ォ
ル ト で ARM コ ー ド を アセ ン ブル し ます。
Thumb を サポー ト す る ARM プ ロ セ ッ サは ARM 状態で起動 さ れ る ため、 BX 命
令を使用 し て Thumb 状態への分岐 と 切 り 替え を行い、 以下のアセ ン ブ ラ デ ィ
レ ク テ ィ ブ を使用 し て、 アセ ンブ リ モー ド を切 り 替え る よ う アセ ン ブ ラ に指
定す る 必要があ り ます。
THUMB
後続の命令を Thumb 命令 と し て アセ ン ブルす る よ う アセ ン ブ ラ
に指定 し ます。 ま た、 後続の命令が存在す る か ど う かに関係な
く 、 2 バ イ ト 境界への整列を行い ます。
ARM
ARM 命令のアセ ン ブルに戻 る よ う アセ ン ブ ラ に指定 し ます。 ま
た、 後続の命令が存在す る か ど う かに関係な く 、 4 バ イ ト 境界へ
の整列を行い ます。
こ れ ら のデ ィ レ ク テ ィ ブの詳細については、 『Assembler Guide』 を参照 し て下
さ い。
ARM DUI 0203HJ
Copyright © 2007 ARM Limited. All rights reserved.
4-9
ARM と Thumb のイ ン タ ーワー ク
4.2.3
ARM ヘ ッ ダのサン プル
例 4-2 には 4 つの コ ー ド セ ク シ ョ ン が含まれてい ます。 サン プルの後に、 各
コ ー ド セ ク シ ョ ンについて説明 し ます。
例 4-2
PRESERVE8
AREA
ENTRY
AddReg,CODE,READONLY
; SECTION 1
start
ADR r0, ThumbProg + 1
BX
r0
; SECTION 2
THUMB
ThumbProg
MOVS r2, #2
MOVS r3, #3
ADDS r2, r2, r3
ADR r0, ARMProg
BX r0
; SECTION 3
ARM
ARMProg
MOV r4, #4
MOV r5, #5
ADD r4, r4, r5
; SECTION 4
stop MOV r0, #0x18
LDR r1, =0x20026
SVC 0x123456
END
4-10
; Name this block of code.
; Mark first instruction to call.
;
;
;
;
Generate branch target address
and set bit 0, hence arrive
at target in Thumb state.
Branch exchange to ThumbProg.
; Subsequent instructions are Thumb code.
; Load r2 with value 2.
; Load r3 with value 3.
; r2 = r2 + r3
; Branch exchange to ARMProg.
; Subsequent instructions are ARM code.
;
;
;
;
angel_SWIreason_ReportException
ADP_Stopped_ApplicationExit
ARM semihosting (formerly SWI)
Mark end of this file.
Copyright © 2007 ARM Limited. All rights reserved.
ARM DUI 0203HJ
ARM と Thumb のイ ン タ ーワー ク
SECTION 1 には、 プ ロ セ ッ サ を Thumb 状態に切 り 替え る 、 ARM コ ー ド の短い
ヘ ッ ダセ ク シ ョ ンが実装 さ れてい ます。 こ のヘ ッ ダ コ ー ド には以下の命令が
使用 さ れてい ます。
•
分岐ア ド レ ス を ロ ー ド し 、 最下位ビ ッ ト を設定す る ADR 命令。 ADR 命令で
は、 r0 に pc+offset+1 の値を ロ ー ド す る こ と に よ っ て ア ド レ ス を生成 し ま
す。 つま り 、 ThumbProg に 1 を加算 し た ア ド レ ス を生成 し ます。
注
ADR 命令は、 同 じ セ ク シ ョ ン内のシ ン ボルに使用 さ れ ます。 範囲が広い場
合は、 LDR pseudo 命令を使用 し ます。 ADR お よ び LDR 命令の詳細について
は、 『Assembler Guide』 を参照 し て下 さ い。
•
Thumb コ ー ド に分岐 し 、 プ ロ セ ッ サ状態を変更す る BX 命令。
SECTION 2 にあ る ThumbProg と い う 名前の ラ ベルの前には、THUMB デ ィ レ ク テ ィ ブ
が配置 さ れてい ます。 こ のデ ィ レ ク テ ィ ブは、 後続の コ ー ド を Thumb コ ー ド
と し て処理す る よ う アセ ン ブ ラ に指定 し てい ます。 こ の Thumb コ ー ド に よ っ
て、 2 本の レ ジ ス タ の内容が加算 さ れ ます。
こ の コ ー ド では、 再度 ADR 命令を使用 し て ラ ベル ARMProg のア ド レ ス を取得 し
ますが、 こ の と き 最下位ビ ッ ト は ク リ ア さ れた ま ま です。 次の BX 命令で ARM
状態に戻 り ます。
SECTION 3 の ARMProg と い う 名前の ラ ベルでは、 2 本の レ ジ ス タ の内容が加算 さ
れ ます。
詳細については、 「付録 A セ ミ ホ ス テ ィ ン グ 」 を参照 し て下 さ い。
注
Thumb セ ミ ホ ス テ ィ ン グでは、 オペレーシ ョ ン番号 0xAB を使用 し ます。 こ れ
は ARM セ ミ ホ ス テ ィ ン グ番号 0x123456 と は異な り ます。
シ ン ボルのエ ク スポー ト
Thumb 命令を参照す る シ ン ボルを エ ク ス ポー ト す る と 、 リ ン カに よ っ て
Thumb コ ー ド の任意の ラ ベルのア ド レ ス に 1 が自動的に加算 さ れ ます。
ARM DUI 0203HJ
Copyright © 2007 ARM Limited. All rights reserved.
4-11
ARM と Thumb のイ ン タ ーワー ク
シ ン ボルを エ ク ス ポー ト し なか っ た場合は、 Thumb 命令を参照す る シ ン ボル
に手動で 1 を加算す る 必要があ り ます。 例 4-2 (ページ 4-10) では ThumbProg+1
にな り ます。 こ の作業は、 すべての参照がアセ ンブ ラ に よ っ て解決 さ れ、 リ
ン カに よ っ て シ ン ボルが検出 さ れないため必要 と な り ます。
サン プルのビル ド
サン プルを ビル ド お よ び実行す る には
4.2.4
1.
テ キ ス ト エデ ィ タ を使用 し て コ ー ド を入力 し 、 addreg.s と い う フ ァ イ ル
名で保存 し ます。
2.
コ マ ン ド プ ロ ン プ ト で 「armasm -g addreg.s」 と 入力 し 、 こ の ソ ース フ ァ
イ ルを アセ ンブル し ます。
3.
「armlink addreg.o -o addreg」 と 入力 し て、 フ ァ イ ルを リ ン ク し ます。
4.
適切なデバ ッ グ タ ーゲ ッ ト で、 RealView Debugger な ど の互換性のあ る
デバ ッ ガ を使用 し て イ メ ージ を実行 し ます。 こ のプ ロ グ ラ ム を 1 命令ず
つス テ ッ プ ス ルーす る と 、 プ ロ セ ッ サが Thumb 状態に移行す る のがわ
か り ます。 こ の切 り 替えが ど の よ う に通知 さ れ る かについては、 使用す
る デバ ッ ガのマニ ュ アルを参照 し て下 さ い。
ARM アーキテ ク チ ャ v5T 以降 と のイ ン タ ーワー ク
ARMv5T 以降には、 以下の よ う な特徴があ り ます。
•
イ ン タ ー ワー ク に使用で き る その他の命令を以下に示 し ます。
BLX address
プ ロ セ ッ サでは、 address への PC 相対 リ ン ク 付 き 分岐を実行
し 、 状態を切 り 替え ます。 address は、 ARM コ ー ド では PC か
ら 32MB 以内に、 Thumb コ ー ド では PC か ら 4MB 以内に存在
す る 必要があ り ます。
BLX register
プ ロ セ ッ サでは、 指定 さ れた レ ジ ス タ に保持 さ れてい る ア ド
レ スへの リ ン ク 付 き 分岐を実行 し ます。 ビ ッ ト 0 の値に よ っ
て、 新 し いプ ロ セ ッ サ状態が決定 さ れます。
いずれの場合 も 、lr のビ ッ ト 0 が CPSR の Thumb ビ ッ ト の現在の値に設定
さ れ ます。 し たが っ て、 復帰命令は自動的に正 し いプ ロ セ ッ サ状態に戻
る こ と がで き ます。
4-12
Copyright © 2007 ARM Limited. All rights reserved.
ARM DUI 0203HJ
ARM と Thumb のイ ン タ ーワー ク
•
LDR、 LDM、 POP のいずれかに よ っ て PC への ロ ー ド が実行 さ れ る 場合は、
PC に ロ ー ド さ れた値の ビ ッ ト 0 が、 CPSR の Thumb ビ ッ ト に設定 さ れ ま
す。 こ の動作を利用 し て命令セ ッ ト を変更で き ます。 サブルーチン か ら
の復帰には こ の方法が特に効果的です。 同 じ 復帰命令で、 ARM と
Thumb の ど ち ら の発呼側に も 戻 る こ と がで き ます。
詳細については、 『Assembler Guide』 と 『ARM アーキ テ ク チ ャ リ フ ァ レ ン ス マ
ニ ュ アル』 を参照 し て下 さ い。
4.2.5
Thumb コ ー ド 内のラ ベル
リ ン カでは、 以下の命令を参照す る ラ ベルを区別 し ます。
•
ARM 命令
•
Thumb 命令
•
デー タ
リ ン カでは、 Thumb 命令を参照す る ラ ベルの値を再配置す る と き に、 再配置
す る 値の最下位ビ ッ ト を設定 し ます。 し たがっ て、 ラ ベルへの分岐が発生す
る と 、 自動的に適切な命令セ ッ ト が選択 さ れ ます。 こ の処理は、 以下のいず
れかの命令が分岐に使用 さ れてい る 場合に行われ ます。
•
ARMv4T で BX が使用 さ れてい る 場合
•
ARM DUI 0203HJ
ARMv5T 以上で BX、 BLX、 ま たは LDR が使用 さ れてい る 場合
Copyright © 2007 ARM Limited. All rights reserved.
4-13
ARM と Thumb のイ ン タ ーワー ク
4.3
C と C++ のイ ン タ ーワー ク と ベニア
ARM 用 と Thumb 用に コ ンパ イ ル さ れた C お よ び C++ コ ー ド は自由に混用で
き ますが、 ARMv4T で状態の切 り 替え を行 う には、 ARM コ ー ド と Thumb
コ ー ド 間の状態の切 り 替え を行 う ベニ アが必要です。 ARM リ ン カでは、 イ ン
タ ー ワ ー ク 呼び出 し を検出す る と 、 こ れ ら の イ ン タ ー ワ ー ク ベニ ア を生成 し
ます。 ベニ アの詳細については、 リ ン カに よ っ て生成 さ れ るベニ ア (ページ
4-6) を参照 し て下 さ い。
4.3.1
イ ン タ ーワー ク 用 コ ー ド の コ ンパイル
--apcs /interwork コ ンパ イ ラ オプシ ョ ン を指定す る と 、 も う 一方のプ ロ セ ッ サ
状態に合わせて コ ンパ イ ル さ れたルーチン か ら 呼び出す こ と がで き る ルーチ
ン を含む C お よ び C++ モジ ュ ールを、 ARM コ ンパ イ ラ で コ ンパ イ ルで き ま
す。
armcc
armcc
armcc
armcc
--c90
--c90
--cpp
--cpp
--thumb --apcs /interwork
--arm --apcs /interwork
--thumb --apcs /interwork
--arm --apcs /interwork
注
--arm はデフ ォ ル ト のオプシ ョ ン です。--c90 は拡張子が .c の フ ァ イ ルのデフ ォ
ル ト オプシ ョ ン で、拡張子が .cpp の フ ァ イ ルのデフ ォ ル ト オプシ ョ ンは --cpp
です。
ARMv4T で イ ン タ ー ワー ク さ せ る モジ ュ ールを コ ンパ イ ルす る と 、 生成 さ れ
る コ ー ド のサ イ ズが若干大 き く な り ます。 ARMv5 では違いはあ り ません。
本体に関数呼び出 し が含まれない リ ーフ関数の場合、 コ ンパ イ ラ に よ っ て生
成 さ れ る コ ー ド で唯一異な る のは、 MOV pc,lr が BX lr に置 き 換え ら れ る と い う
点です。 MOV 命令では、 必要な状態の切 り 替え を行 う こ と がで き ません。
Thumb モー ド の ARMv4T 用に ビル ド さ れた非 リ ーフ関数では、 コ ンパ イ ラ
が、 例えば以下の よ う な 1 つの命令を
POP
{r4,r5,pc}
以下の よ う な シーケ ン ス に置 き 換え る 必要があ り ます。
POP
POP
BX
4-14
{r4,r5}
{r3}
r3
Copyright © 2007 ARM Limited. All rights reserved.
ARM DUI 0203HJ
ARM と Thumb のイ ン タ ーワー ク
こ れに よ る パフ ォ ーマ ン スへの影響はほ と ん ど あ り ません。 イ ン タ ー ワー ク
を使用す る モジ ュ ールがない こ と が確実に分か っ てい る 場合を除 き 、 ソ ース
モジ ュ ールはすべて イ ン タ ー ワ ー ク 用に コ ンパ イ ル し て下 さ い。
ま た、--apcs /interwork オプシ ョ ン を使用す る と 、 モジ ュ ールの コ ンパ イ ルに
よ っ て生成 さ れ る コ ー ド エ リ アに イ ン タ ーワ ー ク 属性が設定 さ れ ます。 リ ン
カでは、 こ の属性を検出 し て適切なベニ ア を挿入 し ます。
注
ARMv4T 以前のアーキ テ ク チ ャ のプ ロ セ ッ サには BX 命令が実装 さ れてい ませ
ん。 そのため、 イ ン タ ー ワー ク 用に コ ンパ イ ル さ れた ARM コ ー ド は、
ARMv4T 以降で し か使用で き ません。
ベニ アに よ っ て使用 さ れ る 容量を確認す る には、--info veneers リ ン カオプ
シ ョ ン を使用 し て下 さ い。
C 言語を使用 し た イ ン タ ーワー クのサン プル
例 4-3 は、 ARM サブルーチンの イ ン タ ー ワー ク 呼び出 し を実行す る Thumb
ルーチン を示 し てい ます。 こ の ARM サブルーチン呼び出 し に よ っ て、 Thumb
ラ イ ブ ラ リ 内の printf() の イ ン タ ー ワ ー ク 呼び出 し が実行 さ れ ます。 こ れ ら 2
つのモジ ュ ールは、 thumbmain.c お よ び armsub.c と い う 名前で、 メ イ ンサン プ
ルデ ィ レ ク ト リ の ...\interwork に保存 さ れてい ます。
例 4-3
/*********************
*
thumbmain.c *
**********************/
#include <stdio.h>
extern void arm_function(void);
int main(void)
{
printf("Hello from Thumb\n");
arm_function();
printf("And goodbye from Thumb\n");
return (0);
}
/*********************
*
armsub.c
*
**********************/
#include <stdio.h>
ARM DUI 0203HJ
Copyright © 2007 ARM Limited. All rights reserved.
4-15
ARM と Thumb のイ ン タ ーワー ク
void arm_function(void)
{
printf("Hello and Goodbye from ARM\n");
}
上記のモジ ュ ールを コ ンパ イ ル し て リ ン ク す る には
1.
以下の よ う に入力 し て、 Thumb コ ー ド を イ ン タ ー ワー ク 用に コ ンパ イ ル
し ます。
armcc --thumb -c -g -O1 --apcs /interwork -o thumbmain.o thumbmain.c
2.
以下の よ う に入力 し て、 ARM コ ー ド を イ ン タ ー ワー ク 用に コ ンパ イ ル
し ます。
armcc -c -g -O1 --apcs /interwork -o armsub.o armsub.c
3.
以下の よ う に入力 し て、 オブジ ェ ク ト フ ァ イ ルを リ ン ク し ます。
armlink thumbmain.o armsub.o -o thumbtoarm.axf
ま たは、 以下の よ う に入力 し て、 イ ン タ ー ワー ク ベニ アのサ イ ズ
(例 4-4 参照) を確認 し ます。
armlink armsub.o thumbmain.o -o thumbtoarm.axf --info veneers
例 4-4
Adding
Adding
Adding
Adding
Adding
Adding
Adding
Adding
Adding
Adding
Adding
Adding
Adding
Adding
TA
AT
AT
AT
TA
TA
TA
AT
TA
TA
TA
TA
TA
TA
veneer
veneer
veneer
veneer
veneer
veneer
veneer
veneer
veneer
veneer
veneer
veneer
veneer
veneer
(4 bytes, Inline) for call to 'arm_function' from thumbmain.o(.text).
(8 bytes, Inline) for call to '__0printf' from armsub.o(.text).
(8 bytes, Inline) for call to '__rt_lib_init' from kernel.o(.text).
(12 bytes, Long) for call to '__rt_lib_shutdown' from kernel.o(.text).
(4 bytes, Inline) for call to '__aeabi_memclr4' from stdio.o(.text).
(4 bytes, Inline) for call to '_mutex_initialize' from stdio.o(.text).
(4 bytes, Inline) for call to '__rt_raise' from stdio.o(.text).
(8 bytes, Inline) for call to '__raise' from rt_raise.o(.text).
(4 bytes, Inline) for call to '__heap_extend' from malloc.o(.text).
(4 bytes, Inline) for call to '__user_perproc_libspace' from malloc.o(.text).
(8 bytes, Short) for call to '__rt_exit' from exit.o(.text).
(4 bytes, Inline) for call to '_fp_init' from lib_init.o(.text).
(4 bytes, Inline) for call to '__ARM_argv_veneer' from lib_init.o(.text).
(4 bytes, Inline) for call to '_sys_exit' from abort.o(.text).
14 Veneer(s) (total 80bytes) added to the image.
4-16
Copyright © 2007 ARM Limited. All rights reserved.
ARM DUI 0203HJ
ARM と Thumb のイ ン タ ーワー ク
4.3.2
C と C++ のイ ン タ ーワー ク に関する基本的な規則
アプ リ ケーシ ョ ン内での イ ン タ ー ワー ク には、 以下の規則が適用 さ れます。
•
他方の (ARM ま たは Thumb) 命令セ ッ ト に戻 る 可能性のあ る 関数を含
む C ま たは C++ モジ ュ ールを コ ンパ イ ルす る には、--apcs /interwork コ マ
ン ド ラ イ ン オプシ ョ ン を使用す る 必要があ り ます。
•
間接的な関数呼び出 し ま たは仮想関数呼び出 し を含む C ま たは C++ モ
ジ ュ ールを コ ンパ イ ルす る 場合に、 それ ら の関数が他方の命令セ ッ ト の
関数であ る 可能性があ る と き は、--apcs /interwork コ マ ン ド ラ イ ン オプ
シ ョ ン を使用す る 必要があ り ます。
•
他方の状態にあ る コ ー ド か ら 、 イ ン タ ー ワー ク 用に コ ンパ イ ル さ れてい
ない コ ー ド に対 し て、 関数ポ イ ン タ を使用 し た呼び出 し な ど の間接的な
呼び出 し は行わないで下 さ い。
•
入力オブジ ェ ク ト に Thumb コ ー ド が含まれてい る 場合、 リ ン カに よ っ
て Thumb ラ ン タ イ ム ラ イ ブ ラ リ が選択 さ れ ます。 こ れ ら の ラ イ ブ ラ リ は
イ ン タ ー ワ ー ク 用に ビル ド さ れてい ます。
リ ン カ コ マ ン ド ラ イ ン で、 独自の ラ イ ブ ラ リ の 1 つを明示的に指定す る
場合は、 それが イ ン タ ー ワー ク に適 し た ラ イ ブ ラ リ であ る よ う にす る 必
要があ り ます。
注
C ま たは C++ モジ ュ ールの中に、 #pragma arm ま たは #pragma thumb でマー ク さ
れた関数が含まれてい る 場合は、--apcs /interwork を使用 し てそのモジ ュ ール
を コ ンパ イ ルす る 必要があ り ます。 こ れに よ り 、 関数を他方の状態か ら 正常
に呼び出す こ と がで き ます。
4.3.3
Thumb 状態の関数へのポ イ ン タ
Thumb 関数 (Thumb コ ー ド で構成 さ れてお り 、 Thumb 状態で実行 さ れ る 関
数) へのポ イ ン タ には、 最下位ビ ッ ト のセ ッ ト が含まれてい る 必要があ り ま
す。 こ れに よ り 、 イ ン タ ー ワー ク が正常に行われます。
リ ン カでは、 Thumb 命令を参照す る ラ ベルの値を再配置す る と き に、 再配置
す る 値の最下位ビ ッ ト を自動的に設定 し ます。 Thumb 関数の絶対ア ド レ ス を
使用 し た場合、 リ ン カでは こ の操作を実行で き ません。
ARM DUI 0203HJ
Copyright © 2007 ARM Limited. All rights reserved.
4-17
ARM と Thumb のイ ン タ ーワー ク
こ のため、 コ ー ド で Thumb 関数の絶対ア ド レ ス を使用す る 必要があ る 場合
は、 そのア ド レ ス に 1 を加算す る 必要があ り ます。 例えば、 例 4-5 の よ う な
Thumb 関数へのポ イ ン タ テーブルを作成す る 場合があ り ます。
詳細については、 アセ ンブ リ 言語の イ ン タ ーワー ク (ページ 4-8) を参照 し て
下 さ い。
例 4-5 Thumb 関数への絶対ア ド レ ス
typedef int (*FN)();
myfunc() {
FN fnptrs[] = {
(FN)(0x8084 + 1), // Valid Thumb address
(FN)(0x8074)
// Invalid Thumb address
};
FN* myfunctions = fnptrs;
myfunctions[0]();
myfunctions[1]();
// Call OK
// Call Fails
}
4.3.4
同一関数の 2 つの コ ピーの使用
2 つの関数に同 じ 名前を付け、 一方を ARM コ ー ド 用、 他方を Thumb コ ー ド
用に コ ンパ イ ルで き ます。
ARM と Thumb の同義語
リ ン カでは、 シ ン ボルの複数の定義を イ メ ージ内に共存 さ せ る こ と がで き ま
す。 ただ し 、 各定義は異な る プ ロ セ ッ サ状態に関連付け ら れてい る 必要があ
り ます。 ARM と Thumb の同義語を使用 し てシ ン ボルを参照す る と き 、 リ ン カ
では以下の よ う な規則が適用 さ れ ます。
•
ARM 状態のシ ン ボルへの B、 BL、 ま たは BLX 命令は、 ARM 定義に従っ て
解決 さ れ ます。
•
Thumb 状態のシ ン ボルへの B、 BL、 ま たは BLX 命令は、 Thumb 定義に従っ
て解決 さ れます。
シ ン ボルへのその他の参照は、 リ ン カが最初に検出 し た定義に従っ て解決 さ
れます。 リ ン カでは、 警告を生成 し 、 選択 し たシ ン ボルを明示 し ます。
4-18
Copyright © 2007 ARM Limited. All rights reserved.
ARM DUI 0203HJ
ARM と Thumb のイ ン タ ーワー ク
4.4
ベニア を使用 し たアセ ン ブ リ 言語のイ ン タ ーワー ク
アセ ンブ リ 言語の イ ン タ ーワー ク (ページ 4-8) で説明 し た、 アセ ンブ リ 言語
に よ る ARM/Thumb イ ン タ ー ワー ク の方法では、 必要なすべての中間処理を
実行 し ま し た。 こ の場合、 リ ン カが イ ン タ ー ワ ー ク ベニ ア を挿入す る 必要は
あ り ませんで し た。
ベニ アの詳細については、 リ ン カに よ っ て生成 さ れ る ベニア (ページ 4-6) を
参照 し て下 さ い。
4.4.1
ベニア を使用 し たア セ ン ブ リ 言語のみのイ ン タ ーワー ク
リ ン カに よ っ て生成 さ れ る イ ン タ ー ワ ー ク ベニ ア を利用す る ARM/Thumb イ
ン タ ー ワー ク コ ー ド は、 アセ ンブ リ 言語で記述で き ます。 こ の場合は以下の
ルーチン を記述す る 必要があ り ます。
•
非 イ ン タ ー ワー ク ルーチン と 同様に、 BL 命令を使用 し て呼び出 し を行 う
発呼側ルーチン。 発呼側ルーチンは、--apcs /interwork ま たは --apcs
/nointerwork のいずれか を使用 し て アセ ンブルで き ます。
注
BL 命令の範囲は、 ARM 状態では 32MB、 Thumb 状態では 4MB です。 開
発中、 範囲を超え る タ ーゲ ッ ト の呼び出 し や、 別の状態の関数の呼び出
し を アプ リ ケーシ ョ ンに含め る 場合があ り ます。 こ の よ う な場合、 リ ン
カに よ っ てベニ アが自動的に挿入 さ れ ます。 こ のベニ アが元の BL の中間
タ ーゲ ッ ト にな り 、 必要な被発呼側のア ド レ ス がベニ ア コ ー ド に よ っ て
PC に設定 さ れ ます。
•
BX 命令を使用 し て復帰す る 被発呼側ルーチン。 こ のルーチンは --apcs
/interwork を使用 し て アセ ン ブルす る 必要があ り ます。 ま た、 EXPORT
ThumbSub な ど を使用 し た、 ルーチンの関数 ラ ベルのエ ク ス ポー ト が必要
にな る 場合 も あ り ます (例 4-6 (ページ 4-20) 参照)。 必要に応 じ て、 ア
セ ンブ ラ コ ー ド を AAPCS に準拠 さ せ る 必要があ り ます。
一般的に こ の作業は ARMv4T のみで必要 と な り ます。 ま た、 発呼側ルーチン
と 被発呼側ルーチン が遠 く 離れていた り 、 異な る エ リ アに配置 さ れてい る 場
合に も 必要 と な り ます。 ARMv5T 以降では、 発呼側ルーチン と 被発呼側ルー
チンが十分に接近 し ていれば、 ベニ アは必要あ り ません。
ARM DUI 0203HJ
Copyright © 2007 ARM Limited. All rights reserved.
4-19
ARM と Thumb のイ ン タ ーワー ク
ベニア を使用 し たアセ ン ブ リ 言語のイ ン タ ーワー クのサン プル
例 4-6 は、 レ ジ ス タ r0 ~ r2 に、 1、 2、 3 の値を それぞれ設定す る コ ー ド を示
し てい ます。 レ ジ ス タ r0 お よ び r2 は ARM コ ー ド に よ っ てセ ッ ト さ れ ます。r1
は Thumb コ ー ド に よ っ てセ ッ ト さ れ ます。 以下の点に注意 し て下 さ い。
•
こ の コ ー ド は --apcs /interwork オプシ ョ ン を使用 し て アセ ン ブルす る 必
要があ り ます。
•
サブルーチンか ら の復帰には、 通常の MOV pc,lr ではな く 、 BX lr 命令が
使用 さ れ ます。
例 4-6
; *****
; arm.s
; *****
PRESERVE8
AREA
Arm,CODE,READONLY
IMPORT
ThumbProg
ENTRY
ARMProg
MOV r0,#1
BL
ThumbProg
MOV r2,#3
MOV r0, #0x18
LDR r1, =0x20026
SVC 0x123456
END
; *******
; thumb.s
; *******
AREA Thumb,CODE,READONLY
THUMB
EXPORT ThumbProg
ThumbProg
MOVS r1, #2
BX
lr
END
4-20
; Name this block of code.
; Mark 1st instruction to call.
;
;
;
;
;
;
;
Set r0 to show in ARM code.
Call Thumb subroutine.
Set r2 to show returned to ARM.
Terminate execution.
angel_SWIreason_ReportException
ADP_Stopped_ApplicationExit
ARM semihosting (formerly SWI)
; Name this block of code.
; Subsequent instructions are Thumb.
; Set r1 to show reached Thumb code.
; Return to ARM subroutine.
; Mark end of this file.
Copyright © 2007 ARM Limited. All rights reserved.
ARM DUI 0203HJ
ARM と Thumb のイ ン タ ーワー ク
こ のモジ ュ ールの ビル ド と リ ン ク を行い、 イ ン タ ー ワ ー ク ベニ ア を確認す る
には、 以下の手順を実行 し ます。
1.
「armasm -g arm.s」 と 入力 し 、 ARM コ ー ド を アセ ンブル し ます。
2.
「armasm --thumb -g --apcs /interwork thumb.s」 と 入力 し 、 Thumb コ ー ド を
アセ ン ブル し ます。
3.
「armlink arm.o thumb.o -o count」 と 入力 し 、 2 つのオブジ ェ ク ト フ ァ イ ル
を リ ン ク し ます。
4.
適切なデバ ッ グ タ ーゲ ッ ト で、 互換性のあ る デバ ッ ガ を使用 し て イ メ ー
ジ を実行 し ます。
例 4-7 は、 逆アセ ン ブル さ れた コ ー ド で、 リ ン カに よ っ て挿入 さ れ る イ ン
タ ー ワー ク ベニ ア を示 し てい ます。 ベニ アは次の ワー ド 境界に挿入 さ れ、 ア
ド レ ス 0x0000801C か ら 始ま っ てい ます。
例 4-7
ARMProg:
00008000 E3A00001
00008004 EB000004
00008008 E3A02003
0000800C E3A00018
00008010 E59F1000
00008014 EF123456
00008018 00020026
0000801C E28FC001
00008020 E12FFF1C
ThumbProg:
00008024
2102
00008026
4770
4.4.2
MOV
r0,#1
BL
0x801c
MOV
r2,#3
MOV
r0,#0x18
LDR
r1,0x8018
SVC
0x123456
<Data> '&' 0x00 0x02 0x00
ADR
r12,{pc}+9 ; #0x8025
BX
r12
MOV
BX
r1,#2
r14
ベニア を使用 し た C、 C++、 お よびア セ ン ブ リ 言語のイ ン タ ーワー ク
一方の状態で実行す る よ う に コ ンパ イ ル さ れた C お よ び C++ コ ー ド では、 他
方の状態で実行す る よ う に設計 さ れた アセ ンブ リ 言語 コ ー ド を呼び出す こ と
が可能であ り 、 ま た こ の逆 も 可能です。 こ の よ う な イ ン タ ー ワ ー ク を行 う に
ARM DUI 0203HJ
Copyright © 2007 ARM Limited. All rights reserved.
4-21
ARM と Thumb のイ ン タ ーワー ク
は、 非 イ ン タ ー ワー ク ルーチン と し て発呼側ルーチン を記述 し て呼び出 し を
行い ます。 アセ ン ブ リ 言語か ら の呼び出 し を行 う 場合には、 BL 命令を使用 し
て こ の呼び出 し を行い ます (例 4-8 参照)。 次に、 以下の手順を実行 し ます。
•
被発呼側ルーチンが C で記述 さ れてい る 場合は、--apcs /interwork を使用
し て コ ンパ イ ル し ます。
•
被発呼側ルーチンがアセ ンブ リ 言語で記述 さ れてい る 場合は、--apcs
/interwork オプシ ョ ン を使用 し て アセ ン ブル し 、 BX lr. を使用 し て復帰 し
ます。
注
こ の方法で使用 さ れ る アセ ン ブ リ 言語 コ ー ド ま たはユーザ ラ イ ブ ラ リ コ ー ド
は、 必要に応 じ て AAPCS に準拠 さ せ る 必要があ り ます。
例 4-8
/**********************
*
thumb.c
*
**********************/
#include <stdio.h>
extern int arm_function(int);
int main(void)
{
int i = 1;
printf("i = %d\n", i);
printf("And now i = %d\n", arm_function(i));
return (0);
}
; *****
; arm.s
; *****
PRESERVE8
AREA Arm,CODE,READONLY ; Name this block of code.
EXPORT arm_function
arm_function
ADD
r0,r0,#4
; Add 4 to first parameter.
BX
lr
; Return
END
4-22
Copyright © 2007 ARM Limited. All rights reserved.
ARM DUI 0203HJ
ARM と Thumb のイ ン タ ーワー ク
こ のモジ ュ ールの ビル ド と リ ン ク を行 う には、 以下の手順を実行 し ます。
ARM DUI 0203HJ
1.
「armcc --thumb -g -c --apcs /interwork thumb.c」 と 入力 し 、 Thumb コ ー ド
を コ ンパ イ ル し ます。
2.
「armasm -g --apcs /interwork arm.s」 と 入力 し 、 ARM コ ー ド を アセ ン ブル
し ます。
3.
「armlink arm.o thumb.o -o add --info veneers」 と 入力 し 、 2 つのオブジ ェ
ク ト フ ァ イ ルを リ ン ク 、 イ ン タ ー ワー ク ベニ アのサ イ ズ を確認 し ます。
4.
適切なデバ ッ グ タ ーゲ ッ ト で、 互換性のあ る デバ ッ ガ を使用 し て イ メ ー
ジ を実行 し ます。
Copyright © 2007 ARM Limited. All rights reserved.
4-23
ARM と Thumb のイ ン タ ーワー ク
4-24
Copyright © 2007 ARM Limited. All rights reserved.
ARM DUI 0203HJ
第 5章
C、 C++、 およびアセ ン ブ リ 言語の混用
本章では、 C、 C++、 お よ び ARM® アセ ン ブ リ 言語の混合 コ ー ド の記述方法に
ついて説明 し ます。 ま た、 C お よ び C++ 言語か ら ARM の イ ン ラ イ ン アセ ンブ
ラ や組み込みアセ ン ブ ラ を使用す る 方法について も 説明 し ます。 本章は以下
のセ ク シ ョ ン か ら 構成 さ れてい ます。
イ ン ラ イ ン アセ ンブ ラ と 組み込みアセ ンブ ラ の使用 (ページ 5-2)
•
ARM DUI 0203HJ
•
アセ ンブ リ コー ド か ら C グ ロ ーバル変数へのア ク セ ス (ページ 5-4)
•
C++ か ら の C ヘ ッ ダ フ ァ イ ルの使用 (ページ 5-6)
•
C、 C++、 お よ びアセ ンブ リ 言語間の呼び出 し (ページ 5-8)
Copyright © 2007 ARM Limited. All rights reserved.
5-1
C、 C++、 およびアセ ン ブ リ 言語の混用
5.1
イ ン ラ イ ン アセ ン ブ ラ と 組み込みアセ ン ブ ラの使用
ARM コ ンパ イ ラ に組み込まれてい る イ ン ラ イ ン アセ ン ブ ラ お よ び組み込みア
セ ン ブ ラ を使用す る と 、 C ま たは C++ 言語か ら 直接ア ク セ ス で き ない タ ー
ゲ ッ ト プ ロ セ ッ サの機能を使用で き ます。 以下に例を示 し ます。
•
サチ ュ レー ト 算術演算 (『Assembler Guide』 の サチ ュ レー ト 命令 (ペー
ジ 4-104) 参照)
•
•
カス タ ム コプロセッサ
プ ロ グ ラ ム状態レ ジ ス タ (PSR)
詳細については、 『Compiler User Guide』 の 「第 6 章 イ ン ラ イ ン アセ ンブ ラ と
組み込みアセ ンブ ラ の使用」 を参照 し て下 さ い。
5.1.1
イ ン ラ イ ン アセ ン ブ ラ の機能
イ ン ラ イ ン アセ ン ブ ラ では、 C お よ び C++ 言語 と の非常に柔軟な イ ン タ ー
ワー ク がサポー ト さ れてい ます。 ど の レ ジ ス タ オペ ラ ン ド に も 、 任意の C ま
たは C++ の式を使用で き ます。 ま た、 イ ン ラ イ ン アセ ンブ ラ では、 複雑な命
令を展開 し 、 アセ ンブ リ 言語 コ ー ド を最適化 し ます。
注
イ ン ラ イ ン アセ ン ブ リ 言語は、 コ ンパ イ ラ に よ っ て最適化 さ れ ます。 その結
果 と し て得 ら れたオブジ ェ ク ト コ ー ド は、 アセ ン ブ リ コ ー ド と 完全に一致 し
ていない場合があ り ます。
ARM コ ー ド 用の イ ン ラ イ ン アセ ン ブ ラ では、 汎用 コ プ ロ セ ッ サ命令、 ハーフ
ワー ド 命令、 お よ び long 乗算な ど、 ARM 命令セ ッ ト のほ と ん ど が実装 さ れ
ます。
5.1.2
組み込みアセ ン ブ ラ の機能
組み込みアセ ン ブ ラ では、 タ ーゲ ッ ト プ ロ セ ッ サへの低レベルな ア ク セ ス を
無制限に実行で き ます。 ま た、 こ のアセ ン ブ ラ に よ り 、 C お よ び C++ のプ リ
プ ロ セ ッ サデ ィ レ ク テ ィ ブ を使用で き る よ う にな る ため、 構造体 メ ンバのオ
フ セ ッ ト に簡単にア ク セ ス で き ます。
組み込みアセ ン ブ ラ を使用す る と 、 アセ ン ブ ラ デ ィ レ ク テ ィ ブ を含む、 すべ
ての ARM アセ ンブ ラ 命令セ ッ ト を使用で き ます。 組み込みアセ ン ブ リ コ ー ド
は、 C お よ び C++ で記述 さ れた コ ー ド と は別にアセ ン ブル さ れます。 コ ンパ
イ ル さ れたオブジ ェ ク ト は、 生成 さ れた後、 C お よ び C++ の ソ ース の コ ンパ
イ ルに よ っ て生成 さ れたオブジ ェ ク ト と 結合 さ れます。
5-2
Copyright © 2007 ARM Limited. All rights reserved.
ARM DUI 0203HJ
C、 C++、 およびアセ ン ブ リ 言語の混用
組み込みアセ ン ブ ラ は、 ARM コ ー ド と Thumb® コ ー ド の両方でサポー ト さ れ
てい ます。 ARM と Thumb の命令セ ッ ト の詳細については、 『Assembler Guide』
を参照 し て下 さ い。
5.1.3
イ ン ラ イ ン ア セ ン ブ リ コ ー ド と 組み込みア セ ン ブ リ コ ー ド の相違点
表 5-1 は、 イ ン ラ イ ン アセ ン ブ ラ と 組み込みアセ ン ブ ラ の主な相違点につい
て説明 し てい ます。
表 5-1 イ ン ラ イ ン アセ ン ブ ラ と 組み込みアセ ン ブ ラの相違点
機能
組み込みアセ ン ブ ラ
イ ン ラ イ ン アセ ン ブ ラ
命令セ ッ ト
ARM お よ び Thumb。
ARM のみ。
ARM アセ ンブ ラ デ ィ レ ク
ティブ
すべてサポー ト さ れてい ます。
サポー ト さ れてい ません。
C ま たは C++ の式
定数式のみ。
C ま たは C++ のすべての式。
アセ ンブ リ コ ー ド の最適化
最適化 さ れません。
完全に最適化 さ れます。
イ ン ラ イ ン展開
正 し いサ イ ズ と リ ン カの イ ン ラ イ
ン展開が有効にな っ てい る と 、 リ
ン カに よ っ て イ ン ラ イ ン展開で き
ます。
可。
レ ジ ス タ へのア ク セ ス
指定 し た物理レ ジ ス タ が使用 さ れ
ます。 PC、 LR、 お よ び SP も 使用で
き ます。
仮想レ ジ ス タ が使用 さ れます。
sp (r13)、 lr (r14)、 お よ び pc (r15)
を使用す る と 、 エ ラ ーが発生 し ます。
復帰命令
コ ー ド に追加す る 必要があ り ます。
自動的に生成 さ れます BX、 BXJ、 お よ
び BLX 命令はサポー ト さ れてい ませ
ん。
BKPT 命令
直接サポー ト さ れてい ます。
サポー ト さ れてい ません。 固有の
__breakpoint 命令を使用で き ます。
『Compiler Reference Guide』 の
__breakpoint (ページ 4-67) を参
照 し て下 さ い。
注
組み込みアセ ン ブ ラ と C ま たは C++ の相違点の リ ス ト は、 『Compiler User
Guide』 の 「第 6 章 イ ン ラ イ ン アセ ンブ ラ と 組み込みアセ ンブ ラ の使用」 に
記載 さ れてい ます。
ARM DUI 0203HJ
Copyright © 2007 ARM Limited. All rights reserved.
5-3
C、 C++、 およびアセ ン ブ リ 言語の混用
5.2
アセ ン ブ リ コ ー ド から C グローバル変数へのア ク セス
グ ロ ーバル変数には、 その変数のア ド レ ス を使用 し て間接的に し かア ク セ ス
す る こ と はで き ません。 グ ロ ーバル変数にア ク セ スす る には、 IMPORT デ ィ レ ク
テ ィ ブ を使用 し て グ ロ ーバル変数を イ ン ポー ト し 、 ア ド レ ス を レ ジ ス タ に
ロ ー ド し ます。 そのグ ロ ーバル変数には、 その型に よ っ て、 ロ ー ド 命令お よ
びス ト ア命令を使用 し て ア ク セ ス で き ます。
符号な し 変数には、 以下の命令を使用 し ます。
•
char 型の場合は LDRB ま たは STRB
•
short 型の場合は LDRH ま たは STRH
•
int 型の場合は LDR ま たは STR
符号付き 変数では、 LDRSB や LDRSH な ど、 上記の命令 と 等価な符号付 き 命令を使
用 し ます。
8 ワー ド 未満の小 さ な構造体全体には、 LDM 命令お よ び STM 命令を使用 し て ア
ク セ ス で き ます。 構造体の各 メ ンバには、 適切な タ イ プの ロ ー ド 命令ま たは
ス ト ア命令を使用 し て ア ク セ ス で き ます。 各 メ ンバにア ク セ スす る には、 構
造体の開始位置か ら メ ンバのオ フ セ ッ ト を把握 し てお く 必要があ り ます。
例 5-1 では、 整数のグ ロ ーバル変数 globvar のア ド レ ス を r1 に ロ ー ド し 、 その
ア ド レ ス に格納 さ れた値を r0 に ロ ー ド し て 2 を加算 し てか ら 、 その新 し い値
を globvar に返 し ます。
例 5-1 グローバル変数へのア ク セス
PRESERVE8
AREA
globals,CODE,READONLY
EXPORT
IMPORT
asmsubroutine
globvar
asmsubroutine
LDR r1, =globvar
LDR
ADD
STR
BX
END
5-4
; read address of globvar into
; r1 from literal pool
r0, [r1]
r0, r0, #2
r0, [r1]
lr
Copyright © 2007 ARM Limited. All rights reserved.
ARM DUI 0203HJ
C、 C++、 およびアセ ン ブ リ 言語の混用
ARM ま たは Thumb の コ ー ド で使用で き る 命令の詳細については、 『Assembler
Guide』 の 「第 4 章 ARM 命令 と Thumb 命令」 を参照 し て下 さ い。
ARM DUI 0203HJ
Copyright © 2007 ARM Limited. All rights reserved.
5-5
C、 C++、 およびアセ ン ブ リ 言語の混用
5.3
C++ からの C ヘ ッ ダ フ ァ イルの使用
C ヘ ッ ダ フ ァ イ ルを C++ か ら 呼び出すには、 extern "C" デ ィ レ ク テ ィ ブで ラ ッ
プす る 必要があ り ます。
5.3.1
シ ス テム C ヘ ッ ダ フ ァ イルのイ ン ク ルー ド
stdio.h な ど の標準シ ス テ ム C ヘ ッ ダ フ ァ イ ルを イ ン ク ルー ド す る 場合は、 特
に必要な手順はあ り ません。 標準 C ヘ ッ ダ フ ァ イ ルには、 既に適切な extern
"C" デ ィ レ ク テ ィ ブが含ま れてい ます。 以下に例を示 し ます。
#include <stdio.h>
int main()
{
...
// C++ code
return 0;
}
こ の構文を使用 し てヘ ッ ダ を イ ン ク ルー ド す る と 、 すべての ラ イ ブ ラ リ 名が
グ ロ ーバルネーム スペース に配置 さ れ ます。
C++ 標準では、 C ヘ ッ ダ フ ァ イ ルの機能が C++ 固有のヘ ッ ダ フ ァ イ ルか ら 使
用で き る よ う に定義 さ れてい ます。 こ の C++ 固有のヘ ッ ダ フ ァ イ ルは、 標準
C ヘ ッ ダ フ ァ イ ル と 共に、
install_directory\RVCT\Data\3.0\build_num\include\platform に イ ン ス ト ール さ
れ、 通常の方法で参照で き ます。 以下に例を示 し ます。
#include <cstdio>
ARM C++ では、 C ヘ ッ ダ フ ァ イ ルの イ ン ク ルー ド が行われ ます。 こ の構文を
使用 し てヘ ッ ダ を イ ン ク ルー ド す る と 、 C ラ イ ブ ラ リ の名前を含む、 C++ 標
準 ラ イ ブ ラ リ 名のすべてがネーム スペース std 内で定義 さ れます。 つま り 、 す
べての ラ イ ブ ラ リ 名は、 以下のいずれかの方法を使用 し て修飾す る 必要があ
り ます。
•
以下の よ う に標準ネーム スペース を指定 し ます。
std::printf("example\n");
•
以下の よ う な C++ キー ワー ド の using を使用 し て名前を グ ロ ーバルネー
ム スペース に イ ン ポー ト し ます。
using namespace std;
printf("example\n");
•
5-6
コ ンパ イ ラ オプシ ョ ン --using_std を使用 し ます。
Copyright © 2007 ARM Limited. All rights reserved.
ARM DUI 0203HJ
C、 C++、 およびアセ ン ブ リ 言語の混用
5.3.2
独自の C ヘ ッ ダ フ ァ イルのイ ン ク ルー ド
独自の C ヘ ッ ダ フ ァ イ ルを イ ン ク ルー ド す る には、#include デ ィ レ ク テ ィ ブ を
extern "C" ス テー ト メ ン ト で ラ ッ プす る 必要があ り ます。 以下の方法で行 う こ
と がで き ます。
•
フ ァ イ ルの イ ン ク ルー ド 時に ラ ッ プ し ます (例 5-2 参照)。
•
extern "C" ス テー ト メ ン ト をヘ ッ ダ フ ァ イ ルに追加 し て ラ ッ プ し ます
(例 5-3 参照)。
例 5-2 イ ン クルー ド フ ァ イルの前に配置 さ れたデ ィ レ ク テ ィ ブ
// C++ code
extern "C" {
#include "my-header1.h"
#include "my-header2.h"
}
int main()
{
// ...
return 0;
}
例 5-3 ヘ ッ ダ フ ァ イル内に配置 さ れたデ ィ レ ク テ ィ ブ
/* C header file */
#ifdef __cplusplus
extern "C" {
#endif
/* Insert start of extern C construct */
/* Body of header file */
#ifdef __cplusplus
}
#endif
ARM DUI 0203HJ
/* Insert end of extern C construct */
/* The C header file can now be */
/* included in either C or C++ code. */
Copyright © 2007 ARM Limited. All rights reserved.
5-7
C、 C++、 およびアセ ン ブ リ 言語の混用
5.4
C、 C++、 およびアセ ン ブ リ 言語間の呼び出 し
こ のセ ク シ ョ ン では、 C++ か ら C お よ びアセ ンブ リ 言語の コ ー ド を呼び出 し
た り 、 C お よ びアセ ン ブ リ 言語か ら C++ コ ー ド を呼び出 し た り す る 場合に役
立つサン プルを紹介 し ます。 ま た、 呼び出 し 規則 と デー タ 型について も 説明
し ます。
AAPCS に準拠 し てい る 場合は、 C、 C++、 お よ びアセ ン ブ リ 言語で記述 し た
ルーチン間の呼び出 し を混在 さ せ る こ と がで き ます。 詳細については、
install_directory\Documentation\Specifications\... にあ る 『Procedure Call
Standard for the ARM Architecture』 (aapcs.pdf) を参照 し て下 さ い。
注
こ のセ ク シ ョ ン の情報は実装に依存す る も のであ り 、 今後の リ リ ース で変更
さ れ る 可能性があ り ます。
5.4.1
複数言語間の呼び出 し に関する一般規則
C、 C++、 お よ びアセ ン ブ リ 言語間の呼び出 し には、 以下の一般規則が適用 さ
れ ます。 詳細については、 『Compiler User Guide』 を参照 し て下 さ い。
組み込みアセ ン ブ ラ を使用 し 、 Application Binary Interface (ABI) for the ARM
Architecture (base standard) [BSABI] に準拠す る こ と で、 複数言語を混用 し
たプ ロ グ ラ ミ ン グ を簡単に実装で き る よ う にな り ます。 こ れに よ り 、 以下の
内容がサポー ト さ れ ます。
__cpp キー ワ ー ド を使用 し た名前の符号化
•
•
暗黙の this パ ラ メ ー タ を渡す方法
•
•
•
仮想関数の呼び出 し 方法
参照の表現
ベース ク ラ ス ま たは仮想 メ ンバ関数を持つ C++ ク ラ ス型の レ イ ア ウ ト
•
Plain Old Data (POD) 構造体以外の ク ラ ス オブジ ェ ク ト を渡す方法
混合言語プ ロ グ ラ ミ ン グには、 以下の一般規則が適用 さ れます。
5-8
•
C の呼び出 し 規則を使用 し ます。
•
C++ では、 非 メ ンバ関数を extern "C" と し て宣言 し 、 C リ ン ケージ を使
用す る よ う に指定で き ます。 RealView® Compilation Tools (RVCT) の本 リ
リ ース では、 C リ ン ケージ を使用す る と 、 関数を定義す る シ ン ボルが符
号化 さ れ ません。 C リ ン ケージ を使用す る と 、 あ る 言語で関数を実装 し 、
その関数を別の言語か ら 呼び出す こ と がで き ます。
Copyright © 2007 ARM Limited. All rights reserved.
ARM DUI 0203HJ
C、 C++、 およびアセ ン ブ リ 言語の混用
注
extern "C" と し て宣言 さ れ る 関数はオーバー ロ ー ド で き ません。
•
アセ ン ブ リ 言語モジ ュ ールは、 アプ リ ケーシ ョ ン で使用 さ れてい る メ モ
リ モデルに適 し た AAPCS 標準に準拠す る 必要があ り ます。
C お よ びアセ ン ブ リ 言語か ら の C++ 関数の呼び出 し には、 以下の規則が適用
さ れ ます。
5.4.2
•
C++ のグ ロ ーバル (非 メ ンバ) 関数を呼び出すには、 こ の関数を extern
"C" と し て宣言 し て、 C リ ン ケージ を指定 し ます。
•
メ ンバ関数 (ス タ テ ィ ッ ク 関数 と 非ス タ テ ィ ッ ク 関数の両方) の名前は
必ず符号化す る 必要があ り ます。 組み込みアセ ン ブ ラ の __cpp キー ワー
ド を使用す る と 、 符号化 さ れた名前を手動で検索す る 必要がな く な り ま
す。
•
C++ イ ン ラ イ ン関数は、 C++ コ ンパ イ ラ でその関数のア ウ ト オブ ラ イ ン
コ ピーが生成 さ れ る よ う に し た場合を除 き 、 C か ら 呼び出す こ と がで き
ません。 例えば、 こ の関数のア ド レ ス を取得す る と 、 ア ウ ト オブ ラ イ ン
コ ピーが生成 さ れます。
•
非ス タ テ ィ ッ ク メ ンバ関数は、 暗黙の this パ ラ メ ー タ を r0 の最初の引
数 と し て受け取 り ます。 ま た、 こ の関数が int に類似 し ていない構造体
を返す場合は、 r1 の 2 番目の引数 と し て受け取 り ます。 ス タ テ ィ ッ ク メ
ンバ関数は、 暗黙の this パ ラ メ ー タ を受け取 り ません。
C++ に関する情報
以下の情報は、 C++ のみに当ては ま り ます。
C++ の呼び出 し 規則
ARM C++ では、 1 つの例外を除 き 、 ARM C と 同 じ 呼び出 し 規則が使用 さ れ ま
す。
•
ARM DUI 0203HJ
非ス タ テ ィ ッ ク メ ンバ関数は、 暗黙の this パ ラ メ ー タ を最初の引数 と し
て、 ま たは呼び出 さ れ る 関数が int に類似 し ていない構造体 を返す場合は
2 番目の引数 と し て使用す る こ と で呼び出 さ れ ます。 こ の規則は今後の
実装で変更 さ れ る 可能性があ り ます。
Copyright © 2007 ARM Limited. All rights reserved.
5-9
C、 C++、 およびアセ ン ブ リ 言語の混用
C++ デー タ 型
ARM C++ では、 以下の例外 と 追加点を除 き 、 ARM C と 同 じ デー タ 型が使用
さ れ ます。
•
struct 型ま たは class 型の C++ オブジ ェ ク ト には、 ベース ク ラ ス ま たは
仮想関数が含ま れていない場合に ARM C で予測 さ れ る レ イ ア ウ ト と 同
じ レ イ ア ウ ト が使用 さ れ ます。 こ の よ う な struct 型のオブジ ェ ク ト に
ユーザ定義の コ ピー代入演算子 も ユーザ定義のデス ト ラ ク タ も 含まれて
いない場合、 こ のオブジ ェ ク ト は Plain Old Data 構造体 と し て処理 さ れ
ます。
•
参照はポ イ ン タ と し て表現 さ れます。
•
C 関数へのポ イ ン タ と C++ 非 メ ンバ関数へのポ イ ン タ は区別 さ れませ
ん。
シ ンボル名の符号化
リ ン カは、 メ ッ セージ内のシ ン ボル名を符号化 し ません。
C で記述す る 名前は、 C++ プ ロ グ ラ ム では extern "C" と し て宣言す る 必要があ
り ます。 こ の宣言は、 既に ARM ISO C ヘ ッ ダで行われてい ます。 詳細につい
ては、 C++ か ら の C ヘ ッ ダ フ ァ イ ルの使用 (ページ 5-6) を参照 し て下 さ い。
5.4.3
言語間の呼び出 し のサン プル
以下のセ ク シ ョ ン では、 複数言語の呼び出 し を混用す る 方法を示すサン プル
コ ー ド を紹介 し ます。
•
C 言語か ら のアセ ンブ リ 言語の呼び出 し (ページ 5-11)
•
アセ ンブ リ 言語か ら の C 言語の呼び出 し (ページ 5-12)
C++ 言語か ら の C 言語の呼び出 し (ページ 5-13)
C++ 言語か ら のアセ ンブ リ 言語の呼び出 し (ページ 5-14)
C 言語か ら の C++ 言語の呼び出 し (ページ 5-15)
アセ ンブ リ 言語か ら の C++ 言語の呼び出 し (ページ 5-16)
C 言語ま たはアセ ンブ リ 言語か ら の C++ 言語の呼び出 し (ページ 5-18)
C 言語 と C++ 言語間での参照の受け渡 し (ページ 5-17)
•
•
•
•
•
•
5-10
Copyright © 2007 ARM Limited. All rights reserved.
ARM DUI 0203HJ
C、 C++、 およびアセ ン ブ リ 言語の混用
C 言語か ら のアセ ン ブ リ 言語の呼び出 し
例 5-4 と 例 5-5 では、 アセ ン ブ リ 言語サブルーチンへの呼び出 し を使用 し て 1
つの ス ト リ ン グ を別の ス ト リ ン グの上に コ ピーす る C プ ロ グ ラ ム を示 し てい
ます。
例 5-4 C 言語からのアセ ン ブ リ 言語の呼び出 し
#include <stdio.h>
extern void strcopy(char *d, const char *s);
int main()
{
const char *srcstr = "First string - source ";
char dststr[] = "Second string - destination ";
/* dststr is an array since we’re going to change it */
printf("Before copying:\n");
printf(" %s\n %s\n",srcstr,dststr);
strcopy(dststr,srcstr);
printf("After copying:\n");
printf(" %s\n %s\n",srcstr,dststr);
return (0);
}
例 5-5 アセ ン ブ リ 言語を使用 し たス ト リ ング コ ピーサブルーチ ン
PRESERVE8
AREA
SCopy, CODE, READONLY
EXPORT strcopy
strcopy
; r0 points to destination string.
; r1 points to source string.
LDRB r2, [r1],#1 ; Load byte and update address.
STRB r2, [r0],#1 ; Store byte and update address.
CMP r2, #0
; Check for zero terminator.
BNE strcopy
; Keep going if not.
BX
lr
; Return.
END
例 5-4 は、 strtest.c お よ び scopy.s と し て、 メ イ ンサン プルデ ィ レ ク ト リ の
...\asm にあ り ます。
ARM DUI 0203HJ
Copyright © 2007 ARM Limited. All rights reserved.
5-11
C、 C++、 およびアセ ン ブ リ 言語の混用
こ のサン プルを コ マ ン ド ラ イ ン か ら ビル ド す る には、 以下の手順に従い ます。
1.
「armasm --debug scopy.s」 と 入力 し 、 アセ ンブ リ 言語 ソ ース を ビル ド し ま
す。
2.
「armcc -c --debug strtest.c」 と 入力 し 、 C ソ ース を ビル ド し ます。
3.
「armlink strtest.o scopy.o -o strtest」 と 入力 し 、 オブジ ェ ク ト フ ァ イ ル
を リ ン ク し ます。
4.
適切なデバ ッ グ タ ーゲ ッ ト で、 互換性のあ る デバ ッ ガ を使用 し て イ メ ー
ジ を実行 し ます。
アセ ン ブ リ 言語か ら の C 言語の呼び出 し
例 5-6 と 例 5-7 では、アセ ン ブ リ 言語か ら C 言語を呼び出す方法を示 し てい ま
す。
例 5-6 C 言語における関数の定義
int g(int a, int b, int c, int d, int e)
{
return a + b + c + d + e;
}
例 5-7 アセ ン ブ リ 言語の呼び出 し
; int f(int i) { return g(i, 2*i, 3*i, 4*i, 5*i); }
PRESERVE8
EXPORT f
AREA f, CODE, READONLY
IMPORT g
; i is in r0
STR lr, [sp, #-4]! ; preserve lr
ADD r1, r0, r0
; compute 2*i (2nd param)
ADD r2, r1, r0
; compute 3*i (3rd param)
ADD r3, r1, r2
; compute 5*i
STR r3, [sp, #-4]! ; 5th param on stack
ADD r3, r1, r1
; compute 4*i (4th param)
BL g
; branch to C function
5-12
Copyright © 2007 ARM Limited. All rights reserved.
ARM DUI 0203HJ
C、 C++、 およびアセ ン ブ リ 言語の混用
ADD sp, sp, #4
LDR pc, [sp], #4
END
; remove 5th param
; return
C++ 言語か らの C 言語の呼び出 し
例 5-8 お よ び例 5-9 では、 C++ 言語か ら C 言語を呼び出す方法を示 し てい ま
す。
例 5-8 C++ 言語からの C 関数の呼び出 し
struct S {
// has no base classes
// or virtual functions
S(int s) : i(s) { }
int i;
};
extern "C" void cfunc(S *);
// declare the C function to be called from C++
int f(){
S s(2);
// initialize 's'
cfunc(&s);
// call 'cfunc' so it can change 's'
return s.i * 3;
}
例 5-9 C 言語における関数の定義
struct S {
int i;
};
void cfunc(struct S *p) {
/* the definition of the C function to be called from C++ */
p->i += 5;
}
ARM DUI 0203HJ
Copyright © 2007 ARM Limited. All rights reserved.
5-13
C、 C++、 およびアセ ン ブ リ 言語の混用
C++ 言語か ら のアセ ン ブ リ 言語の呼び出 し
例 5-10 と 例 5-11 では、 C++ 言語か ら アセ ン ブ リ 言語を呼び出す方法を示 し て
い ます。
例 5-10 C++ 言語から のアセ ン ブ リ 言語の呼び出 し
struct S {
// has no base classes
// or virtual functions
S(int s) : i(s) { }
int i;
};
extern "C" void asmfunc(S *);
int f() {
S s(2);
asmfunc(&s);
// declare the Asm function
// to be called
// initialize 's'
// call 'asmfunc' so it
// can change 's'
return s.i * 3;
}
例 5-11 アセ ン ブ リ 言語で記述 さ れた関数の定義
PRESERVE8
AREA Asm, CODE
EXPORT asmfunc
asmfunc
LDR r1, [r0]
ADD r1, r1, #5
STR r1, [r0]
BX lr
END
5-14
; the definition of the Asm
; function to be called from C++
Copyright © 2007 ARM Limited. All rights reserved.
ARM DUI 0203HJ
C、 C++、 およびアセ ン ブ リ 言語の混用
C 言語か ら の C++ 言語の呼び出 し
例 5-12 と 例 5-13 では、 C 言語か ら C++ 言語を呼び出す方法を示 し てい ます。
例 5-12 C++ で呼び出 さ れる関数の定義
struct S {
// has no base classes or virtual functions
S(int s) : i(s) { }
int i;
};
extern "C" void cppfunc(S *p) {
// Definition of the C++ function to be called from C.
// The function is written in C++, only the linkage is C
p->i += 5;
//
}
例 5-13 C 言語での関数の宣言 と 呼び出 し
struct S {
int i;
};
extern void cppfunc(struct S *p);
/* Declaration of the C++ function to be called from C */
int f(void) {
struct S s;
s.i = 2;
cppfunc(&s);
/* initialize 's' */
/* call 'cppfunc' so it */
/* can change 's' */
return s.i * 3;
}
ARM DUI 0203HJ
Copyright © 2007 ARM Limited. All rights reserved.
5-15
C、 C++、 およびアセ ン ブ リ 言語の混用
アセ ン ブ リ 言語か ら の C++ 言語の呼び出 し
例 5-14 と 例 5-15 では、 アセ ン ブ リ 言語か ら C++ 言語を呼び出す方法を示 し
てい ます。
例 5-14 C++ で呼び出 さ れる関数の定義
struct S {
// has no base classes or virtual functions
S(int s) : i(s) { }
int i;
};
extern "C" void cppfunc(S * p) {
// Definition of the C++ function to be called from ASM.
// The body is C++, only the linkage is C
p->i += 5;
}
ARM アセ ンブ リ 言語では、 C++ 関数の名前を イ ン ポー ト し 、 リ ン ク 付 き 分岐
(BL) 命令を使用 し てその関数を呼び出 し ます。
例 5-15 アセ ン ブ リ 言語で記述 さ れた関数の定義
AREA Asm, CODE
IMPORT cppfunc
EXPORT
; import the name of the C++
; function to be called from Asm
f
f
5-16
STMFD
MOV
STR
MOV
BL
sp!,{lr}
r0,#2
r0,[sp,#-4]!
r0,sp
cppfunc
LDR
ADD
LDMFD
END
r0, [sp], #4
r0, r0, r0,LSL #1
sp!,{pc}
;
;
;
;
initialize struct
argument is pointer to struct
call 'cppfunc' so it can change
the struct
Copyright © 2007 ARM Limited. All rights reserved.
ARM DUI 0203HJ
C、 C++、 およびアセ ン ブ リ 言語の混用
C 言語 と C++ 言語間での参照の受け渡 し
例 5-16 と 例 5-17 では、C 言語 と C++ 言語の間で参照を受け渡す方法を示 し て
い ます。
例 5-16 C++ 関数の定義
extern "C" int cfunc(const int&);
// Declaration of the C function to be called from C++
extern "C" int cppfunc(const int& r) {
// Definition of the C++ to be called from C.
return 7 * r;
}
int f() {
int i = 3;
return cfunc(i);
}
// passes a pointer to 'i'
例 5-17 C 関数の定義
extern int cppfunc(const int*);
/* declaration of the C++ to be called from C */
int cfunc(const int *p) {
/* definition of the C function to be called from C++ */
int k = *p + 4;
return cppfunc(&k);
}
ARM DUI 0203HJ
Copyright © 2007 ARM Limited. All rights reserved.
5-17
C、 C++、 およびアセ ン ブ リ 言語の混用
C 言語またはアセ ン ブ リ 言語か ら の C++ 言語の呼び出 し
例 5-18、 例 5-19、 お よ び例 5-20 (ページ 5-19) の コ ー ド は、 C ま たはアセ ン
ブ リ 言語か ら C++ 言語の非ス タ テ ィ ッ ク な非仮想 メ ンバ関数を呼び出す方法
を示 し てい ます。 関数の符号化 さ れた名前を参照す る には、 コ ンパ イ ラ か ら
アセ ン ブ ラ 出力を使用 し て下 さ い。
例 5-18 C++ メ ンバ関数の呼び出 し
struct T {
T(int i) : t(i) { }
int t;
int f(int i);
};
int T::f(int i) { return i + t; }
// Definition of the C++ function to be called from C.
extern "C" int cfunc(T*);
// declaration of the C function to be called from C++
int f() {
T t(5);
return cfunc(&t);
}
// create an object of type T
例 5-19 C 関数の定義
struct T;
extern int _ZN1T1fEi(struct T*, int);
/* the mangled name of the C++ */
/* function to be called */
int cfunc(struct T* t) {
/* Definition of the C function to be called from C++. */
return 3 * _ZN1T1fEi(t, 2);
/* like '3 * t->f(2)' */
}
5-18
Copyright © 2007 ARM Limited. All rights reserved.
ARM DUI 0203HJ
C、 C++、 およびアセ ン ブ リ 言語の混用
例 5-20 アセ ン ブ リ 言語での関数の実装
EXPORT cfunc
AREA foo, CODE
IMPORT _ZN1T1fEi
cfunc
STMFD
sp!,{lr}
MOV r1, #2
BL _ZN1T1fEi
ADD r0, r0, r0, LSL #1
LDMFD sp!,{pc}
END
; r0 already contains the object pointer
; multiply by 3
別の方法 と し て、 例 5-21 で示す よ う に、 例 5-18 (ページ 5-18) と 例 5-20 は、
組み込みアセ ン ブ リ を使用 し て実装で き ます。 こ のサン プルでは、 関数の参
照に __cpp キー ワー ド が使用 さ れます。 そのため、 関数の符号化 さ れた名前を
把握 し てお く 必要はあ り ません。
例 5-21 組み込みアセ ン ブ リ での関数の実装
struct T {
T(int i) : t(i) { }
int t;
int f(int i);
};
int T::f(int i) { return i + t; }
// Definition of asm function called from C++
__asm int asm_func(T*) {
STMFD sp!, {lr}
MOV r1, #2;
BL __cpp(T::f);
ADD r0, r0, r0, LSL #1 ; multiply by 3
LDMFD sp!, {pc}
}
int f() {
T t(5); // create an object of type T
return asm_func(&t);
}
ARM DUI 0203HJ
Copyright © 2007 ARM Limited. All rights reserved.
5-19
C、 C++、 およびアセ ン ブ リ 言語の混用
5-20
Copyright © 2007 ARM Limited. All rights reserved.
ARM DUI 0203HJ
第 6章
プ ロ セ ッ サ例外処理
本章では、 アーキ テ ク チ ャ ARMv6 以前、 v7-A お よ び v7-R のプ ロ フ ァ イ ルが
サポー ト し てい る 各種の例外の処理方法について説明 し ます。
例えば Cortex-M3 な ど の ARMv7-M プ ロ セ ッ サは、 別の例外処理モデルを使
用 し ます。 「第 7 章 Handling Cortex-M3 Processor ExceptionsCortex-M3 プ ロ セ ッ
サ例外処理」 を参照 し て下 さ い。
本章は以下のセ ク シ ョ ンか ら 構成 さ れてい ます。
•
プ ロ セ ッ サ例外について (ページ 6-3)
•
•
•
•
•
•
•
•
•
ARM DUI 0203HJ
プ ロ セ ッ サ状態の判断 (ページ 6-7)
例外の開始 と 終了 (ページ 6-9)
例外処理 (ページ 6-14)
例外ハン ド ラ の イ ン ス ト ール (ページ 6-15)
SVC ハン ド ラ (ページ 6-20)
割 り 込みハン ド ラ (ページ 6-30)
リ セ ッ ト ハン ド ラ (ページ 6-41)
未定義命令ハン ド ラ (ページ 6-42)
プ リ フ ェ ッ チアボー ト ハン ド ラ (ページ 6-43)
Copyright © 2007 ARM Limited. All rights reserved.
6-1
プ ロ セ ッ サ例外処理
•
•
6-2
デー タ アボー ト ハン ド ラ (ページ 6-44)
シ ス テ ムモー ド (ページ 6-46)
Copyright © 2007 ARM Limited. All rights reserved.
ARM DUI 0203HJ
プ ロ セ ッ サ例外処理
6.1
プ ロ セ ッ サ例外について
プ ロ グ ラ ムの通常の実行フ ロ ーにおいて、 近 く の ラ ベルへの分岐や、 サブ
ルーチンへの分岐 と リ ン ク な ど が実行 さ れ る こ と に よ り 、 プ ロ グ ラ ム カ ウ ン
タ (PC) はア ド レ ス空間の中でシーケ ン シ ャ ルに増加 し ます。
プ ロ セ ッ サ例外は、 内部 ソ ース ま たは外部 ソ ース に よ っ て生成 さ れ る イ ベン
ト を プ ロ セ ッ サが処理で き る よ う に、 こ の通常の実行フ ロ ーが迂回 さ れ る と
き に発生 し ます。 こ の イ ベン ト には以下の よ う な も のがあ り ます。
•
•
•
外部で生成 さ れた割 り 込み
未定義命令を実行 し よ う と す る プ ロ セ ッ サの試行
オペレーテ ィ ン グ シ ス テ ム の特権付 き 機能へのア ク セ ス
こ れ ら の例外が発生 し た と き に実行 し ていたプ ロ グ ラ ム を、 適切な例外ルー
チンの終了時に再開で き る よ う にす る ため、 例外を処理す る と き は、 それ ま
でのプ ロ セ ッ サ状態を保存 し てお く 必要があ り ます。
ARM DUI 0203HJ
Copyright © 2007 ARM Limited. All rights reserved.
6-3
プ ロ セ ッ サ例外処理
6.1.1
例外の タ イ プ
表 6-1 は、 ARM プ ロ セ ッ サに よ っ て認識 さ れ る 例外の タ イ プ を示 し てい ま
す。
表 6-1 例外の タ イ プ
例外
説明
リ セッ ト
プ ロ セ ッ サ リ セ ッ ト ピ ンがアサー ト さ れ る と 発生 し ます。 こ の例外は、 起動が通知
さ れた場合ま たはプ ロ セ ッ サ を起動 さ れた状態にす る ために リ セ ッ ト が行われた場
合にのみ発生 し ます。 ソ フ ト リ セ ッ ト は、 リ セ ッ ト ベ ク タ 0x0000 ま たは 0xFFFF0000
に分岐 さ せ る こ と に よ っ て実行で き ます。
未定義命令
実行中の命令が、 プ ロ セ ッ サや接続 さ れてい る ど の コ プ ロ セ ッ サに も 認識 さ れない
場合に発生 し ます。
スーパーバ イ ザ コ ール
(SVC)
ユーザ定義の同期割 り 込み命令です。 スーパーバ イ ザ コ ールに よ り 、 例えば、 ユー
ザモー ド で実行中のプ ロ グ ラ ムが、 スーパーバ イ ザモー ド で実行 さ れ る RTOS 関数
な ど の特権操作を要求で き ます。
プ リ フ ェ ッ チアボー ト
ア ド レ ス が不正であ っ たために フ ェ ッ チ さ れなか っ た命令をプ ロ セ ッ サが実行 し よ
う と し た と き に発生 し ます (「不正ア ド レ ス 」 参照)。
デー タ アボー ト
デー タ 転送命令に よ っ て不正な ア ド レ ス での ロ ー ド ま たは保存が試行 さ れた と き に
発生 し ます (「不正ア ド レ ス 」 参照)。
IRQ
プ ロ セ ッ サ外部割 り 込み要求ピ ンがアサー ト (LOW) さ れ、 CPSR 内の I ビ ッ ト が ク
リ ア さ れてい る と き に発生 し ます。
FIQ
プ ロ セ ッ サ外部高速割 り 込み要求ピ ンがアサー ト (LOW) さ れ、 CPSR 内の F ビ ッ ト
が ク リ ア さ れてい る と き に発生 し ます。
不正ア ド レ ス
不正な仮想ア ド レ ス と は、 物理 メ モ リ のア ド レ ス と 現時点で対応 し ていない
ア ド レ ス か、 現在のモー ド ではプ ロ セ ッ サか ら ア ク セ ス で き ない と メ モ リ 管
理サブシ ス テ ム が判断 し た ア ド レ ス を指 し ます。
6-4
Copyright © 2007 ARM Limited. All rights reserved.
ARM DUI 0203HJ
プ ロ セ ッ サ例外処理
6.1.2
ベ ク タ テーブル
プ ロ セ ッ サ例外処理はベ ク タ テーブル に よ っ て制御 さ れます。 ベ ク タ テーブ
ルは 32 バ イ ト の予約エ リ アであ り 、 通常は メ モ リ マ ッ プの最下位に配置 さ れ
ます。 ベ ク タ テーブルでは各例外 タ イ プに 1 ワ ー ド の空間が割 り 当て ら れ、 1
ワー ド が予約 さ れてい ます。
こ の空間はハン ド ラ の コ ー ド 全体を保持す る には大 き さ が不十分であ る ため、
通常は各例外 タ イ プのベ ク タ エ ン ト リ に、 適切なハン ド ラ を使用 し て実行を
継続す る ための分岐命令ま たは ロ ー ド PC 命令が保持 さ れてい ます。
6.1.3
例外に よ る モー ド と レ ジ ス タ の使用
通常、 アプ リ ケーシ ョ ンはユーザモー ド で実行 さ れ ますが、 例外処理は特権
付 き モー ド で実行 さ れ る 必要があ り ます。 例外が発生す る と プ ロ セ ッ サモー
ド が変更 さ れ、 こ れに よ り 各例外ハン ド ラ は、 以下の よ う な特定のバン ク レ
ジ ス タ のサブセ ッ ト にア ク セ ス で き る よ う にな り ます。
•
専用の r13、 つま り ス タ ッ ク ポ イ ン タ (sp_mode)
•
専用の r14、 つま り リ ン ク レ ジ ス タ (lr_mode)
•
専用の 保存プ ロ グ ラ ム状態レ ジ ス タ (spsr_mode)
FIQ の場合、 各例外ハン ド ラ は さ ら に 5 本の汎用レ ジ ス タ (r8_FIQ ~ r12_FIQ)
にア ク セ ス で き ます。
各例外ハン ド ラ は、 終了時に他の レ ジ ス タ を元の内容に復元 さ せ る 必要があ
り ます。 こ の操作は、 ハン ド ラ が必要 と す る すべての レ ジ ス タ 内容を ス タ ッ
ク に保存 し 、 復帰前に こ れ ら を復元す る こ と で可能 と な り ます。 RealView
ARMulator® ISS を使用す る 場合は、 必要 と な る ス タ ッ ク が自動的に設定 さ れ
ます。 こ れ ら を使用 し ない場合は、 ス タ ッ ク を設定す る 必要があ り ます。
注
前述の と お り 、 register_mode 形式のシ ン ボ リ ッ ク な レ ジ ス タ 名はアセ ン ブ ラ
に よ っ て事前に宣言 さ れ ません。 こ の形式を使用す る には、 RN アセ ンブ ラ
デ ィ レ ク テ ィ ブ を使用 し て、 適切なシ ン ボ リ ッ ク 名を宣言す る 必要があ り ま
す。例えば、lr_FIQ RN r14 を使用す る と 、r14 のシ ン ボ リ ッ ク レ ジ ス タ 名 lr_FIQ
を宣言で き ます。 RN デ ィ レ ク テ ィ ブの詳細については、 『Assembler Guide』 の
デ ィ レ ク テ ィ ブに関す る 章を参照 し て下 さ い。
ARM DUI 0203HJ
Copyright © 2007 ARM Limited. All rights reserved.
6-5
プ ロ セ ッ サ例外処理
6.1.4
例外の優先度
複数の例外が同時に発生 し た場合、 こ れ ら の例外は決ま っ た優先度順に処理
さ れ ます。 各例外が順に処理 さ れてか ら 、 ユーザプ ロ グ ラ ムの実行が継続 さ
れます。 すべての例外が同時に発生す る こ と はあ り 得ません。 例えば、 未定義
命令例外 と SVC 例外は、 ど ち ら も あ る 命令の実行に よ っ て ト リ ガ さ れ る た
め、 同時に発生す る こ と はあ り ません。
表 6-2 は、 例外 と それに対応す る プ ロ セ ッ サモー ド お よ び処理の優先度を示
し てい ます。
表 6-2 例外の優先度
ベク タ ア ド レス
例外の タ イ プ
例外モー ド
優先度 (1= 高、 6= 低)
0x0
リ セッ ト
スーパーバ イ ザ
(SVC)
1
0x4
未定義命令
未定義
6
0x8
スーパーバ イ ザ コ ール
(SVC)
スーパーバ イ ザ
(SVC)
6
0xC
プ リ フ ェ ッ チアボー ト
アボー ト
5
0x10
デー タ アボー ト
アボー ト
2
0x14
予約
なし
なし
0x18
割 り 込み (IRQ)
割 り 込み (IRQ)
4
0x1C
高速割 り 込み (FIQ)
高速割 り 込み
(FIQ)
3
デー タ アボー ト 例外は FIQ 例外 よ り も 優先度が高いので、 FIQ の処理前に登
録 さ れます。 デー タ アボー ト ハン ド ラ が起動 し ますが、 制御はす ぐ に FIQ ハ
ン ド ラ に渡 さ れます。 FIQ の処理が完了す る と 、 デー タ アボー ト ハン ド ラ に制
御が戻 り ます。 こ れに よ り 、 FIQ が最初に処理 さ れてデー タ 転送エ ラ ーが検出
を免れ る こ と はあ り ません。
6-6
Copyright © 2007 ARM Limited. All rights reserved.
ARM DUI 0203HJ
プ ロ セ ッ サ例外処理
6.2
プ ロ セ ッ サ状態の判断
例外ハン ド ラ に よ っ て、 例外発生時にプ ロ セ ッ サが ARM 状態 と Thumb® 状態
の ど ち ら にあ っ たか を判断 し なければな ら ない場合があ り ます。
特に、 SVC ハン ド ラ でプ ロ セ ッ サ状態を読み出す必要があ る 場合があ り ま
す。 プ ロ セ ッ サ状態は、 SPSR の T ビ ッ ト を検査す る こ と で参照で き ます。 こ の
ビ ッ ト は、 Thumb 状態ではセ ッ ト さ れ、 ARM 状態では ク リ ア さ れます。
ARM と Thumb の ど ち ら の命令セ ッ ト に も SVC 命令があ り ます。 Thumb 状態か
ら SVC を呼び出す場合には、 以下の点に注意す る 必要があ り ます。
•
命令のア ド レ ス は、 lr - 4 ではな く lr - 2 にあ り ます。
•
命令自体は 16 ビ ッ ト であ る ため、 ハーフ ワー ド を ロ ー ド す る 必要があ
り ます (図 6-1 参照)。
•
SVC 番号は、 ARM 状態の と き の 24 ビ ッ ト でな く 8 ビ ッ ト で保持 さ れ ま
す。
15 14 13 12 11 10 9 8 7
1 1 0 1 1 1 1 1
0
8_bit_immediate
comment field
図 6-1 Thumb SVC 命令
例 6-1 (ページ 6-8) は、 両方の ソ ース か ら の SVC を処理す る ARM コ ー ド を示
し てい ます。
以下に注意 し て下 さ い。
•
各 do_svc_x ルーチン において、 コ ー ド 密度を向上 さ せ る ため、 必要に応
じ て Thumb 状態への切 り 替え と 復帰が実行 さ れ る 可能性があ り ます。
•
switch() ス テー ト メ ン ト を含む C 関数の呼び出 し でジ ャ ン プテーブルを
置 き 換え る こ と に よ っ て SVC を実装で き ます。
ARM DUI 0203HJ
•
SVC 番号は、 呼び出 さ れた と き の状態に応 じ て異な る 方法で処理す る こ
と が可能です。
•
Thumb 状態か ら ア ク セ ス可能な SVC 番号の範囲は、 SVC ハン ド ラ
(ページ 6-20) で説明 さ れてい る よ う に、 SVC を動的に呼び出す こ と に
よ っ て拡張で き ます。
Copyright © 2007 ARM Limited. All rights reserved.
6-7
プ ロ セ ッ サ例外処理
例 6-1 SVC ハン ド ラ
T_bit
EQU
0x20
:
:
SVCHandler
STMFD
MRS
TST
LDRNEH
BICNE
LDREQ
BICEQ
; Thumb bit of CPSR/SPSR, that is,
; bit 5.
sp!, {r0-r3,r12,lr}
r0, spsr
;
;
;
;
;
;
;
;
r0, #T_bit
r0,[lr,#-2]
r0,r0,#0xFF00
r0,[lr,#-4]
r0,r0,#0xFF000000
Store registers.
Move SPSR into
general purpose register.
Occurred in Thumb state?
Yes: load halfword and...
...extract comment field.
No: load word and...
...extract comment field.
; r0 now contains SVC number
CMP
LDRLS
B
r0, #MaxSVC
pc, [pc, r0, LSL#2]
SVCOutOfRange
; Rangecheck
; Jump to the appropriate routine.
svctable
DCD
DCD
:
:
do_svc_1
do_svc_2
do_svc_1
; Handle the SVC.
LDMFD
sp!, {r0-r3,r12,pc}^
; Restore the registers and return.
do_svc_2
:
6-8
Copyright © 2007 ARM Limited. All rights reserved.
ARM DUI 0203HJ
プ ロ セ ッ サ例外処理
6.3
例外の開始 と 終了
こ のセ ク シ ョ ン では、 例外に対す る プ ロ セ ッ サの応答 と 、 例外処理後に例外
発生時の場所に戻 る 方法について説明 し ます。 こ の復帰方法は、 例外 タ イ プ
に よ っ て異な り ます (例外の タ イ プ (ページ 6-4) 参照)。
Thumb 対応プ ロ セ ッ サの基本的な例外処理 メ カ ニズ ムは、 Thumb に対応 し て
いないプ ロ セ ッ サ と 同 じ です。 例外が発生す る と 、 適切なベ ク タ テーブルエ
ン ト リ か ら 次の命令が フ ェ ッ チ さ れます。
Thumb 状態 と ARM 状態の ど ち ら の例外に も 、 同 じ ベ ク タ テーブルが使用 さ
れ ます。 「例外に対す る プ ロ セ ッ サの応答」 で説明 さ れてい る 例外処理手順
に、 ARM 状態への切 り 替え を行 う 最初の ス テ ッ プが加わ り ます。
こ こ か ら は、 Thumb 対応プ ロ セ ッ サに適 し た例外ハン ド ラ を記述す る 際に こ
れ以外に注意 し てお く べ き 点について記載 し ます。
6.3.1
例外に対する プ ロ セ ッ サの応答
例外が生成 さ れ る と 、 プ ロ セ ッ サは以下の よ う に動作 し ます。
1.
カ レ ン ト プ ロ グ ラ ム ス テー タ ス レ ジ ス タ (CPSR) を、 例外が処理 さ れ
る モー ド の 保存プ ロ グ ラ ム ス テー タ ス レ ジ ス タ (SPSR) に コ ピー し ま
す。 こ れに よ り 、 現在のモー ド 、 割 り 込みマ ス ク 、 お よ び条件フ ラ グが
保存 さ れ ます。
ARM DUI 0203HJ
2.
現在の命令セ ッ ト の状態が、 例外ベ ク タ テーブルで使用 さ れてい る 命令
セ ッ ト の状態に一致 し ない場合は、 命令セ ッ ト を自動的に切 り 替え る こ
と がで き ます。 v6T2 よ り 前の ARM アーキ テ ク チ ャ では、 例外ベ ク タ
テーブルは常に ARM 命令を含んでい ま し た。ARM アーキ テ ク チ ャ v6T2
以降は、 例外ベ ク タ テーブルに ARM 命令ま たは Thumb 命令の ど ち ら か
を含め る こ と がで き る よ う にな り ま し た。
3.
以下を行 う ために、 適切な CPSR モー ド ビ ッ ト を変更 し ます。
•
適切なモード に切り 替え、 そのモード の適切なバン ク レ ジス タ に
マッ プする 。
•
割り 込みを 無効にする 。 ど の例外が発生し ても IRQ は無効にさ れま
す。 FIQ は FIQ が発生し たと き と 、 リ セッ ト 時に無効にさ れま す。
4.
復帰ア ド レ ス と 復帰命令 (ページ 6-11) で定義 さ れてい る よ う に、
lr_mode に復帰ア ド レ ス を セ ッ ト し ます。
5.
プ ロ グ ラ ム カ ウ ン タ に、 例外のベ ク タ ア ド レ ス を セ ッ ト し ます。
Copyright © 2007 ARM Limited. All rights reserved.
6-9
プ ロ セ ッ サ例外処理
6.3.2
例外ハン ド ラ か らの復帰
例外か ら の復帰方法は、 例外ハン ド ラ が ス タ ッ ク 処理を行 う か ど う かに よ っ
て異な り ます。 いずれの場合 も 、 実行を例外発生時の場所に戻すには、 例外
ハン ド ラ が以下の処理を行 う 必要があ り ます。
•
spsr_mode か ら CPSR を復元す る 。
•
lr_mode に保存 さ れてい る 復帰ア ド レ ス を使用 し てプ ロ グ ラ ム カ ウ ン タ
を復元す る 。
復帰先のモー ド の レ ジ ス タ を ス タ ッ ク か ら 復元す る 必要のない単純な復帰で
は、 例外ハン ド ラ は以下を使用す る デー タ 処理命令を実行す る こ と に よ っ て、
こ れ ら の処理を行い ます。
•
セ ッ ト さ れた S フ ラ グ
•
復帰先の レ ジ ス タ と し て使用 さ れ る プ ロ グ ラ ム カ ウ ン タ
必要な復帰命令は、 例外 タ イ プに よ っ て異な り ます。 各例外 タ イ プか ら の復
帰方法については、 復帰ア ド レ ス と 復帰命令 (ページ 6-11) を参照 し て下 さ
い。
注
リ セ ッ ト ハン ド ラ は メ イ ン コ ー ド を直接実行す る ため、 リ セ ッ ト ハン ド ラ か
ら 復帰す る 必要はあ り ません。
例外ハン ド ラ のエ ン ト リ コ ー ド が、 ス タ ッ ク を使用 し て例外処理中 も 保存 し
ておかなければな ら ない レ ジ ス タ を格納 し た場合には、 ^ 修飾子を付けた多
重 ロ ー ド 命令を使用 し て復帰で き ます。 例えば、 以下の命令を使用 し て復帰
で き ます。
LDMFD sp!,{r0-r12,pc}^
上記の命令で復帰で き る のは、 以下の レ ジ ス タ が ス タ ッ ク に保存 さ れた場合
です。
•
ハン ド ラ 呼び出 し 時に使用 さ れていたすべての作業レ ジ ス タ
•
復帰ア ド レ ス と 復帰命令 (ページ 6-11) で説明す る デー タ 処理命令 と 同
じ 結果が得 ら れ る よ う に修正 さ れた リ ン ク レ ジ ス タ
^ 修飾子を指定す る こ と で、 CPSR が SPSR か ら 復元 さ れます。 こ の修飾子は、 特
権モー ド か ら 使用す る 必要があ り ます。 ス タ ッ ク 処理の詳細については、
『Assembler Guide』 に記載 さ れてい る 、 LDM お よ び STM を使用 し た ス タ ッ ク の実
装に関す る 説明を参照 し て下 さ い。
6-10
Copyright © 2007 ARM Limited. All rights reserved.
ARM DUI 0203HJ
プ ロ セ ッ サ例外処理
6.3.3
復帰ア ド レ ス と 復帰命令
例外発生時にプ ロ グ ラ ム カ ウ ン タ が指す実際の位置は、 例外 タ イ プに よ っ て
異な り ます。 復帰ア ド レ ス は、 必ず し も プ ロ グ ラ ム カ ウ ン タ が指す次の命令
であ る と は限 り ません。
例外が ARM 状態で発生 し た場合、 プ ロ セ ッ サは pc - 4 を lr_mode に格納 し ま
す。 し か し 、 例外が Thumb 状態で発生 し た場合は、 例外 タ イ プご と に異な る
値がプ ロ セ ッ サに よ っ て自動的に格納 さ れ ます。 こ の よ う な調整が必要な理
由は、 Thumb ま たは Thumb-2 命令では、 ARM 命令が使用 し てい る 32 ビ ッ ト
以外のサ イ ズ を使用 し てい る 場合があ る ためです。
プ ロ セ ッ サが こ の調整を行 う こ と に よ っ て、 ハン ド ラ は例外発生時の命令状
態に関係な く 、 1 つの復帰命令で正 し く 復帰で き ます。
こ れ以降のセ ク シ ョ ン では、 各 タ イ プの例外を処理す る コ ー ド か ら 正 し く 復
帰す る ための命令について示 し ます。
SVC ハン ド ラ お よび未定義命令ハン ド ラ か らの復帰
SVC 例外 と 未定義命令例外は、 命令自身に よ っ て生成 さ れ る ため、 こ れ ら の
例外が発生 し て も プ ロ グ ラ ム カ ウ ン タ は更新 さ れ ません。 プ ロ セ ッ サは pc - 4
を lr_mode に格納 し ます。 こ れに よ り 、 lr_mode は次に実行 さ れ る 命令を指 し
ます。 以下の命令を使用 し て リ ン ク レ ジ ス タ か ら プ ロ グ ラ ム カ ウ ン タ を復元
する と 、
MOVS
pc, lr
ハン ド ラ か ら 制御が戻 さ れます。
以下は、 復帰ア ド レ ス を ス タ ッ ク にプ ッ シ ュ し 、 復帰時にそれを ポ ッ プす る
ハン ド ラ のエ ン ト リ / 終了 コ ー ド を示 し てい ます。
STMFD
;...
LDMFD
sp!,{reglist,lr}
sp!,{reglist,pc}^
Thumb 状態で例外が発生す る 場合を除 き 、こ のハン ド ラ の復帰命令 MOVS pc,lr
に よ っ て、 プ ロ グ ラ ム カ ウ ン タ は次に実行す る 命令のア ド レ ス に変更 さ れ ま
す。 こ のア ド レ ス の値は pc - 2 にあ る ため、 プ ロ セ ッ サが lr_mode に格納す る
値は pc - 2 と な り ます。
ARM DUI 0203HJ
Copyright © 2007 ARM Limited. All rights reserved.
6-11
プ ロ セ ッ サ例外処理
FIQ ハン ド ラ および IRQ ハン ド ラ か らの復帰
各命令の実行後、 プ ロ セ ッ サは割 り 込みピ ンが LOW にセ ッ ト さ れ、 CPSR 内の
割 り 込み無効ビ ッ ト が ク リ ア さ れてい る こ と をチ ェ ッ ク し ます。 こ の結果、
プ ロ グ ラ ム カ ウ ン タ が更新 さ れてい る 場合にのみ IRQ 例外ま たは FIQ 例外が
生成 さ れ ます。 プ ロ セ ッ サは pc - 4 を lr_mode に格納 し ます。 こ れに よ り
lr_mode は、 例外が発生 し た命令の終わ り か ら 1 つ先の命令を指 し ます。 ハン
ド ラ 終了後、 lr_mode が指す命令の前の命令か ら 実行が継続 さ れ る 必要があ り
ます。 実行が再開 さ れ る ア ド レ ス は、 lr_mode の値 よ り も 1 ワ ー ド 少ない値 と
な る ため、 復帰命令は以下の よ う にな り ます。
SUBS
pc, lr, #4
以下は、 復帰ア ド レ ス を ス タ ッ ク にプ ッ シ ュ し 、 復帰時にそれを ポ ッ プす る
ハン ド ラ のエ ン ト リ / 終了 コ ー ド を示 し てい ます。
SUB
STMFD
;...
LDMFD
lr,lr,#4
sp!,{reglist,lr}
sp!,{reglist,pc}^
Thumb 状態で例外が発生す る 場合を除 き 、 こ のハン ド ラ の復帰命令 SUBS
pc,lr,#4 に よ っ て、 プ ロ グ ラ ム カ ウ ン タ は次に実行す る 命令のア ド レ ス に変
更 さ れ ます。 プ ロ グ ラ ム カ ウ ン タ は例外発生前に更新 さ れ る ため、 次の命令
の位置は pc - 4 と な り ます。 し たがっ て、 プ ロ セ ッ サが lr_mode に格納す る 値
は pc と な り ます。
プ リ フ ェ ッ チアボー ト ハン ド ラ か らの復帰
プ ロ セ ッ サが不正ア ド レ ス か ら 命令を フ ェ ッ チ し よ う と す る と 、 その命令に
無効の フ ラ グが立て ら れ ます。 パ イ プ ラ イ ン に既に入っ てい る 命令の実行は、
その無効な命令に到達す る ま で継続 さ れ、 無効な命令に到達 し た時点でプ リ
フ ェ ッ チアボー ト が生成 さ れ ます。
こ の例外ハン ド ラ は、 マ ッ プ さ れていない命令を物理 メ モ リ に ロ ー ド し 、
MMU があれば こ れを使用 し て、 その仮想 メ モ リ の位置を物理 メ モ リ にマ ッ
プ し ます。 その後、 プ リ フ ェ ッ チアボー ト 例外を発生 さ せた命令の再試行に
戻 る 必要があ り ます。 こ れでその命令が ロ ー ド さ れ、 実行 さ れます。
プ リ フ ェ ッ チアボー ト の生成時にはプ ロ グ ラ ム カ ウ ン タ が更新 さ れないため、
lr_ABT は こ の例外を発生 さ せた命令の次の命令を指 し ます。 こ のハン ド ラ は以
下を使用 し て lr_ABTñ4 に復帰す る 必要があ り ます。
SUBS
6-12
pc,lr, #4
Copyright © 2007 ARM Limited. All rights reserved.
ARM DUI 0203HJ
プ ロ セ ッ サ例外処理
以下は、 復帰ア ド レ ス を ス タ ッ ク にプ ッ シ ュ し 、 復帰時にそれを ポ ッ プす る
ハン ド ラ のエ ン ト リ / 終了 コ ー ド を示 し てい ます。
SUB
STMFD
;...
LDMFD
lr,lr,#4
sp!,{reglist,lr}
sp!,{reglist,pc}^
Thumb 状態で例外が発生す る 場合を除 き 、 こ のハン ド ラ の復帰命令 (SUBS
pc,lr,#4) に よ っ て、 プ ロ グ ラ ム カ ウ ン タ はアボー ト さ れた命令のア ド レ ス に
変更 さ れ ます。 プ ロ グ ラ ム カ ウ ン タ は例外発生前に更新 さ れないため、 ア
ボー ト さ れた命令の位置は (pc - 4) と な り ます。 し たが っ て、 プ ロ セ ッ サが
lr_mode に格納す る 値は pc と な り ます。
デー タ アボー ト ハン ド ラ か らの復帰
ロ ー ド 命令ま たは ス ト ア命令に よ っ て メ モ リ へのア ク セ ス が試行 さ れ る と き 、
プ ロ グ ラ ム カ ウ ン タ は更新 さ れてい ます。 lr_ABT に格納 さ れ る pc - 4 の値は、
例外が発生 し た ア ド レ ス か ら 2 つ先の命令を指 し ます。 MMU が存在 し 、
MMU に よ っ て適切な ア ド レ ス が物理 メ モ リ にマ ッ プ さ れた場合には、 ア
ボー ト さ れた命令の実行を再試行で き る よ う に、 デー タ アボー ト ハン ド ラ は
こ のアボー ト さ れた元の命令に戻 る 必要があ り ます。 し たがっ て復帰ア ド レ
ス は lr_ABT の値 よ り も 2 ワー ド 少ない値 と な り 、 復帰命令は以下の よ う にな
り ます。
SUBS
pc, lr, #8
以下は、 復帰ア ド レ ス を ス タ ッ ク にプ ッ シ ュ し 、 復帰時にそれを ポ ッ プす る
ハン ド ラ のエ ン ト リ / 終了 コ ー ド を示 し てい ます。
SUB
STMFD
;...
LDMFD
lr,lr,#8
sp!,{reglist,lr}
sp!,{reglist,pc}^
Thumb 状態で例外が発生す る 場合を除 き 、 こ のハン ド ラ の復帰命令 SUBS
pc,lr,#8 に よ っ て、 プ ロ グ ラ ム カ ウ ン タ はアボー ト さ れた命令のア ド レ ス に
変更 さ れ ます。 プ ロ グ ラ ム カ ウ ン タ は例外発生前に更新 さ れ る ため、 アボー
ト さ れた命令の位置は pc - 6 と な り ます。 し たがっ て、 プ ロ セ ッ サが lr_mode
に格納す る 値は pc + 2 と な り ます。
ARM DUI 0203HJ
Copyright © 2007 ARM Limited. All rights reserved.
6-13
プ ロ セ ッ サ例外処理
6.4
例外処理
ト ッ プ レベルのベニ アルーチン では、 プ ロ セ ッ サの ス テー タ ス と 必要なすべ
ての レ ジ ス タ を ス タ ッ ク に保存す る 必要があ り ます。 例外ハン ド ラ を記述す
る 際には、 以下の方法を使用で き ます。
•
例外ハン ド ラ 全体を ARM コ ー ド で記述す る 。
•
プ ロ セ ッ サが Thumb2 命令を サポー ト し てい る 場合は、 例外ハン ド ラ 全
体を Thumb-2 コ ー ド で記述す る 。
•
ARM コ ー ド の ト ッ プ レベルのハン ド ラ か ら 、 例外を処理す る Thumb
コ ー ド ルーチンへの 分岐 と 切 り 替え (BX) を実行す る 。 Thumb-1 命令
セ ッ ト には SPSR か ら CPSR を復元で き る 命令がないため、 例外か ら 復帰
す る には ARM コ ー ド ま たは Thumb-2 コ ー ド を使用す る 必要があ り ま
す。
図 6-2 は、 こ の実装方法を示 し てい ます。
Thumb coded
application
Vector table
Switch to
ARM state
ARM coded
veneers
Save CPU and
register state
Entry Veneer
Switch to Thumb
state and return
Restore CPU and
register state
Thumb coded
handler
Switch to
Thumb state
Handle the
exception
Switch to
ARM state
Exit veneer
図 6-2 ARM 状態または Thumb 状態での例外処理
こ の よ う に ARM コ ー ド と Thumb コ ー ド を組み合わせ る 方法について
は、 「第 4 章 ARM と Thumb の イ ン タ ーワー ク 」 を参照 し て下 さ い。
6-14
Copyright © 2007 ARM Limited. All rights reserved.
ARM DUI 0203HJ
プ ロ セ ッ サ例外処理
6.5
例外ハン ド ラのイ ン ス ト ール
新 し い例外ハン ド ラ はベ ク タ テーブルに イ ン ス ト ール さ れ る 必要があ り ます。
イ ン ス ト ールが完了す る と 、 その新 し いハン ド ラ は、 対応す る 例外が発生す
る たびに実行 さ れます。
6.5.1
例外ハン ド ラ を イ ン ス ト ールする方法
例外ハン ド ラ は以下の方法で イ ン ス ト ールで き ます。
分岐命令
例外ハン ド ラ への到達に使用で き る 最 も 簡単な方法です。 ベ ク タ
テーブル内の各エ ン ト リ には、 必要 と さ れ る ハン ド ラ ルーチン
への分岐が保持 さ れ ます。 し か し 、 こ の方法には制限があ り ま
す。 分岐命令の範囲は pc に相対 し て 32MB の範囲内に限定 さ れ
る ため、 メ モ リ 構成に よ っ ては分岐でハン ド ラ に到達す る こ と
が不可能な場合があ り ます。
ロ ー ド PC 命令
こ の方法では、 以下の処理に よ っ てプ ロ グ ラ ム カ ウ ン タ にハン
ド ラ のア ド レ ス を直接参照 さ せます。
6.5.2
1.
ハン ド ラ の絶対ア ド レ ス を適切な メ モ リ 位置、 つま り ベ ク
タ ア ド レ ス か ら 4KB 以内に格納 し ます。
2.
選択 し た メ モ リ 位置の内容を プ ロ グ ラ ム カ ウ ン タ に ロ ー ド
す る 命令をベ ク タ 内に配置 し ます。
リ セ ッ ト 時のハン ド ラのイ ン ス ト ール
アプ リ ケーシ ョ ンがプ ロ グ ラ ムの実行開始をデバ ッ ガ ま たはデバ ッ グモニ タ
に依存 し ていない場合には、 アセ ン ブ リ 言語の リ セ ッ ト ま たは起動 コ ー ド か
ら ベ ク タ テーブルを直接 ロ ー ド で き ます。
ROM が メ モ リ 内の 0x0 に配置 さ れてい る 場合は、 コ ー ド の開始部分に各ベ ク
タ の分岐ス テー ト メ ン ト を記述で き ます。 FIQ ハン ド ラ が 0x1C か ら 直接実行
さ れ る 場合は、 こ の中に FIQ ハン ド ラ を含め る こ と も 可能です (割 り 込みハ
ン ド ラ (ページ 6-30) 参照)。
例 6-2 (ページ 6-16) は、 ア ド レ ス 0 にあ る ROM にベ ク タ が配置 さ れてい る
場合に、 こ れ ら のベ ク タ を セ ッ ト ア ッ プす る コ ー ド を示 し てい ます。 ロ ー ド
命令の代わ り に分岐ス テー ト メ ン ト を使用で き ます。
ARM DUI 0203HJ
Copyright © 2007 ARM Limited. All rights reserved.
6-15
プ ロ セ ッ サ例外処理
例 6-2
Vector_Init_Block
LDR
LDR
LDR
LDR
LDR
NOP
LDR
LDR
Reset_Addr
Undefined_Addr
SVC_Addr
Prefetch_Addr
Abort_Addr
IRQ_Addr
FIQ_Addr
DCD
DCD
DCD
DCD
DCD
DCD
DCD
DCD
pc,
pc,
pc,
pc,
pc,
Reset_Addr
Undefined_Addr
SVC_Addr
Prefetch_Addr
Abort_Addr
;Reserved vector
pc, IRQ_Addr
pc, FIQ_Addr
Start_Boot
Undefined_Handler
SVC_Handler
Prefetch_Handler
Abort_Handler
0
;Reserved vector
IRQ_Handler
FIQ_Handler
リ セ ッ ト 時には 0x0 に ROM が配置 さ れ る よ う に設定す る 必要があ り ます。 リ
セ ッ ト コ ー ド を記述 し て、 RAM を 0x0 に リ マ ッ プで き ます。 こ の リ マ ッ プ を
行 う 前に、 リ セ ッ ト コ ー ド で ROM 内の領域か ら ベ ク タ 、 お よ び必要に応 じ
て FIQ ハン ド ラ を コ ピー し 、 RAM に配置す る 必要があ り ます。
こ の場合は、 リ セ ッ ト ベ ク タ コ ー ド を位置非依存にで き る よ う 、 LDR pc 命令を
使用 し て リ セ ッ ト ハン ド ラ のア ド レ ス を指定す る 必要があ り ます。
例 6-2 では、 例 6-3 に示すベ ク タ が RAM 内のベ ク タ テーブルに コ ピー さ れ ま
す。
例 6-3
MOV
ADR
LDMIA
STMIA
LDMIA
STMIA
6-16
r8, #0
r9, Vector_Init_Block
r9!,{r0-r7}
;Copy the vectors (8 words)
r8!,{r0-r7}
r9!,{r0-r7}
;Copy the DCD'ed addresses
r8!,{r0-r7}
;(8 words again)
Copyright © 2007 ARM Limited. All rights reserved.
ARM DUI 0203HJ
プ ロ セ ッ サ例外処理
別の方法 と し ては、 分散 ロ ー ド メ カ ニズ ム を使用 し て、 ベ ク タ テーブルの
ロ ー ド / 実行ア ド レ ス を定義す る こ と も で き ます。 こ の場合は、 C ラ イ ブ ラ リ
に よ っ てベ ク タ テーブルが コ ピー さ れ ます (「第 2 章 組み込み ソ フ ト ウ ェ ア
の開発」 参照)。
6.5.3
C 言語から のハン ド ラ のイ ン ス ト ール
開発過程においては、 例外ハン ド ラ を メ イ ン アプ リ ケーシ ョ ン か ら ベ ク タ に
直接 イ ン ス ト ール し なければな ら ない場合があ り ます。 こ の よ う な場合には、
必要 と さ れ る 命令エ ン コ ーデ ィ ン グ処理を適切なベ ク タ ア ド レ ス に記述す る
必要があ り ます。 こ の作業は、 ハン ド ラ への到達に分岐命令を使用す る 方法
と 、 プ ロ グ ラ ム カ ウ ン タ を ロ ー ド す る 方法の両方で行 う こ と がで き ます。
分岐方式
必要な命令は以下の よ う に構成で き ます。
1.
例外ハン ド ラ のア ド レ ス を取得 し ます。
2.
そのア ド レ ス か ら 、 対応す る ベ ク タ のア ド レ ス を減算 し ます。
3.
プ リ フ ェ ッ チ分の 0x8 を減算 し ます。
4.
バ イ ト オ フ セ ッ ト ではな く ワー ド オ フ セ ッ ト にな る よ う に、 上記の結果
を 2 だけ右にシ フ ト し ます。
5.
得 ら れた値の長 さ が 24 ビ ッ ト であ る こ と を確認す る ため、 上位 8 ビ ッ
ト が ク リ ア さ れてい る こ と を確認 し ます。
6.
こ の結果 と 分岐命令のオペ コ ー ド 、 0xEA000000 と の論理和を取 り 、 ベ ク
タ に配置す る 値を求め ます。
例 6-4 (ページ 6-18) は、 こ のアルゴ リ ズ ム を実装す る C 関数を示 し てい ま
す。
こ の C 関数は以下の引数を取 り ます。
•
•
ハン ド ラ のア ド レ ス
ハン ド ラ の イ ン ス ト ール先ベ ク タ のア ド レ ス
こ の関数でハン ド ラ を イ ン ス ト ール し た り 、 ベ ク タ の元の内容を戻 し た り す
る こ と がで き ます。 こ の結果を使用 し て、 特定の例外に使用 さ れ る ハン ド ラ
のチ ェ イ ン を作成で き ます。
ARM DUI 0203HJ
Copyright © 2007 ARM Limited. All rights reserved.
6-17
プ ロ セ ッ サ例外処理
以下の コ ー ド で上記のルーチン を呼び出 し 、 IRQ ハン ド ラ を イ ン ス ト ール し
ます。
unsigned *irqvec = (unsigned *)0x18;
Install_Handler ((unsigned)IRQHandler, irqvec);
こ の場合、 戻 さ れた IRQ ベ ク タ の元の内容は破棄 さ れ ます。
例 6-4 分岐方式の実装
unsigned Install_Handler (unsigned routine, unsigned *vector)
/* Updates contents of 'vector' to contain branch instruction */
/* to reach ’routine’ from ’vector’. Function return value is */
/* original contents of 'vector'.*/
/* NB: ’Routine’ must be within range of 32MB from ’vector’.*/
{
unsigned vec, oldvec;
vec = ((routine - (unsigned)vector - 0x8)>>2);
if ((vec & 0xFF000000))
{
/* diagnose the fault */
printf ("Installation of Handler failed");
exit (1);
}
vec = 0xEA000000 | vec;
oldvec = *vector;
*vector = vec;
return (oldvec);
}
PC のロー ド 方法
必要な命令は以下の よ う に構成で き ます。
6-18
1.
例外ハン ド ラ のア ド レ ス を含む ワ ー ド のア ド レ ス を取得 し ます。
2.
そのア ド レ ス か ら 、 対応す る ベ ク タ のア ド レ ス を減算 し ます。
3.
プ リ フ ェ ッ チ分の 0x8 を減算 し ます。
4.
結果が 12 ビ ッ ト で表現 さ れてい る こ と を確認 し ます。
5.
こ の結果 と LDR pc, [pc,#offset] のオペ コ ー ド 、0xe59FF000 と の論理和を取
り 、 ベ ク タ に配置す る 値を求め ます。
6.
こ のハン ド ラ のア ド レ ス を記憶位置に配置 し ます。
Copyright © 2007 ARM Limited. All rights reserved.
ARM DUI 0203HJ
プ ロ セ ッ サ例外処理
例 6-5 (ページ 6-19) は、 こ の方式を実装す る C ルーチン を示 し てい ます。
こ の例で も 、 戻 さ れ る 元の IRQ ベ ク タ の内容は破棄 さ れ ますが、 こ の内容を
使用 し てハン ド ラ のチ ェ イ ン を作成で き る 場合があ り ます。
例 6-5 プ ログ ラ ム カ ウン タ を ロー ド する方法の実装
unsigned Install_Handler (unsigned location, unsigned *vector)
/* Updates contents of 'vector' to contain LDR pc, [pc, #offset] */
/* instruction to cause long branch to address in 'location'. */
/* Function return value is original contents of 'vector'. */
{
unsigned vec, oldvec;
vec = ((unsigned)location - (unsigned)vector - 0x8) | 0xe59ff000;
oldvec = *vector;
*vector = vec;
return (oldvec);
}
以下の コ ー ド で上記のルーチン を呼び出 し 、 IRQ ハン ド ラ を イ ン ス ト ール し
ます。
unsigned *irqvec = (unsigned *)0x18;
static unsigned pIRQ_Handler = (unsigned)IRQ_handler
Install_Handler (&pIRQHandler, irqvec);
注
命令キ ャ ッ シ ュ と デー タ キ ャ ッ シ ュ が分離 さ れてい る プ ロ セ ッ サ を使用す る
場合は、 キ ャ ッ シ ュ コ ヒ ーレ ン シの問題がベ ク タ の新 し い内容を使用す る と
き の妨げにな ら ない よ う に注意す る 必要があ り ます。
デー タ キ ャ ッ シ ュ 、 ま たは少な く と も 修正 さ れたベ ク タ を含むエ ン ト リ は、
新 し いベ ク タ の内容を メ イ ン メ モ リ に書 き 込め る よ う に、 削除す る 必要があ
り ます。 次に、 新 し いベ ク タ の内容を メ イ ン メ モ リ か ら 読み出せ る よ う に、
命令キ ャ ッ シ ュ を フ ラ ッ シ ュ す る 必要があ り ます。
キ ャ ッ シ ュ の削除 と フ ラ ッ シ ュ については、 タ ーゲ ッ ト プ ロ セ ッ サのテ ク ニ
カル リ フ ァ レ ン ス マニ ュ アルを参照 し て下 さ い。
ARM DUI 0203HJ
Copyright © 2007 ARM Limited. All rights reserved.
6-19
プ ロ セ ッ サ例外処理
6.6
SVC ハン ド ラ
こ のセ ク シ ョ ン では、 SVC ハン ド ラ について説明 し ます。
6.6.1
呼び出す SVC の決定
SVC ハン ド ラ は起動時に、 ど の SVC が呼び出 さ れてい る か を特定す る 必要が
あ り ます。 こ の情報は、 図 6-3 に示す よ う に命令自体の 0 ~ 23 ビ ッ ト に保存
す る か、 1 つの整数レ ジ ス タ に渡 さ れます。 通常、 こ の整数レ ジ ス タ には r0
~ r3 のいずれかが使用 さ れ ます。
31
28 27 26 25 24 23
cond
1 1 1 1
0
24_bit_immediate
comment field
図 6-3 ARM SVC 命令
ト ッ プ レベルの SVC ハン ド ラ では、 SVC 命令を リ ン ク レ ジ ス タ の相対ア ド レ
ス に ロ ー ド で き ます。 こ の ロ ー ド は、 アセ ン ブ リ 言語か、 C/C++ イ ン ラ イ ン
アセ ン ブ ラ ま たは組み込みアセ ンブ ラ で行い ます。
SVC ハン ド ラ は、 まず例外を発生 さ せた SVC 命令を レ ジ ス タ に ロ ー ド す る 必
要があ り ます。 こ の時点で lr_SVC には SVC 命令の次の命令のア ド レ ス が保持 さ
れてい る ため、 こ の SVC 命令は以下を使用 し て レ ジ ス タ ( こ の場合は r0) に
ロ ー ド さ れ ます。
LDR r0, [lr,#-4]
SVC ハン ド ラ は次に コ メ ン ト フ ィ ール ド ビ ッ ト を検査 し 、 要求 さ れてい る 処
理を特定 し ます。 SVC 番号は、 オペ コ ー ド の上位 8 ビ ッ ト を ク リ アす る こ と
に よ っ て抽出 さ れます。
BIC r0, r0, #0xFF000000
例 6-6 (ページ 6-21) は、 こ れ ら の命令を組み合わせて ト ッ プ レベルの SVC
ハン ド ラ を形成す る 方法を示 し てい ます。
ARM 状態 と Thumb 状態の SVC 命令を処理す る ハン ド ラ の例については、 プ ロ
セ ッ サ状態の判断 (ページ 6-7) を参照 し て下 さ い。
6-20
Copyright © 2007 ARM Limited. All rights reserved.
ARM DUI 0203HJ
プ ロ セ ッ サ例外処理
例 6-6 ト ッ プ レ ベルの SVC ハン ド ラ
PRESERVE8
AREA TopLevelSVC, CODE, READONLY
EXPORT
SVC_Handler
SVC_Handler
STMFD
sp!,{r0-r12,lr}
LDR
r0,[lr,#-4]
BIC
r0,r0,#0xff000000
; Name this block of code.
;
;
;
;
;
Store registers.
Calculate address of SVC instruction
and load it into r0.
Mask off top 8 bits of instruction
to give SVC number.
;
; Use value in r0 to determine which SVC routine to execute.
;
LDMFD
sp!, {r0-r12,pc}^
; Restore registers and return.
END
; Mark end of this file.
6.6.2
アセ ン ブ リ 言語を使用 し た SVC ハン ド ラ
要求 さ れた SVC 番号のハン ド ラ を呼び出す最 も 簡単な方法は、 ジ ャ ン プテー
ブルを使用す る 方法です。 r0 に SVC 番号が含まれてい る 場合、 例 6-7 に示 し
た コ ー ド を、 例 6-6 の ト ッ プ レベルハン ド ラ の BIC 命令に続けて挿入で き ま
す。
例 6-7 SVC ジ ャ ン プ テーブル
CMP
r0,#MaxSVC
; Range check
LDRLS pc, [pc,r0,LSL #2]
B
SVCOutOfRange
SVCJumpTable
DCD
SVCnum0
DCD
SVCnum1
; DCD for each of other SVC routines
SVCnum0
; SVC number 0 code
B
EndofSVC
SVCnum1
; SVC number 1 code
B
EndofSVC
; Rest of SVC handling code
;
EndofSVC
ARM DUI 0203HJ
Copyright © 2007 ARM Limited. All rights reserved.
6-21
プ ロ セ ッ サ例外処理
; Return execution to top level
; SVC handler so as to restore
; registers and return to program.
6.6.3
C 言語お よびア セ ン ブ リ 言語を使用 し た SVC ハン ド ラ
ト ッ プ レベルのハン ド ラ は常に ARM アセ ン ブ リ 言語で記述す る 必要があ り
ますが、 各 SVC を処理す る ルーチンはアセ ン ブ リ 言語で も C 言語で も 記述で
き ます。 こ の点に関す る 制約条件については、 スーパーバ イ ザモー ド での
SVC の使用 (ページ 6-23) を参照 し て下 さ い。
ト ッ プ レベルのハン ド ラ では、 リ ン ク 付 き分岐 (BL) 命令を使用 し て適切な
C 関数にジ ャ ン プ し ます。 SVC 番号はアセ ンブ リ ルーチンに よ っ て r0 に ロ ー
ド さ れ る ため、 こ の値は最初のパ ラ メ ー タ と し て C 関数に渡 さ れ ます。 C 関
数は こ の値を switch() ス テー ト メ ン ト な ど で使用で き ます。
例 6-6 (ページ 6-21) の SVC_Handler ルーチンには、 以下の行を追加で き ます。
BL
C_SVC_Handler
; Call C routine to handle the SVC
例 6-8 は、 C 関数の実装方法を示 し てい ます。
例 6-8
void C_SVC_handler (unsigned number)
{
switch (number)
{
case 0 :
/* SVC number 0 code */
break;
case 1 :
/* SVC number 1 code */
break;
...
default :
/* Unknown SVC - report error */
}
}
場合に よ っ て スーパーバ イ ザ ス タ ッ ク 空間には制限があ る ため、 大量の ス
タ ッ ク 空間を必要 と す る 関数の使用は避けて下 さ い。
MOV
BL
6-22
r1, sp
C_SVC_Handler
; Second parameter to C routine...
; ...is pointer to register values.
; Call C routine to handle the SVC
Copyright © 2007 ARM Limited. All rights reserved.
ARM DUI 0203HJ
プ ロ セ ッ サ例外処理
ト ッ プ レベルのハン ド ラ が ス タ ッ ク ポ イ ン タ の値を第 2 パ ラ メ ー タ と し て r1
の C 関数に渡 し 、 C 関数が こ の値にア ク セ スす る ために更新 さ れ る 場合には、
C 言語で記述 し た SVC ハン ド ラ と の間で値を受け渡す こ と がで き ます。
void C_SVC_handler(unsigned number, unsigned *reg)
こ れで こ の C 関数は、 メ イ ン アプ リ ケーシ ョ ン コ ー ド 内で SVC 命令が検出 さ
れた と き に レ ジ ス タ に保持 さ れてい る 値にア ク セ ス で き ます (図 6-4 参照)。
値は レ ジ ス タ か ら 以下の よ う に読み出 し 、
value_in_reg_0
value_in_reg_1
value_in_reg_2
value_in_reg_3
=
=
=
=
reg
reg
reg
reg
[0];
[1];
[2];
[3];
以下の よ う に書 き 戻 し ます。
reg
reg
reg
reg
[0]
[1]
[2]
[3]
=
=
=
=
updated_value_0;
updated_value_1;
updated_value_2;
updated_value_3;
こ れに よ り 、 更新 さ れた値が適切な ス タ ッ ク 位置に書 き 込まれ、 ト ッ プ レベ
ルのハン ド ラ に よ っ て レ ジ ス タ に復元 さ れ ます。
Previous sp_SVC
lr_SVC
r3
reg[3]
r2
r1
sp_SVC
r0
reg[0]
図 6-4 スーパーバイザス タ ッ クへのア ク セス
6.6.4
スーパーバイザモー ド での SVC の使用
SVC 命令が実行 さ れ る 場合、 以下の よ う にな り ます。
ARM DUI 0203HJ
1.
プ ロ セ ッ サが スーパーバ イ ザモー ド に入 り ます。
2.
CPSR が spsr_SVC に格納 さ れます。
Copyright © 2007 ARM Limited. All rights reserved.
6-23
プ ロ セ ッ サ例外処理
3.
復帰ア ド レ ス が lr_SVC に格納 さ れます (例外に対す る プ ロ セ ッ サの応答
(ページ 6-9) 参照)。
プ ロ セ ッ サが既に スーパーバ イ ザモー ド にあ る と き は、 lr_SVC と spsr_SVC が破
壊 さ れます。
スーパーバ イ ザモー ド で SVC を呼び出す場合は、 リ ン ク レ ジ ス タ と SPSR の元
の値が失われない よ う に、 lr_SVC お よ び spsr_SVC を保存 し てお く 必要があ り ま
す。 例えば、 特定の SVC 番号のハン ド ラ ルーチン が別の SVC を呼び出す場合
は、 そのハン ド ラ ルーチン で lr_SVC と spsr_SVC の両方を ス タ ッ ク に格納す る
必要があ り ます。 こ の動作の結果、 ハン ド ラ が呼び出 さ れ る ご と に、 ハン ド
ラ を呼び出 し た SVC に続 く 命令に復帰す る ために必要な情報が保存 さ れ る こ
と が保証 さ れ ます。 例 6-9 は、 こ の方法を示 し てい ます。
例 6-9 SVC ハン ド ラ
AREA SVC_Area, CODE, READONLY
PRESERVE8
EXPORT SVC_Handler
IMPORT C_SVC_Handler
T_bit EQU 0x20
SVC_Handler
STMFD
MOV
MRS
STMFD
sp!,{r0-r3,r12,lr}
r1, sp
r0, spsr
sp!, {r0, r3}
TST r0, #T_bit
LDRNEH r0,[lr,#-2]
BICNE r0,r0,#0xFF00
LDREQ r0,[lr,#-4]
BICEQ r0,r0,#0xFF000000
;
;
;
;
;
Store registers.
Set pointer to parameters.
Get spsr.
Store spsr onto stack and another register to maintain
8-byte-aligned stack. Only really needed in case of nested SVCs.
;
;
;
;
;
Occurred in Thumb state?
Yes: load halfword and...
...extract comment field.
No: load word and...
...extract comment field.
; r0 now contains SVC number
; r1 now contains pointer to stacked registers
BL
LDMFD
MSR
6-24
C_SVC_Handler
sp!, {r0, r3}
spsr_cf, r0
; Call C routine to handle the SVC.
; Get spsr from stack.
; Restore spsr.
Copyright © 2007 ARM Limited. All rights reserved.
ARM DUI 0203HJ
プ ロ セ ッ サ例外処理
LDMFD
sp!, {r0-r3,r12,pc}^ ; Restore registers and return.
END
C/C++ で記述 し た入れ子構造の SVC
C ま たは C++ で入れ子にな っ た SVC を記述で き ます。 ARM コ ンパ イ ラ に よ っ
て生成 さ れ る コ ー ド は、 必要に応 じ て lr_SVC の ス ト ア と 再 ロ ー ド を実行 し ま
す。
6.6.5
ア プ リ ケーシ ョ ンか らの SVC の呼び出 し
SVC はアセ ンブ リ 言語ま たは C/C++ か ら 呼び出す こ と がで き ます。
アセ ン ブ リ 言語では、 必要な レ ジ ス タ 値を設定 し て関連 SVC を発行 し ます。
以下に例を示 し ます。
MOV
SVC
r0, #65
0x0
; load r0 with the value 65
; Call SVC 0x0 with parameter value in r0
SVC 命令は、 ほぼすべての ARM 命令 と 同 じ よ う に、 条件付 き で実行で き ま
す。
C/C++ か ら は SVC を __SVC 関数 と し て宣言 し 、 こ れを呼び出 し ます。 以下に例
を示 し ます。
__svc(0) void my_svc(int);
.
.
.
my_svc(65);
こ れに よ り 、 以下の条件下で、 呼び出 し のオーバーヘ ッ ド を新たに発生 さ せ
る こ と な く SVC を イ ン ラ イ ン で コ ンパ イ ルで き ます。
•
すべての引数を r0 ~ r3 のみで渡す。
•
すべての結果を r0 ~ r3 のみで返す。
SVC が実際の関数呼び出 し であ る かの よ う に、 パ ラ メ ー タ が SVC に渡 さ れま
す。 し か し 、 2 ~ 4 個の戻 り 値があ る 場合には、 それ ら の戻 り 値が構造体で返
さ れ る こ と を コ ンパ イ ラ に通知す る 必要があ る ため、 __value_in_regs デ ィ レ ク
テ ィ ブ を使用 し ます。 こ れは通常、 struct の値を取 る 関数が、 結果の構造体が
配置 さ れ る ア ド レ ス を第 1 引数に取 る void 関数 と 同 じ よ う に処理 さ れ る ため
です。
ARM DUI 0203HJ
Copyright © 2007 ARM Limited. All rights reserved.
6-25
プ ロ セ ッ サ例外処理
例 6-10 お よ び例 6-11 は、 0x0、 0x1、 0x2、 お よ び 0x3 の 4 つの SVC 番号を取 る
SVC ハン ド ラ を示 し てい ます。 SVC 0x0 お よ び 0x1 は、 それぞれ 2 つの整数パ
ラ メ ー タ を使用 し 、 1 つの結果を返 し ます。 SVC 0x2 は 4 つのパ ラ メ ー タ を使
用 し 、 1 つの結果を返 し ます。 SVC 0x3 は 4 つのパ ラ メ ー タ を使用 し 、 4 つの結
果を返 し ます。 こ のサン プルは、 メ イ ンサン プルデ ィ レ ク ト リ ...\svc\main.c
お よ び ...\svc\svc.h に収録 さ れてい ます。
例 6-10 main.c
#include <stdio.h>
#include "svc.h"
unsigned *svc_vec = (unsigned *)0x08;
extern void SVC_Handler(void);
int main( void )
{
int result1, result2;
struct four_results res_3;
Install_Handler( (unsigned) SVC_Handler, svc_vec );
printf("result1 = multiply_two(2,4) = %d\n", result1 = multiply_two(2,4));
printf("result2 = multiply_two(3,6) = %d\n", result2 = multiply_two(3,6));
printf("add_two( result1, result2 ) = %d\n", add_two( result1, result2 ));
printf("add_multiply_two(2,4,3,6) = %d\n", add_multiply_two(2,4,3,6));
res_3 = many_operations( 12, 4, 3, 1 );
printf("res_3.a = %d\n", res_3.a );
printf("res_3.b = %d\n", res_3.b );
printf("res_3.c = %d\n", res_3.c );
printf("res_3.d = %d\n", res_3.d );
return 0;
}
例 6-11 svc.h
__svc(0) int multiply_two(int, int);
__svc(1) int add_two(int, int);
__svc(2) int add_multiply_two(int, int, int, int);
struct four_results
{
int a;
int b;
int c;
int d;
6-26
Copyright © 2007 ARM Limited. All rights reserved.
ARM DUI 0203HJ
プ ロ セ ッ サ例外処理
};
__svc(3) __value_in_regs struct four_results
many_operations(int, int, int, int);
6.6.6
ア プ リ ケーシ ョ ンか らの動的な SVC の呼び出 し
状況に よ っ ては、 SVC 番号が実行時ま でわか ら ない SVC を呼び出 さ なければ
な ら ない場合があ り ます。 こ の よ う な状況は、 例えば 1 つのオブジ ェ ク ト 上で
実行 さ れ る 複数の処理が関連 し 合っ ていて、 各処理ご と に SVC があ る よ う な
場合に発生 し ます。 こ の よ う な場合には、 前述の方法は適切ではあ り ません。
こ の状況には、 以下の よ う な方法で対処で き ます。
•
SVC 番号から SVC 命令を 構成し 、 それを ど こ かに格納し た後で実行する 。
•
それ自身の引数に対 し て実行 さ れ る 実際の処理のための コ ー ド を別の引
数 と し て取 る 汎用 SVC を使用す る 。 こ の汎用 SVC に よ っ て処理がデ
コ ー ド さ れ、 実行 さ れ ます。
2 番目の方法 と し ては、 要求 さ れ る 処理を示す値を レ ジ ス タ (通常は r0 ま た
は r12) に渡す こ と で、 アセ ン ブ リ 言語で実装で き ます。 こ れで、 SVC ハン ド
ラ が適切な レ ジ ス タ 内の値を基に動作す る よ う に書 き 直す こ と がで き ます。
場合に よ っ ては値を コ メ ン ト フ ィ ール ド の SVC に渡す必要があ る ため、 こ れ
ら の 2 つの方法を組み合わせて使用す る こ と も あ り ます。
例えば、 オペレーテ ィ ン グ シ ス テ ム が 1 つの SVC 命令 し か使用せず、 レ ジ ス タ
を使用 し て要求 さ れ る 処理番号を渡す と し ます。 こ の場合は残 り の SVC 空間
を アプ リ ケーシ ョ ン固有の SVC に使用す る こ と がで き ます。 こ の方法は、 特
定のアプ リ ケーシ ョ ン で、 命令か ら の処理番号の抽出にかか る オーバーヘ ッ
ド が大 き すぎ る 場合に利用で き ます。 ARM お よ び Thumb のセ ミ ホ ス テ ッ ド 命
令は、 こ の方法で実装 さ れます。
例 6-12 (ページ 6-28) は、 C の関数呼び出 し を セ ミ ホ ス テ ィ ン グ呼び出 し に
対応付け る と き の __svc の使用方法を示 し てい ます。 こ のサン プルは、 メ イ ン
サ ンプルデ ィ レ ク ト リ ...\emb_sw_dev\source\retarget.c の retarget.c に収録 さ
れてい ます。
ARM DUI 0203HJ
Copyright © 2007 ARM Limited. All rights reserved.
6-27
プ ロ セ ッ サ例外処理
例 6-12 C 関数のセ ミ ホス テ ィ ング呼び出 し への対応付け
#ifdef __thumb
/* Thumb Semihosting */
#define SemiSVC 0xAB
#else
/* ARM Semihosting */
#define SemiSVC 0x123456
#endif
/* Semihosting call to write a character */
__svc(SemiSVC) void Semihosting(unsigned op, char *c);
#define WriteC(c) Semihosting (0x3,c)
void write_a_character(int ch)
{
char tempch = ch;
WriteC( &tempch );
}
コ ンパ イ ラ には、 r12 を使用 し て要求 さ れ る 処理番号の受け渡 し を行 う ための
メ カ ニズ ムが組み込ま れてい ます。 AAPCS では r12 は ip レ ジ ス タ であ り 、 関
数呼び出 し の間だけ専用の役割が与え ら れ ます。 それ以外の と き は、 こ の レ
ジ ス タ を ス ク ラ ッ チ レ ジ ス タ と し て使用で き ます。 前述の と お り 、 汎用 SVC
への引数は レ ジ ス タ r0 ~ r3 で渡 さ れ、 それ ら の値は必要に応 じ て r0 ~ r3 に
返 さ れます ( アプ リ ケーシ ョ ンか ら の SVC の呼び出 し (ページ 6-25) 参照)。
r12 に渡す処理番号は、 汎用 SVC に よ っ て呼び出 さ れ る SVC の値にす る こ と
がで き ますが、 必ず し も そ う す る 必要はあ り ません。
例 6-13 は、 汎用 SVC、 つま り 間接 SVC を使用す る C コ ー ド を示 し てい ます。
例 6-13
__svc_indirect(0x80)
unsigned SVC_ManipulateObject(unsigned operationNumber,
unsigned object,unsigned parameter);
unsigned DoSelectedManipulation(unsigned object,
unsigned parameter, unsigned operation)
{ return SVC_ManipulateObject(operation, object, parameter);
}
6-28
Copyright © 2007 ARM Limited. All rights reserved.
ARM DUI 0203HJ
プ ロ セ ッ サ例外処理
こ れに よ っ て以下の コ ー ド が生成 さ れます。
DoSelectedManipulation PROC
STMFD
sp!,{r3,lr}
MOV
r12,r2
SVC
0x80
LDMFD
sp!,{r3,pc}
ENDP
ま た、 __svc の メ カ ニズ ム を使用 し て、 C 言語か ら SVC 番号を r0 に入れて渡
す こ と も 可能です。 例えば、 SVC 0x0 が汎用 SVC と し て使用 さ れ、 処理 0 が文
字の読み出 し 、 処理 1 が文字の書 き 込みであ る 場合は、 以下の よ う に設定で
き ます。
__svc (0) char __ReadCharacter (unsigned op);
__svc (0) void __WriteCharacter (unsigned op, char c);
上記は、 以下の よ う に定義 し てお く と わか り やす く な り ます。
#define ReadCharacter () __ReadCharacter (0);
#define WriteCharacter (c) __WriteCharacter (1, c);
し か し 、 r0 を こ の方法で使用 し た場合、 SVC にパ ラ メ ー タ を渡すレ ジ ス タ に
は 3 つの レ ジ ス タ し か使用で き ません。 通常、 r0 ~ r3 よ り も 多 く のパ ラ メ ー
タ を サブルーチンに渡す必要があ る 場合には、 ス タ ッ ク を使用 し ます。 ただ
し 、 ス タ ッ ク に格納 さ れ る パ ラ メ ー タ は、 SVC ハン ド ラ が使用す る スーパー
バ イ ザ ス タ ッ ク ではな く ユーザモー ド ス タ ッ ク に格納 さ れ る のが一般的であ
る ため、 SVC ハン ド ラ か ら 簡単にア ク セ ス で き ません。
別の方法 と し ては、 レ ジ ス タ の 1 つ (通常は r1) を使用 し て、 他のパ ラ メ ー
タ が保存 さ れてい る メ モ リ ブ ロ ッ ク を参照す る 方法があ り ます。
ARM DUI 0203HJ
Copyright © 2007 ARM Limited. All rights reserved.
6-29
プ ロ セ ッ サ例外処理
6.7
割 り 込みハン ド ラ
こ のセ ク シ ョ ン では、 外部割 り 込み FIQ お よ び IRQ を処理す る 割 り 込みハン
ド ラ を記述す る 方法について説明 し ます。
6.7.1
外部割 り 込みのレ ベル
ARM プ ロ セ ッ サには FIQ と IRQ の 2 つの レベルの外部割 り 込みがあ り ます。
こ れ ら はど ち ら も コ アに流れ る レベルセ ン シテ ィ ブな LOW ア ク テ ィ ブ信号
です。 割 り 込みを発生 さ せ る には、 CPSR 内の適切な無効ビ ッ ト を ク リ ア し てお
く 必要があ り ます。
FIQ は、 以下の よ う に IRQ よ り も 優先 さ れ ます。
•
複数の割 り 込みが発生す る と 、 FIQ が最初に処理 さ れ ます。
•
FIQ の処理に よ っ て IRQ が無効に さ れ、 FIQ ハン ド ラ が IRQ を再度有効
にす る ま で IRQ の処理は開始 さ れ ません。 IRQ は、 ハン ド ラ の終わ り で
SPSR か ら CPSR を復元す る こ と に よ っ て再度有効にす る のが一般的です。
FIQ ベ ク タ はベ ク タ テーブルのア ド レ ス 0x1C にあ る 最後のエ ン ト リ であ る た
め、 FIQ ハン ド ラ を こ のベ ク タ 位置に直接配置 し て、 そのア ド レ ス か ら シー
ケ ン シ ャ ルに実行で き ます。 し たが っ て分岐の必要やそれに伴 う 遅延が発生
せず、 シ ス テ ム にキ ャ ッ シ ュ が搭載 さ れてい る 場合は、 ベ ク タ テーブル と
FIQ ハン ド ラ のすべてがキ ャ ッ シ ュ 内の 1 つのブ ロ ッ ク に ロ ッ ク さ れ ます。
FIQ はで き る だけ速 く 割 り 込みを処理す る 目的で設計 さ れ る ため、 こ れは重
要です。 さ ら に FIQ モー ド の 5 つのバン ク レ ジ ス タ に よ っ て、ハン ド ラ の呼び
出 し と 呼び出 し の間、 状態を保持で き る ため、 さ ら に実行速度を上げ る こ と
がで き ます。
注
割 り 込みハン ド ラ には、 割 り 込み ソ ース を ク リ アす る コ ー ド を含め る 必要が
あ り ます。
6.7.2
C 言語を使用 し た単純な割 り 込みハン ド ラ の記述
__irq 関数宣言キー ワー ド を使用 し て、 単純な割 り 込みハン ド ラ を C 言語で記
述で き ます。 __irq キー ワー ド は、 単純な 1 レベルの割 り 込みハン ド ラ と 、 サ
ブルーチン を呼び出す割 り 込みハン ド ラ の両方に使用で き ます。 ただ し 、
__irq キー ワ ー ド を使用 し て も SPSR の保存 と 復元は行われないため、 こ れを 再
入可能な 割 り 込みハン ド ラ に使用す る こ と はで き ません。 こ こ での再入可能
6-30
Copyright © 2007 ARM Limited. All rights reserved.
ARM DUI 0203HJ
プ ロ セ ッ サ例外処理
と は、 ハン ド ラ が割 り 込みを再度有効に し 、 それ自身に割 り 込ませ る こ と が
可能な こ と を意味 し ます。 詳細については、 再入可能割 り 込みハン ド ラ
(ページ 6-33) を参照 し て下 さ い。
__irq キー ワー ド の使用に よ り 、 以下の よ う にな り ます。
•
破壊 さ れ る 可能性のあ る すべての AAPCS レ ジ ス タ が保存 さ れ ます。
•
NEON/VFP 拡張レ ジ ス タ 以外の関数に よ っ て使用 さ れ る 他のすべての レ
ジ ス タ が保存 さ れます。
プ ロ グ ラ ム カ ウ ン タ に lr - 4 を セ ッ ト し 、 CPSR に元の値を復元す る こ と
に よ っ て関数が終了 し ます。
•
関数がサブルーチン を呼び出す場合、 __irq を使用す る こ と に よ り 、 破壊 さ れ
る 可能性のあ る レ ジ ス タ が保存 さ れ る だけでな く 、 その割 り 込みモー ド の リ
ン ク レ ジ ス タ も 保存 さ れ ます。 詳細については、 「割 り 込みハン ド ラ か ら のサ
ブルーチンの呼び出 し 」 を参照 し て下 さ い。
注
Thumb-1 C コ ー ド を コ ンパ イ ルす る 場合は、 こ の方法で C 言語の割 り 込みハ
ン ド ラ を作成す る こ と はで き ません。 Thumb の コ ー ド を コ ンパ イ ルす る と き
は、 __irq と し て指定 さ れてい る 関数が ARM モー ド に コ ンパ イ ル さ れます。
し か し 、 イ ン タ ー ワー ク が有効に さ れてい る 場合には、 __irq 関数に よ っ て呼
び出 さ れ る サブルーチン を Thumb-1 モー ド で コ ンパ イ ルで き ます。 イ ン タ ー
ワー ク の詳細については、 「第 4 章 ARM と Thumb の イ ン タ ーワー ク 」 を参照
し て下 さ い。
Thumb-2 を サポー ト し てい る プ ロ セ ッ サに、 こ の制限は適用 さ れ ません。
割 り 込みハン ド ラ か らのサブルーチ ンの呼び出 し
ト ッ プ レベルの割 り 込みハン ド ラ か ら サブルーチン を呼び出す場合に __irq
キー ワー ド を使用す る と 、 ス タ ッ ク か ら lr_IRQ の値が復元 さ れ ます。 そのた
め、 SUBS 命令は、 割 り 込み処理後に こ の値を使用 し て正 し いア ド レ ス に復帰
で き ます。
例 6-14 (ページ 6-32) は こ れを実装す る コ ー ド を示 し てい ます。 ト ッ プ レベル
割 り 込みハン ド ラ は、 メ モ リ マ ッ プ さ れた割 り 込み コ ン ト ロ ー ラ のベース ア
ド レ ス の値を 0x80000000 か ら 読み出 し ます。 こ のア ド レ ス の値が 1 の と き 、
ト ッ プ レベルのハン ド ラ は C で記述 さ れたハン ド ラ に分岐 し ます。
ARM DUI 0203HJ
Copyright © 2007 ARM Limited. All rights reserved.
6-31
プ ロ セ ッ サ例外処理
例 6-14
__irq void IRQHandler (void)
{
volatile unsigned int *base = (unsigned int *) 0x80000000;
if (*base == 1)
{
C_int_handler();
}
*(base+1) = 0;
// which interrupt was it?
// process the interrupt
// clear the interrupt
}
armcc で コ ンパ イ ルす る と 、 例 6-14 か ら は以下の コ ー ド が生成 さ れます。
IRQHandler PROC
STMFD
MOV
LDR
SUB
CMP
BLEQ
MOV
STR
ADD
LDMFD
SUBS
ENDP
sp!,{r0-r4,r12,lr}
r4,#0x80000000
r0,[r4,#0]
sp,sp,#4
r0,#1
C_int_handler
r0,#0
r0,[r4,#4]
sp,sp,#4
sp!,{r0-r4,r12,lr}
pc,lr,#4
こ れを、 __irq キー ワー ド が使用 さ れていない場合の以下の結果 と 比較 し て下
さ い。
IRQHandler PROC
STMFD
MOV
LDR
CMP
BLEQ
MOV
STR
LDMFD
ENDP
6-32
sp!,{r4,lr}
r4,#0x80000000
r0,[r4,#0]
r0,#1
C_int_handler
r0,#0
r0,[r4,#4]
sp!,{r4,pc}
Copyright © 2007 ARM Limited. All rights reserved.
ARM DUI 0203HJ
プ ロ セ ッ サ例外処理
6.7.3
再入可能割 り 込みハン ド ラ
割 り 込みハン ド ラ が割 り 込みを再度有効に し てサブルーチン を呼び出 し た後、
別の割 り 込みが発生す る と 、 lr_IRQ に格納 さ れてい る こ のサブルーチン の復
帰ア ド レ ス は 2 番目の IRQ の発生時に破壊 さ れます。 C 言語で __irq キー ワー
ド を使用 し て も 、 再入可能割 り 込みハン ド ラ に必要な SPSR の保存 と 復元は行
われないため、 ト ッ プ レベル割 り 込みハン ド ラ はアセ ン ブ リ 言語で記述す る
必要があ り ます。
再入可能割 り 込みハン ド ラ は、 IRQ 状態を保存 し 、 プ ロ セ ッ サモー ド を切 り
替え、 入れ子のサブルーチン ま たは C 関数に分岐す る 前に新 し いプ ロ セ ッ サ
モー ド の状態を保存す る 必要があ り ます。 ま た、LDRD ま たは STRD 命令あ る いは
8 バ イ ト 境界で整列 さ れた ス タ ッ ク 割 り 当てデー タ を使用す る 可能性のあ る
AAPCS 準拠の コ ンパ イ ル済み C コ ー ド を呼び出す前に、 新 し いプ ロ セ ッ サ
モー ド に対 し て ス タ ッ ク が 8 バ イ ト 境界で整列 さ れてい る こ と を確認す る 必
要があ り ます。 ス タ ッ ク の整列の問題の詳細については、 ARM Web サ イ ト の
ABI for the ARM Architecture Advisory Note - SP must be 8-byte aligned on entry to
AAPCS-conforming functions (ARM アーキ テ ク チ ャ に対す る ABI の勧告 - SP は
AAPCS 準拠関数のエ ン ト リ において 8 バ イ ト 境界で整列す る 必要があ る )
(ARM GENC-007024) を参照 し て下 さ い。
ARMv4 以降では、 シ ス テ ム モー ド に切 り 替え る こ と がで き ます。 シ ス テ ム
モー ド ではユーザモー ド レ ジ ス タ を使用 し なが ら 、 例外ハン ド ラ で必要 と さ
れ る 可能性があ る 特権ア ク セ ス が可能です。 詳細については、 シ ス テ ムモー
ド (ページ 6-46) を参照 し て下 さ い。 ARMv4 よ り も 前の ARM アーキ テ ク
チ ャ では、 こ の処理を行 う 場合には スーパーバ イ ザモー ド に切 り 替え る 必要
があ り ます。
注
こ の方法は、 IRQ と FIQ の両方の割 り 込みに使用で き ます。 し か し 、 FIQ 割 り
込みはで き る だけ速 く 処理 さ れ る う え、 通常は 1 つの割 り 込み ソ ース し か存
在 し ないため、 再入可能な機能が実装 さ れ る 必要はないか も し れ ません。
IRQ ハン ド ラ で安全に割 り 込みを再度有効にす る には、 以下の手順に従っ て
下 さ い。
ARM DUI 0203HJ
1.
復帰ア ド レ ス を作成 し 、 IRQ ス タ ッ ク に保存 し ます。
2.
作業レ ジ ス タ 、 被発呼側で保存 さ れない レ ジ ス タ 、 お よ び spsr_IRQ を保
存 し ます。
3.
割 り 込み ソ ース を ク リ ア し ます。
Copyright © 2007 ARM Limited. All rights reserved.
6-33
プ ロ セ ッ サ例外処理
4.
IRQ を無効に し た ま ま、 シ ス テ ム モー ド に切 り 替え ます。
5.
ス タ ッ ク が 8 バ イ ト 境界で整列 さ れてい る こ と を確認 し 、 必要に応 じ て
調整 し ます。
6.
ユーザモー ド の リ ン ク レ ジ ス タ と 、 SP_usr で使用 さ れ る 、 アーキ テ ク
チ ャ v4 ま たは v5TE 用の調整、 0 ま たは 4 を保存 し ます。
7.
割 り 込みを再度有効に し 、 C 中断ハン ド ラ 関数を呼び出 し ます。
8.
C 言語の割 り 込みハン ド ラ が復帰 し た ら 、 割 り 込みを無効に し ます。
9.
ユーザモー ド の リ ン ク レ ジ ス タ と ス タ ッ ク 調整値を復元 し ます。
10.
必要に応 じ て ス タ ッ ク を再調整 し ます。
11.
IRQ モー ド に切 り 替え ます。
12.
他の レ ジ ス タ と spsr_IRQ を復元 し ます。
13.
こ の IRQ か ら 復帰 し ます。
例 6-15 は、 ARMv4/v5TE プ ロ セ ッ サに対 し て シ ス テ ム モー ド で こ れを実装す
る コ ー ド を示 し てい ます。 例 6-16 (ページ 6-35) は、 ARMv6 プ ロ セ ッ サに対
し て こ れを実装す る コ ー ド を示 し てい ます。
例 6-15
PRESERVE8
AREA INTERRUPT, CODE, READONLY
IMPORT C_irq_handler
IRQ
SUB
lr, lr, #4
STR
lr, [sp, #-4]!
MRS
r14, SPSR
STMFD
sp!, {r0-r4,r12, r14}
BL identify_and_clear_source
MSR
CPSR_c, #0x9f
AND
SUB
STMFD
MSR
BL
MSR
6-34
r1, sp, #4
sp, sp, r1
sp!, {r1, lr}
CPSR_c, #0x1f
C_irq_handler
CPSR_c, #0x9f
;
;
;
;
construct the return address
and push the adjusted lr_IRQ
copy spsr_IRQ to r14
save AAPCS regs and spsr_IRQ
;
;
;
;
;
;
;
;
;
switch to SYS mode, IRQ is
still disabled. USR mode
registers are now current.
test alignment of the stack
remove any misalignment (0 or 4)
store the adjustment and lr_USR
enable IRQ
branch to C IRQ handler
disable IRQ, remain in SYS mode
Copyright © 2007 ARM Limited. All rights reserved.
ARM DUI 0203HJ
プ ロ セ ッ サ例外処理
LDMFD
ADD
MSR
LDMFD
MSR
LDMFD
END
sp!, {r1,lr}
sp, sp, r1
CPSR_c, #0x92
;
;
;
;
sp!, {r0-r4, r12, r14} ;
SPSR_csxf, r14
;
sp!, {pc}^
;
restore stack adjustment and lr_USR
add the stack adjustment (0 or 4)
switch to IRQ mode and keep IRQ
disabled. FIQ is still enabled.
restore registers and
spsr_IRQ
return from IRQ.
例 6-16 入れ子にな っ た割 り 込み (ARMv6、 非ベ ク タ 割 り 込み)
IRQ_Handler
SUB lr, lr, #4
SRSFD #0x1f!
; Save LR_irq and SPSR_irq to System mode stack
CPS #0x1f
; Switch to System mode
STMFD sp!, {r0-r3,r12}
; Store other AAPCS registers
AND r1, sp, #4
SUB sp, sp, r1
STMFD sp!, {r1, lr}
BL identify_and_clear_source
CPSIE i
; Enable IRQ
BL C_irq_handler
CPSID i
; Disable IRQ
LDMFD sp!, {r1,lr}
ADD sp, sp, r1
LDMFD sp!, {r0-r3, r12}
; Restore registers
RFEFD sp!
; Return using RFE from System mode stack
こ のサン プルでは、 FIQ が永久に有効に さ れてい る と 想定 し てい ます。
6.7.4
アセ ン ブ リ 言語を使用 し た割 り 込みハン ド ラ のサン プル
割 り 込みハン ド ラ は、 で き る だけ速 く 実行で き る よ う にアセ ン ブ リ 言語で記
述す る のが一般的です。 以下のセ ク シ ョ ン ではい く つかのサン プルを紹介 し
ます。
•
シ ン グルチ ャ ネル DMA 転送 (ページ 6-36)
•
•
•
ARM DUI 0203HJ
デ ュ アルチ ャ ネル DMA 転送 (ページ 6-36)
割 り 込みの優先度 (ページ 6-38)
コ ン テ キ ス ト ス イ ッ チ (ページ 6-40)
Copyright © 2007 ARM Limited. All rights reserved.
6-35
プ ロ セ ッ サ例外処理
シ ン グルチ ャ ネル DMA 転送
例 6-17 は、 メ モ リ 転送を行 う ために割 り 込み駆動型 I/O であ る ソ フ ト DMA
を実行す る 割 り 込みハン ド ラ を示 し てい ます。 こ の コ ー ド は FIQ ハン ド ラ で
す。 バン ク 付 き FIQ レ ジ ス タ を使用 し て、 割 り 込みの間、 状態が保持 さ れ ま
す。 こ の コ ー ド は、 0x1C に配置す る のが最 も 適切です。
こ のサン プル コ ー ド では、 以下の よ う にな り ます。
r8
デー タ が読み出 さ れ る I/O デバ イ ス のベース ア ド レ ス を指 し ま
す。
IOData
ベース ア ド レ ス か ら 、 デー タ が読み出 さ れ る 32 ビ ッ ト の レ ジ ス
タ ま でのオ フ セ ッ ト です。 こ の レ ジ ス タ の読み出 し に よ っ て、 割
り 込みが ク リ ア さ れ ます。
r9
デー タ 転送先の メ モ リ 位置を指 し ます。
r10
転送先の最後のア ド レ ス を指 し ます。
通常の転送を処理す る 全体のシーケ ン ス には 4 つの命令が使用 さ れ ます。条件
付 き の復帰後に配置 さ れてい る コ ー ド は、 転送が完了 し た こ と を通知す る た
めに使用 さ れ ます。
例 6-17 FIQ ハン ド ラ
LDR
STR
CMP
SUBLSS
r11, [r8, #IOData]
r11, [r9], #4
r9, r10
pc, lr, #4
;
;
;
;
;
;
Load port data from the IO device.
Store it to memory: update the pointer.
Reached the end ?
No, so return.
Insert transfer complete
code here.
ロ ー ド 命令をバ イ ト ロ ー ド 命令に置 き 換え る こ と に よ り 、 バ イ ト 転送を実行
で き ます。 メ モ リ か ら I/O デバ イ スへの転送は、 ロ ー ド 命令 と ス ト ア命令の間
でア ド レ シ ン グモー ド を ス ワ ッ プす る こ と に よ っ て実行 さ れ ます。
デ ュ アルチ ャ ネル DMA 転送
例 6-18 (ページ 6-37) は 例 6-17 と 似てい ますが、 こ こ では 2 つのチ ャ ネルが
処理 さ れ ます。 こ の コ ー ド は FIQ ハン ド ラ です。 バン ク 付 き FIQ レ ジ ス タ を使
用 し て、 割 り 込みの間、 状態が保持 さ れます。 こ の コ ー ド は、 0x1c に配置す
る のが最 も 適切です。
6-36
Copyright © 2007 ARM Limited. All rights reserved.
ARM DUI 0203HJ
プ ロ セ ッ サ例外処理
こ のサン プル コ ー ド では、 以下の よ う にな り ます。
r8
デー タ が読み出 さ れ る I/O デバ イ ス のベース ア ド レ ス を指
し ます。
IOStat
ベース ア ド レ ス か ら 、 2 つのポー ト の ど ち ら が割 り 込みを
発生 さ せたか を示すレ ジ ス タ へのオ フ セ ッ ト です。
IOPort1Active
第 1 ポー ト が割 り 込みを発生 さ せた こ と を示すビ ッ ト マ ス
ク です。 こ れ以外の場合は、 第 2 ポー ト が割 り 込みを発生
さ せた と みな さ れ ます。
IOPort1、 IOPort2 読み出 さ れ る 2 つのデー タ レ ジ ス タ へのオ フ セ ッ ト です。
デー タ レ ジ ス タ の読み出 し に よ っ て、 対応す る ポー ト の割
り 込みが ク リ ア さ れ ます。
r9
第 1 ポー ト か ら のデー タ を転送す る 先の メ モ リ 位置を指 し
ます。
r10
第 2 ポー ト か ら のデー タ を転送す る 先の メ モ リ 位置を指 し
ます。
r11、 r12
転送先の最後のア ド レ ス を指 し ます。 こ れは第 1 ポー ト で
は r11 で、 第 2 ポー ト では r12 です。
通常の転送を処理す る 全体のシーケ ン ス には 9 つの命令が使用 さ れ ます。 条件
付 き の復帰後に配置 さ れてい る コ ー ド は、 転送が完了 し た こ と を通知す る た
めに使用 さ れ ます。
例 6-18 FIQ ハン ド ラ
ARM DUI 0203HJ
LDR
r13, [r8, #IOStat]
; Load status register to find which port
; caused the interrupt.
TST
LDREQ
LDRNE
STREQ
STRNE
CMP
CMPLE
SUBNES
r13, #IOPort1Active
r13, [r8, #IOPort1]
; Load port 1 data.
r13, [r8, #IOPort2]
; Load port 2 data.
r13, [r9], #4
; Store to buffer 1.
r13, [r10], #4
; Store to buffer 2.
r9, r11
; Reached the end?
r10, r12
; On either channel?
pc, lr, #4
; Return
; Insert transfer complete code here.
Copyright © 2007 ARM Limited. All rights reserved.
6-37
プ ロ セ ッ サ例外処理
ロ ー ド 命令をバ イ ト ロ ー ド 命令に置 き 換え る こ と に よ り 、 バ イ ト 転送を実行
で き ます。 メ モ リ か ら I/O デバ イ スへの転送は、 条件付 き ロ ー ド 命令 と 条件付
き ス ト ア命令の間でア ド レ シ ン グモー ド を ス ワ ッ プす る こ と に よ っ て実行 さ
れます。
割 り 込みの優先度
例 6-19 では、 最高 32 個の割 り 込み ソ ース が適切なハン ド ラ ルーチン に送信
さ れ ます。 こ のサン プルは通常の割 り 込みベ ク タ 、 IRQ に使用 さ れ る 目的で
設計 さ れてい る ため、 0x18 か ら 分岐 さ せ る 必要があ り ます。
外部ハー ド ウ ェ アは、 割 り 込みの優先度を決定 し 、 I/O レ ジ ス タ に優先度の高
いア ク テ ィ ブな割 り 込みを割 り 当て る ために使用 し ます。
こ のサン プル コ ー ド では、 以下の よ う にな り ます。
IntBase
割 り 込み コ ン ト ロ ー ラ のベース ア ド レ ス を保持 し ます。
IntLevel
最高優先度のア ク テ ィ ブな割 り 込みを含むレ ジ ス タ のオ フ セ ッ
ト を保持 し ます。
r13
小 さ な Full Descending ス タ ッ ク を指 し ます。
割 り 込みは、 こ の コ ー ド への分岐 も 含め、 10 命令実行後に有効に さ れます。
各割 り 込みに固有のハン ド ラ は、 さ ら に 2 命令実行後に、 すべての レ ジ ス タ
が ス タ ッ ク に保存 さ れた状態で開始 さ れます。
ま た、 各ハン ド ラ の最後の 3 命令は割 り 込みを も う 一度オ フ に し た状態で実
行 さ れ る ため、 SPSR は安全に ス タ ッ ク か ら 復元で き ます。
注
アプ リ ケーシ ョ ン ノ ー ト 30: Software Prioritization of Interrupts ( ソ フ ト ウ ェ ア
に よ る 割 り 込み優先度の決定) では、 上記のハー ド ウ ェ ア を使用す る 方法で
はな く 、 ソ フ ト ウ ェ ア を使用 し て複数 ソ ース の割 り 込みの優先度を決定す る
方法について説明 し てい ます。
例 6-19
; first save the critical state
SUB
lr, lr, #4
; Adjust the return address
; before we save it.
STMFD
sp!, {lr}
; Stack return address
6-38
Copyright © 2007 ARM Limited. All rights reserved.
ARM DUI 0203HJ
プ ロ セ ッ サ例外処理
MRS
STMFD
r14, SPSR
sp!, {r12, r14}
MOV
r12, #IntBase
LDR
r12, [r12, #IntLevel]
;
;
;
;
;
;
;
;
get the SPSR ...
... and stack that plus a
working register too.
Now get the priority level of the
highest priority active interrupt.
Get the interrupt controller's
base address.
Get the interrupt level (0 to 31).
; Now read-modify-write the CPSR to enable interrupts.
MRS
BIC
r14, CPSR
r14, r14, #0x80
MSR
CPSR_c, r14
LDR
pc, [pc, r12, LSL #2]
NOP
;
;
;
;
;
;
;
;
;
Read the status register.
Clear the I bit
(use 0x40 for the F bit).
Write it back to re-enable
interrupts and
jump to the correct handler.
PC base address points to this
instruction + 8
pad so the PC indexes this table.
; Table of handler start addresses
DCD
Priority0Handler
DCD
Priority1Handler
DCD
Priority2Handler
; ...
Priority0Handler
STMFD
sp!, {r0 - r11}
; ...
LDMFD
sp!, {r0 - r11}
; Save other working registers.
; Insert handler code here.
; Restore working registers (not r12).
; Now read-modify-write the CPSR to disable interrupts.
MRS
r12, CPSR
; Read the status register.
ORR
r12, r12, #0x80
; Set the I bit
; (use 0x40 for the F bit).
MSR
CPSR_c, r12
; Write it back to disable interrupts.
; Now that interrupt disabled, can safely restore SPSR then return.
LDMFD
sp!, {r12, r14}
; Restore r12 and get SPSR.
MSR
SPSR_csxf, r14
; Restore status register from r14.
LDMFD
sp!, {pc}^
; Return from handler.
Priority1Handler
; ...
ARM DUI 0203HJ
Copyright © 2007 ARM Limited. All rights reserved.
6-39
プ ロ セ ッ サ例外処理
コ ン テキス ト ス イ ッ チ
例 6-20 では、 ユーザモー ド のプ ロ セ スへの コ ン テ キ ス ト ス イ ッ チが実行 さ れ
ます。 こ の コ ー ド では、 実行準備が整っ たプ ロ セ ッ サの プ ロ セ ス制御ブ ロ ッ
ク (PCB) を指すポ イ ン タ の リ ス ト が使用 さ れてい ます。
図 6-5 は、 こ のサ ンプルで使用 さ れてい る PCB の レ イ ア ウ ト を示 し てい ます。
r14
r13
r12
r11
r10
r9
r8
r7
r6
r5
r4
r3
r2
r1
r0
lr
spsr
PCB pointer
User mode registers
図 6-5 PCB のレ イ アウ ト
r12 は次に実行 さ れ る プ ロ セ ス の PCB を指すポ イ ン タ を指 し ます。 こ の リ ス
ト の終わ り にはゼ ロ ポ イ ン タ が配置 さ れ ます。 レ ジ ス タ r13 は PCB へのポ イ
ン タ であ り 、 タ イ ム ス ラ イ ス の際には保存 さ れ る ため、 エ ン ト リ 時には実行
中のプ ロ セ ス の PCB を指 し ます。
例 6-20
STMIA
MRS
STMDB
LDR
CMP
LDMNEDB
MSRNE
LDMNEIA
NOP
SUBNES
6-40
r13, {r0 - r14}^
r0, SPSR
r13, {r0, lr}
r13, [r12], #4
r13, #0
r13, {r0, lr}
SPSR_cxsf, r0
r13, {r0 - r14}^
;
;
;
;
;
;
;
;
Dump user registers above r13.
Pick up the user status
and dump with return address below.
Load next process info pointer.
If it is zero, it is invalid
Pick up status and return address.
Restore the status.
Get the rest of the registers
pc, lr, #4
; and return and restore CPSR.
; Insert "no next process code" here.
Copyright © 2007 ARM Limited. All rights reserved.
ARM DUI 0203HJ
プ ロ セ ッ サ例外処理
6.8
リ セ ッ ト ハン ド ラ
リ セ ッ ト ハン ド ラ の動作は、 ソ フ ト ウ ェ ア開発対象のシ ス テ ム に よ っ て異な
り ます。 例えば、 以下の よ う な動作が考え ら れ ます。
•
例外ベ ク タ のセ ッ ト ア ッ プ。 詳細については、 例外ハン ド ラ の イ ン ス
ト ール (ページ 6-15) を参照 し て下 さ い。
•
ス タ ッ ク と レ ジ ス タ の初期化。
•
MMU を使用 し てい る 場合の、 メ モ リ シ ス テ ム の初期化。
•
重要な I/O デバ イ ス の初期化。
•
割 り 込みの有効化。
•
プ ロ セ ッ サのモー ド ま たは状態、 あ る いはその両方の変更。
•
C 言語に必要な変数の初期化 と メ イ ン アプ リ ケーシ ョ ン の呼び出 し 。
詳細については、 「第 2 章 組み込み ソ フ ト ウ ェ アの開発」 を参照 し て下 さ い。
ARM DUI 0203HJ
Copyright © 2007 ARM Limited. All rights reserved.
6-41
プ ロ セ ッ サ例外処理
6.9
未定義命令ハン ド ラ
未定義命令例外は、 次の場合に生成 さ れ ます。
•
プ ロ セ ッ サが命令を認識 し ない場合
•
プ ロ セ ッ サが コ プ ロ セ ッ サ命令 と し て命令を認識 し てい る に も かかわ ら
ず、 コ プ ロ セ ッ サがその命令を認識 し ない場合
例えば、 命令が コ プ ロ セ ッ サ用の命令であ る に も かかわ ら ず、 それに関連す
る VFP な ど の コ プ ロ セ ッ サがシ ス テ ム に接続 さ れていないか、 無効に さ れて
い る ケース が考え ら れます。 ただ し 、 その よ う な コ プ ロ セ ッ サ用の ソ フ ト
ウ ェ アエ ミ ュ レー タ を使用す る こ と も 可能です。
こ の よ う なエ ミ ュ レー タ は、 以下の よ う な処理を行 う 必要があ り ます。
1.
未定義命令ベ ク タ に接続 し 、 古い内容を保存す る 必要があ り ます。
2.
未定義命令を検査 し 、 エ ミ ュ レー ト す る 必要があ る か ど う か をチ ェ ッ ク
し ます。 こ のチ ェ ッ ク は、 SVC ハン ド ラ が SVC 番号を抽出す る 方法 と 似
てい ますが、 エ ミ ュ レー タ では下位 24 ビ ッ ト を抽出す る のではな く 、
ビ ッ ト 27 ~ 24 を抽出す る 必要があ り ます。
こ れ ら の ビ ッ ト に基づ き 、 以下の方法でその命令が コ プ ロ セ ッ サ命令で
あ る か ど う かが判断 さ れます。
3.
•
ビ ッ ト 27 ~ 24 が b1110 ま たは b110x の場合、 その命令は コ プ ロ
セ ッ サ命令です。
•
ビ ッ ト 8 ~ 11 が、 コ プ ロ セ ッ サエ ミ ュ レー タ に よ っ てその命令を
処理す る 必要があ る こ と を示 し てい る 場合、 エ ミ ュ レー タ はその
命令を処理 し てユーザプ ロ グ ラ ムに復帰す る 必要があ り ます。
上記以外の場合、 エ ミ ュ レー タ は イ ン ス ト ール時に保存 さ れたベ ク タ を
使用 し て、 その例外を元のハン ド ラ ま たはチ ェ イ ン内の次のエ ミ ュ レー
タ に渡す必要があ り ます。
チ ェ イ ン内の ど のエ ミ ュ レー タ も その命令を処理で き ない場合には、 未定義
命令ハン ド ラ がエ ラ ーを通知 し て終了す る 必要があ り ます。
注
ARMv6T2 よ り 前の Thumb 命令セ ッ ト には コ プ ロ セ ッ サ命令がないため、 未
定義命令ハン ド ラ でその よ う な命令を エ ミ ュ レー ト す る 必要はあ り ません。
6-42
Copyright © 2007 ARM Limited. All rights reserved.
ARM DUI 0203HJ
プ ロ セ ッ サ例外処理
6.10
プ リ フ ェ ッ チアボー ト ハン ド ラ
シ ス テ ムに MMU が存在 し ない場合は、 プ リ フ ェ ッ チアボー ト ハン ド ラ でエ
ラ ーを通知 し て実行を終了で き ます。 MMU が存在す る 場合には、 アボー ト を
発生 さ せた ア ド レ ス が物理 メ モ リ に復元 さ れ る 必要があ り ます。 lr_ABT は、
アボー ト の原因 と な っ た ア ド レ ス の次のア ド レ ス にあ る 命令を指 し てい る た
め、 復元す る 必要のあ る ア ド レ ス は lr_ABT-4 と な り ます。 そのア ド レ ス に対 し
て仮想 メ モ リ の メ モ リ 障害が処理 さ れ る と 、 命令フ ェ ッ チが再試行 さ れ ます。
プ リ フ ェ ッ チアボー ト ハン ド ラ は、 次の命令ではな く 、 アボー ト を発生 さ せ
た命令に復帰 し ます。 以下に例を示 し ます。
SUBS
ARM DUI 0203HJ
pc,lr,#4
Copyright © 2007 ARM Limited. All rights reserved.
6-43
プ ロ セ ッ サ例外処理
6.11
デー タ アボー ト ハン ド ラ
シ ス テ ム に MMU が存在 し ない場合は、 デー タ アボー ト ハン ド ラ でエ ラ ーを
通知 し て終了す る 必要があ り ます。 MMU が存在す る 場合は、 デー タ アボー ト
ハン ド ラ に よ っ て仮想 メ モ リ の メ モ リ 障害を解決す る 必要があ り ます。
lr_ABT はデー タ アボー ト を発生 さ せた命令 よ り も 2 つ先の命令を指すため、
デー タ アボー ト を発生 さ せた命令の位置は lr_ABT-8 と な り ます。
こ のアボー ト を発生す る 可能性のあ る 命令には以下の よ う な種類があ り ます。
単一レ ジ ス タ ロ ー ド / ス ト ア命令
応答はプ ロ セ ッ サ タ イ プに よ っ て異な り ます。
•
アボー ト が ARM7TDMI® な ど の ARM7 プ ロ セ ッ サで発生 し
た場合、 ア ド レ ス レ ジ ス タ が更新 さ れてい る ので、 変更を
元に戻す必要があ り ます。
•
アボー ト が ARM9、 ARM10、 ま たは StrongARM 以降のプ
ロ セ ッ サで発生 し た場合、 プ ロ セ ッ サは命令開始前に保持
さ れていた値を そのア ド レ ス に復元 し ます。 こ の変更を元
に戻す コ ー ド は必要あ り ません。
ス ワ ッ プ命令 (SWP) こ の命令に関連 し て ア ド レ ス レ ジ ス タ が更新 さ れ る こ
と はあ り ません。
多重 ロ ー ド / ス ト ア命令
応答はプ ロ セ ッ サ タ イ プに よ っ て異な り ます。
•
アボー ト が ARM 7 ベース のプ ロ セ ッ サで発生 し 、 ラ イ ト
バ ッ ク が有効に さ れてい る 場合には、 転送全体が発生 し た
かの よ う にベース レ ジ ス タ が更新 さ れ ます。
レ ジ ス タ リ ス ト 内にベース レ ジ ス タ を指定 し て LDM を使用
し た場合、 プ ロ セ ッ サは後で回復で き る よ う に、 上書 き さ
れた値を修正 さ れたベース値で置 き 換え ます。 元のベース
ア ド レ ス は、 使用 さ れ る レ ジ ス タ の数を使用 し て再計算 さ
れます。
•
6-44
アボー ト が ARM9、 ARM10 あ る いは StrongARM 以降のプ
ロ セ ッ サで発生 し 、 ラ イ ト バ ッ ク が有効に さ れてい る 場合
には、 命令開始前に保持 さ れていた値をベース レ ジ ス タ に
復元 し ます。
Copyright © 2007 ARM Limited. All rights reserved.
ARM DUI 0203HJ
プ ロ セ ッ サ例外処理
上記 3 つの ど のケース で も 、 MMU は要求 さ れた仮想 メ モ リ を物理 メ モ リ に
ロ ー ド で き ます。 MMU の フ ォール ト ア ド レ ス レ ジ ス タ (FAR) には、 アボー
ト を発生 さ せた ア ド レ ス が保持 さ れます。 こ れに よ り 、 ハン ド ラ は復帰 し て
命令を再実行す る こ と がで き ます。
デー タ アボー ト ハン ド ラ のサ ンプル コ ー ド は、 メ イ ン サン プルデ ィ レ ク ト リ
の ...\databort に収録 さ れてい ます。
ARM DUI 0203HJ
Copyright © 2007 ARM Limited. All rights reserved.
6-45
プ ロ セ ッ サ例外処理
6.12
シ ス テムモー ド
ARM アーキ テ ク チ ャ では、 ユーザモー ド を 15 本の汎用レ ジ ス タ 、 PC、 お よ
び CPSR を使用す る モー ド と し て定義 し てい ます。 こ のモー ド の他に も 他の特
権プ ロ セ ッ サモー ド があ り 、 それぞれが専用の SPSR と 、 15 本のユーザモー ド
汎用レ ジ ス タ の一部に置 き 換わ る レ ジ ス タ を使用 し ます。
プ ロ セ ッ サ例外が発生す る と 、 現在のプ ロ グ ラ ム カ ウ ン タ がその例外モー ド
の リ ン ク レ ジ ス タ に コ ピー さ れ、 CPSR がその例外モー ド の SPSR に コ ピー さ れ
ます。 こ れに よ り CPSR が例外に応 じ て変更 さ れ、 プ ロ グ ラ ム カ ウ ン タ には例
外ハン ド ラ を起動す る ための、 例外に よ っ て決ま る ア ド レ ス がセ ッ ト さ れ ま
す。
ARM サブルーチン呼び出 し 命令 (BL) が、 プ ロ グ ラ ム カ ウ ン タ の変更前に復
帰ア ド レ ス を r14 に コ ピーす る ため、こ のサブルーチンの復帰命令は r14 を pc
に移動 し ます (MOV pc,lr)。
こ れ ら の動作に よ り 、 例外を処理す る ARM モー ド でサブルーチン が呼び出
さ れ る 場合に、 サブルーチン復帰ア ド レ ス が例外復帰ア ド レ ス で上書 き さ れ
る 結果、 同 じ タ イ プの別の例外は発生 し ません。
以前のバージ ョ ンの ARM アーキ テ ク チ ャ では、 こ の問題は例外 コ ー ド 内に
サブルーチン コ ールを含めない よ う に注意す る か、 特権モー ド か ら ユーザ
モー ド に変更す る こ と に よ っ て解決 さ れてい ま し た。 最初の解決方法は制約
があ ま り に も 大 き く 、 ま た 2 番目の方法では タ ス ク を正 し く 実行す る ために
必要な特権ア ク セ ス を割 り 当て ら れません。
ARMv4 以降では、 こ の問題を解決す る ために シ ス テ ム モー ド と 呼ばれ る プ ロ
セ ッ サモー ド が追加 さ れてい ます。 シ ス テ ム モー ド は、 ユーザモー ド レ ジ ス
タ を共有す る 特権プ ロ セ ッ サモー ド です。 特権モー ド の タ ス ク は こ のモー ド
で実行す る こ と が可能であ り 、 例外に よ る リ ン ク レ ジ ス タ の上書 き を防 ぐ こ
と がで き ます。
注
例外か ら シ ス テ ム モー ド に入 る こ と はで き ません。 例外ハン ド ラ はシ ス テ ム
モー ド に入 る と き に CPSR を変更 し ます。 こ の例については、 再入可能割 り 込
みハン ド ラ (ページ 6-33) を参照 し て下 さ い。
6-46
Copyright © 2007 ARM Limited. All rights reserved.
ARM DUI 0203HJ
第 7章
Handling Cortex-M3 Processor
ExceptionsCortex-M3 プ ロ セ ッ サ例外処理
本章では、 Cortex-M3 プ ロ セ ッ サがサポー ト し てい る 各種の例外の処理方法
について説明 し ます。
本章は以下のセ ク シ ョ ンか ら 構成 さ れてい ます。
•
Cortex-M3 プ ロ セ ッ サ例外について (ページ 7-2)
•
•
•
•
•
•
•
•
例外テーブルの書 き込み (ページ 7-11)
例外ハン ド ラ の書 き込み (ページ 7-13)
例外テーブルの配置 (ページ 7-14)
シ ス テ ム制御空間レ ジ ス タ の設定 (ページ 7-15)
個別の IRQ の設定 (ページ 7-17)
スーパーバ イ ザ コ ール (ページ 7-18)
シ ス テ ム タ イ マ (ページ 7-20)
他の ARM プ ロ セ ッ サ用に記述 さ れた例外処理 コ ー ド の移植 (ページ
7-22)
ARM DUI 0203HJ
Copyright © 2007 ARM Limited. All rights reserved.
7-1
Handling Cortex-M3 Processor ExceptionsCortex-M3 プ ロ セ ッ サ例外処理
7.1
Cortex-M3 プ ロ セ ッ サ例外について
プ ロ グ ラ ムの通常の実行フ ロ ーにおいて、 近 く の ラ ベルや分岐への分岐や、
サブルーチンへの リ ン ク な ど が実行 さ れ る こ と に よ り 、 プ ロ グ ラ ム カ ウ ン タ
(PC) はア ド レ ス空間の中でシーケ ン シ ャ ルに増加 し てい き ます。
プ ロ セ ッ サ例外は、 内部 ソ ース ま たは外部 ソ ース に よ っ て生成 さ れ る イ ベン
ト を プ ロ セ ッ サが処理で き る よ う に、 こ の通常の実行フ ロ ーが迂回 さ れ る と
き に発生 し ます。 こ の イ ベン ト には以下の よ う な も のがあ り ます。
•
•
•
外部で生成 さ れた割 り 込み
未定義命令を実行 し よ う と す る プ ロ セ ッ サの試行
オペレーテ ィ ン グ シ ス テ ムの特権付 き 機能へのア ク セ ス
例外が発生 し た と き は、 ベ ク タ テーブル内のア ド レ スへの分岐が実行 さ れ ま
す。 発生 し た例外に よ っ て、 使用 さ れ る ベ ク タ テーブル内のア ド レ ス の場所
が決定 さ れ ます。 詳細については、 例外番号 (ページ 7-5) お よ びベ ク タ テー
ブル (ページ 7-6) を参照 し て下 さ い。
注
ほ と ん ど の ARM プ ロ セ ッ サ と は異な り 、 Cortex-M3 プ ロ セ ッ サのベ ク タ テー
ブルには、 命令ではな く ア ド レ ス が含まれ ます。
こ れ ら の例外が発生 し た と き に実行 し ていたプ ロ グ ラ ム を、 適切な例外ルー
チンの終了時に再開で き る よ う にす る ため、 例外を処理す る と き は、 それ ま
でのプ ロ セ ッ サ状態を保存 し てお く 必要があ り ます。
保存プ ロ セ ス の一部は、 Cortex-M3 プ ロ セ ッ サのハー ド ウ ェ アに よ っ て自動
的に行われ ます。 破壊 さ れ る 可能性のあ る CPSR お よ び AAPCS レ ジ ス タ は自
動的に保存 さ れ る ので、 ほ と ん ど の例外ハン ド ラ は C ま たは C++ 言語で記述
で き ます。 通常、 アセ ン ブ リ 言語での低レベルのハン ド ラ は必要あ り ません。
Cortex-M3 プ ロ セ ッ サは ARM v7-M アーキ テ ク チ ャ に基づいてお り 、 Thumb-2
命令のみを実行 し 、 ARM 命令セ ッ ト はサポー ト し てい ません。 そのため、 例
外処理 コ ー ド は Thumb 状態で実行 さ れ ます。
7-2
Copyright © 2007 ARM Limited. All rights reserved.
ARM DUI 0203HJ
Handling Cortex-M3 Processor ExceptionsCortex-M3 プ ロ セ ッ サ例外処理
7.1.1
動作お よび実行モー ド
Cortex-M3 プ ロ セ ッ サは、 以下のモー ド をサポー ト し てい ます。
•
ス レ ッ ド モー ド と ハン ド ラ モー ド の 2 つの動作モー ド
•
特権モー ド と ユーザモー ド の 2 つの実行モー ド
ス レ ッ ド モー ド は、 リ セ ッ ト 時、 お よ び通常は例外か ら の復帰時に開始 さ れ
ます。 ス レ ッ ド モー ド では、 特権モー ド ま たはユーザモー ド のいずれかで
コ ー ド を実行で き ます。
ハン ド ラ モー ド は、 例外が発生 し た結果、 開始 さ れ ます。 コ ー ド はすべて特
権モー ド で実行 さ れ ます。 例外が発生す る と 、 コ アは自動的に特権モー ド に
切 り 替わ り ます。
特権モー ド にはフルア ク セ ス権が備わ っ てい ます。
ユーザモー ド のア ク セ ス権は制限 さ れてい ます。 制限は以下の と お り です。
•
MSR 命令で使用可能な フ ィ ール ド な ど の、 命令の使用に対す る 制限
•
特定の コ プ ロ セ ッ サ レ ジ ス タ の使用に対す る 制限
•
シ ス テ ム設計に基づいた メ モ リ お よ びペ リ フ ェ ラ ルへのア ク セ ス に対す
る 制限
•
MPU コ ン フ ィ ギ ュ レーシ ョ ン に よ っ て課 さ れた メ モ リ お よ びペ リ フ ェ
ラ ルへのア ク セ ス に対す る 制限
例外か ら の復帰時に特権ス レ ッ ド モー ド か ら ユーザ ス レ ッ ド モー ド に切 り 替
え る には、 リ ン ク レ ジ ス タ (R14) 内の EXC_RETURN 値を変更 し ます。 MSR
命令を使用 し て CONTROL[0] を ク リ アす る こ と で、 特権ス レ ッ ド モー ド か ら
ユーザ ス レ ッ ド モー ド に切 り 替え る こ と も で き ます。 ただ し 、 例えば SVC な ど
の例外を経由せずに非特権モー ド か ら 特権モー ド に直接切 り 替え る こ と はで
き ません ( スーパーバ イ ザ コール (ページ 7-18) を参照)。
ARM DUI 0203HJ
Copyright © 2007 ARM Limited. All rights reserved.
7-3
Handling Cortex-M3 Processor ExceptionsCortex-M3 プ ロ セ ッ サ例外処理
7.1.2
メ イ ン ス タ ッ ク お よびプ ロ セスス タ ッ ク
Cortex-M3 プ ロ セ ッ サは、 メ イ ン ス タ ッ ク と プ ロ セ ス ス タ ッ ク の 2 種類の ス
タ ッ ク をサポー ト し てい ます。 プ ロ セ ッ サには、 各ス タ ッ ク に 1 つずつ対応 し
てい る 2 つの ス タ ッ ク ポ イ ン タ (SP) があ り ます。 使用中の ス タ ッ ク に応 じ
て、 1 つの ス タ ッ ク ポ イ ン タ のみが一度に表示 さ れます。
メ イ ン ス タ ッ ク は、 リ セ ッ ト 時、 お よ び例外ハン ド ラ へのエ ン ト リ 時に使用
さ れ ます。 プ ロ セ ス ス タ ッ ク を使用す る には、 こ の ス タ ッ ク を選択す る 必要
があ り ます。 こ のためには、 以下のいずれかの方法を使用で き ます。
•
ハン ド ラ モー ド の終了時に EXC_RETURN 値を使用す る
•
ス レ ッ ド モー ド 中に MSR 命令を使用 し て CONTROL[1] に書 き 込む
注
初期化ま たは コ ン テ キ ス ト 切 り 替え コ ー ド でプ ロ セ ス ス タ ッ ク ポ イ ン タ を初
期化す る 必要があ り ます。
7-4
Copyright © 2007 ARM Limited. All rights reserved.
ARM DUI 0203HJ
Handling Cortex-M3 Processor ExceptionsCortex-M3 プ ロ セ ッ サ例外処理
7.1.3
例外番号
表 7-1 は、 Cortex-M3 プ ロ セ ッ サに よ っ て認識 さ れ る 例外の タ イ プ を示 し てい
ます。 こ れ ら の各例外を発生 さ せ る イ ベン ト については、 イ ベン ト (ページ
7-8) を参照 し て下 さ い。
表 7-1 例外番号
例外番号
例外
優先度
無効
1
リ セッ ト
-3
不可
2
NMI
-2
不可
マ ス ク 不可割 り 込み
3
HardFault
-1
不可
他の例外に よ っ て カバー さ れないすべてのエ ラ ー
4
MemManage
設定可能
可能
メ モ リ 保護エ ラ ー (命令ま たはデー タ )
5
BusFault
設定可能
可能
他の メ モ リ エ ラ ー
6
UsageFault
設定可能
可能
メ モ リ エ ラ ー以外の命令例外エ ラ ー
7 ~ 10
予約済み
-
-
11
SVCall
設定可能
不可
SVC 命令の実行に よ る 同期スーパーバ イ ザ コ ール
12
デバ ッ グモ
ニタ
設定可能
可能
同期デバ ッ グ イ ベン ト
13
予約済み
-
-
14
PendSV
設定可能
不可
非同期スーパーバ イ ザ コ ール
15
SysTick
設定可能
不可
シ ス テ ム タ イ マ Tick
16
External
Interrupt(0)
設定可能
可能
外部割 り 込み
...
...
...
...
16 + n
External
Interrupt(n)
設定可能
可能
ARM DUI 0203HJ
説明
外部割 り 込み
Copyright © 2007 ARM Limited. All rights reserved.
7-5
Handling Cortex-M3 Processor ExceptionsCortex-M3 プ ロ セ ッ サ例外処理
7.1.4
ベ ク タ テーブル
リ セ ッ ト 時、 ベ ク タ テーブルは 0x00000000 のア ド レ ス に存在 し ます。
コ ー ド が特権モー ド で実行 さ れてい る 場合は、 以下の操作を実行で き ます。
•
ベ ク タ テーブル、 vectorbaseaddress の現在の場所を ベ ク タ テーブルオ フ
セ ッ ト レ ジ ス タ (VTOR) か ら 読み込む こ と がで き ます。
•
VTOR に書 き 込む こ と で、 ベ ク タ テーブルの場所を別のア ド レ ス に移動
で き ます。
VTOR の詳細については、 ベ ク タ テーブルオ フ セ ッ ト レ ジ ス タ (ページ 7-7)、
特権の詳細については、 動作お よ び実行モー ド (ページ 7-3) を参照 し て下 さ
い。
ベ ク タ テーブルには、 各種の例外用ハン ド ラ のア ド レ ス が含まれてい ます。
例外番号 n のハン ド ラ は、 (vectorbaseaddress + 4 * n) にあ り ます。 各例外に対
応 し てい る n の値については、 例外番号 (ページ 7-5) を参照 し て下 さ い。
注
こ れは、 他の ARM プ ロ セ ッ サのベ ク タ テーブル と は異な り ます。 他の ARM
プ ロ セ ッ サのベ ク タ テーブルには、 ア ド レ ス ではな く 、 命令が含まれてい ま
す。
ARMv7-M プ ロ セ ッ サでは Thumb コ ー ド のみを実行で き る ので、 ハン ド ラ の
ア ド レ ス のビ ッ ト [0] はすべて 1 に設定 さ れてい る 必要があ り ます。
vectorbaseaddress の ワー ド は、 メ イ ン ス タ ッ ク ポ イ ン タ の リ セ ッ ト 値を含ん
でい ます。
7-6
Copyright © 2007 ARM Limited. All rights reserved.
ARM DUI 0203HJ
Handling Cortex-M3 Processor ExceptionsCortex-M3 プ ロ セ ッ サ例外処理
ベ ク タ テーブルオ フ セ ッ ト レ ジ ス タ
こ の レ ジ ス タ は、 ア ド レ ス 0xE000ED08 で メ モ リ マ ッ プ さ れ ます。 リ セ ッ ト 時に
は、 0x00000000 が含まれ ます。
VTOR の ビ ッ ト [31:30] お よ びビ ッ ト [7:0] は予約 さ れてお り 、 すべて 0 に
な っ てい ます。 ビ ッ ト [29] が 0 の場合、 ベ ク タ テーブルは メ モ リ の CODE
領域に存在 し 、 それ以外の場合には RAM 領域に存在 し ます。
ベ ク タ テーブルのア ド レ ス は、 常に 32 ワ ー ド 境界で整列 さ れてい る 必要があ
り ます。 16 を超え る 外部割 り 込みを使用す る 場合は、 ア ド レ ス の整列を 32
ビ ッ ト よ り 大 き い も のにす る 必要があ り ます。 表 7-2 は、 さ ま ざ ま な数の外
部割 り 込みに対す る 整列を示 し てい ます。 ARMv7-M では 240 を超え る 外部割
り 込みはサポー ト し てい ません。
表 7-2
ARM DUI 0203HJ
外部割 り 込み数
vectorbaseaddress の整列
0 ~ 16
32 ワー ド
17 ~ 48
64 ワー ド
49 ~ 112
128 ワー ド
113 ~ 240
256 ワー ド
Copyright © 2007 ARM Limited. All rights reserved.
7-7
Handling Cortex-M3 Processor ExceptionsCortex-M3 プ ロ セ ッ サ例外処理
7.1.5
イベン ト
各種の例外には、 以下の よ う な原因が考え ら れ ます。
リ セッ ト
リ セ ッ ト は、 リ セ ッ ト 信号がアサー ト さ れた と き に、 修復不可
能な方法で実行を終了す る 特殊な例外です。 リ セ ッ ト には以下の
2 つの レベルがあ り ます。
•
パ ワーオン リ セ ッ ト (POR) は、 コ ア、 シ ス テ ム制御領域、
お よ びデバ ッ グ ロ ジ ッ ク を リ セ ッ ト し ます。
•
ロ ーカル リ セ ッ ト は、 コ アお よ びほ と ん ど のシ ス テ ム制御
領域を リ セ ッ ト し ます。 シ ス テ ム制御領域内のデバ ッ グ関
連の リ ソ ース は リ セ ッ ト さ れず、 デバ ッ グ ロ ジ ッ ク も リ
セ ッ ト さ れません。
リ セ ッ ト 信号のアサー ト が解除 さ れ る と 、 固定点か ら 実行が再
開 さ れます。
NMI
マ ス ク 不可割 り 込み。
HardFault
こ れは、 他の例外 メ カ ニズ ム では処理で き ないエ ラ ーに対す る
一般的なエ ラ ーです。 こ れは通常は修復不可能なエ ラ ーに使用 さ
れ ます。
HardFault はエ ラ ーのエ ス カ レー ト に使用 さ れ ます。
MemManage
メ モ リ 保護ユニ ッ ト に よ っ て通知 さ れた メ モ リ 保護エ ラ ーは、
デー タ と 命令の両方のア ク セ ス に対 し て MemManage 例外を発生
さ せます。 こ のエ ラ ーが無効に さ れてい る 場合、 メ モ リ 保護エ
ラ ーは HardFault にエ ス カ レー ト し ます。
7-8
BusFault
MemManage が処理す る も の以外の メ モ リ 関連エ ラ ーは、
BusFault 例外を発生 さ せます。 こ れ ら は通常は、 シ ス テ ムバ ス に
よ っ て検出 さ れ る エ ラ ーです。 こ れ ら のエ ラ ーには同期ま たは非
同期の も のがあ り ます。 こ のエ ラ ーが無効に さ れてい る 場合、 こ
れ ら のエ ラ ーは HardFault にエ ス カ レー ト し ます。
UsageFault
メ モ リ エ ラ ー以外の命令実行エ ラ ー。 こ れには以下の よ う な も の
があ り ます。
•
未定義命令を実行 し よ う と し た場合
•
結果が無効な状態 と な る 命令を実行 し た場合
•
例外復帰時のエ ラ ー
Copyright © 2007 ARM Limited. All rights reserved.
ARM DUI 0203HJ
Handling Cortex-M3 Processor ExceptionsCortex-M3 プ ロ セ ッ サ例外処理
•
•
•
使用不可ま たは無効に さ れてい る コ プ ロ セ ッ サ を使用 し よ
う と し た場合
UsageFault を発生 さ せ る よ う に設定 さ れてい る 場合のゼ ロ
除算
UsageFault を発生 さ せ る よ う に設定 さ れてい る 場合の非整
列ア ド レ ス
SVC 命令の実行に よ り 発生 し た同期スーパーバ イ ザ コ ール。 アプ
SVCall
リ ケーシ ョ ン コ ー ド では、 SVC 命令を使用 し て、 シ ス テ ムへの特
権ア ク セ ス を求め る サービ ス を要求 し ます。
デバ ッ グモニ タ
同期デバ ッ グ イ ベン ト 。 こ れは、 ブ レー ク ポ イ ン ト (BKPT) 命令
の実行であ る 場合があ り ます。
PendSV
非同期スーパーバ イ ザ コ ール。
SysTick
シ ス テ ム タ イ マ イ ベン ト 。
External Interrupt(n)
ネ ス ト さ れたベ ク タ 割 り 込み コ ン ト ロ ー ラ か ら の信号。 詳細につ
いては、 ネ ス ト さ れたベ ク タ 割 り 込み コ ン ト ロ ー ラ (ページ
7-10) を参照 し て下 さ い。
ARM DUI 0203HJ
Copyright © 2007 ARM Limited. All rights reserved.
7-9
Handling Cortex-M3 Processor ExceptionsCortex-M3 プ ロ セ ッ サ例外処理
7.1.6
例外の優先度お よびプ リ エ ン プ シ ョ ン (横取 り )
低い優先度番号を持つ例外は、 高い優先度番号の例外 よ り も 先行で き ます。
つま り 、 プ ロ セ ス がハン ド ラ モー ド の場合、 その優先度番号が、 現在処理中
の例外 よ り も 低い場合には、 例外が発生 し ます。 同 じ 優先度番号ま たはそれ
よ り 高い優先番号を持つ例外は、 保留 さ れ ます。
例外ハン ド ラ の終了時には、 以下の操作が行われ ます。
•
保留中の例外が存在 し ない場合、 プ ロ セ ッ サは ス レ ッ ド モー ド に復帰
し 、 例外はアプ リ ケーシ ョ ン プ ロ グ ラ ムに復帰 し ます。
•
保留中の例外が存在す る 場合は、 最 も 低い優先度番号を持つ保留中の例
外のハン ド ラ に制御が渡 さ れ ます。 最 も 低い優先度番号を持つ保留中の
例外が 2 つ存在す る 場合は、 よ り 低い例外番号を持つ例外が先に処理 さ
れます。
リ セ ッ ト 、 マ ス ク 不可割 り 込み、 お よ び HardFault の優先度はそれぞれ -3、
-2、 お よ び -1 です。 設定可能な優先度を持つその他すべての例外は、 0 以上の
優先度を持ち ます。
7.1.7
ネス ト さ れたベ ク タ 割 り 込み コ ン ト ロー ラ
実装に応 じ て、 ネ ス ト さ れたベ ク タ 割 り 込み コ ン ト ロ ー ラ (NVIC) は、 最高
240 の外部割 り 込みを サポー ト で き 、 最高 256 の優先度レベルを動的に割 り 当
て る こ と がで き ます。 NVIC は、 レベル と パル ス の両方の割 り 込み ソ ース を サ
ポー ト し てい ます。 プ ロ セ ッ サ状態は、 割 り 込みの開始時にハー ド ウ ェ アに
自動的に保存 さ れ、 割 り 込み終了時に復元 さ れ ます。 NVIC は、 割 り 込みの
テールチ ェ イ ン ニ ン グ も サポー ト し てい ます。
Cortex-M3 で NVIC が使用 さ れてい る 事実は、 Cortex-M3 用のベ ク タ テーブル
が以前の ARM コ ア と は大 き く 異な る こ と を意味 し てい ます。 Cortex-M3 ベ ク
タ テーブルには、 ほ と ん どすべての ARM コ ア と は異な り 、 命令ではな く 例
外ハン ド ラ と ISR のア ド レ ス を含んでい ます。 初期の ス タ ッ ク ポ イ ン タ 、 お
よ び リ セ ッ ト ハン ド ラ のア ド レ ス は、 それぞれ 0x0 お よ び 0x4 に配置 さ れてい
る 必要があ り ます。 こ れ ら のア ド レ ス は、 リ セ ッ ト 時に該当す る CPU レ ジ ス
タ に ロ ー ド さ れ ます。
7-10
Copyright © 2007 ARM Limited. All rights reserved.
ARM DUI 0203HJ
Handling Cortex-M3 Processor ExceptionsCortex-M3 プ ロ セ ッ サ例外処理
7.2
例外テーブルの書き込み
ベ ク タ テーブルにデー タ を入力す る 最 も 簡単な方法は、 分散フ ァ イ ルを使用
し て メ モ リ ア ド レ ス 0x0 に C 配列の関数ポ イ ン タ を配置す る 方法です。 C 配
列を使用す る と 、 初期ス タ ッ ク ポ イ ン タ 、 イ メ ージのエ ン ト リ ポ イ ン ト 、 お
よ び例外ハン ド ラ のア ド レ ス を設定で き ます。
例 7-1 例外ハン ド ラの C 構造例
/* Filename: exceptions.c */
typedef void(* const ExecFuncPtr)(void);
/* Place table in separate section */
#pragma arm section rodata="exceptions_area"
ExecFuncPtr exception_table[] = {
(ExecFuncPtr)&Image$$ARM_LIB_STACKHEAP$$ZI$$Limit,
/* Initial Stack Pointer, from linker-generated symbol
*/
(ExecFuncPtr)&__main,
/* Initial PC, set to entry point */
&NMIException,
&HardFaultException,
&MemManageException,
&BusFaultException,
&UsageFaultException,
0, 0, 0, 0,
/* Reserved */
&SVCHandler,
&DebugMonitor,
0,
/* Reserved */
&PendSVC,
(ExecFuncPtr)&SysTickHandler,
/* Configurable interrupts start here...*/
&InterruptHandler,
&InterruptHandler,
&InterruptHandler
/*
:
*/
};
#pragma arm section
こ の構造内の最初の 2 つの項目は、 初期ス タ ッ ク ポ イ ン タ と イ メ ージのエ ン
ト リ ポ イ ン ト です。 例 7-1 では、 イ メ ージのエ ン ト リ ポ イ ン ト と し て C ラ イ
ブ ラ リ エ ン ト リ ポ イ ン ト (__main) を使用 し てい ます。
例外テーブルには、 独自のセ ク シ ョ ン も あ り ます。 こ れは、 以下の行を使用
し ます。
ARM DUI 0203HJ
Copyright © 2007 ARM Limited. All rights reserved.
7-11
Handling Cortex-M3 Processor ExceptionsCortex-M3 プ ロ セ ッ サ例外処理
#pragma arm section rodata="exceptions_area"
以下では、
#pragma arm section rodata="exceptions_area"
および
#pragma arm section
の間の RO デー タ すべて を、 exceptions_area と い う 独自のセ ク シ ョ ンに配置す
る よ う に コ ンパ イ ラ に指示 し てい ます。 次に、 分散フ ァ イ ルで こ れを参照 し 、
例外テーブルを メ モ リ マ ッ プ内の正 し い位置 (ア ド レ ス 0x0) に配置で き ま
す。
7-12
Copyright © 2007 ARM Limited. All rights reserved.
ARM DUI 0203HJ
Handling Cortex-M3 Processor ExceptionsCortex-M3 プ ロ セ ッ サ例外処理
7.3
例外ハン ド ラの書き込み
コ アでは、 例外の発生時にシ ス テ ム状態を保存 し 、 復帰時にシ ス テ ム状態を
復元 し ます。 例外ハン ド ラ がシ ス テ ム状態を保存ま たは復元す る 必要はあ り
ません。 こ れ ら は通常の ABI 準拠の C 関数 と し て記述で き ます。
ARM アーキ テ ク チ ャ 用のアプ リ ケーシ ョ ンバ イ ナ リ イ ン タ フ ェース (ABI)
では、 各種の ソ ース フ ァ イ ルにおけ る 関数間の呼び出 し な ど のすべての外部
イ ン タ フ ェ ース において、 ス タ ッ ク が 8 バ イ ト 境界で整列 さ れてい る 必要が
あ り ます。 ただ し 、 例えば リ ーフ関数の よ う に、 コ ー ド が内部で 8 バ イ ト 境界
の ス タ ッ ク 整列を保持す る 必要はあ り ません。
こ れは、 IRQ の発生時に ス タ ッ ク が 8 バ イ ト 境界で正 し く 整列 さ れていない
場合があ る こ と を意味 し ます。 リ ビ ジ ョ ン 1 以降では、 Cortex-M3 プ ロ セ ッ サ
は例外の発生時に ス タ ッ ク ポ イ ン タ を自動的に整列で き ます。 こ の動作を有
効にす る には、 コ ン フ ィ グ レーシ ョ ン制御レ ジ ス タ 内のア ド レ ス 0xE000ED14
に STKALIGN (ビ ッ ト 9) を設定 し ます。
リ ビ ジ ョ ン 0 の Cortex-M3 プ ロ セ ッ サ を使用 し てい る 場合、 こ の調整はハー
ド ウ ェ アでは実行 さ れません。 コ ンパ イ ラ は、 ス タ ッ ク を正 し く 整列す る
コ ー ド を IRQ ハン ド ラ 内に生成で き ます。 こ れを行 う には、 IRQ ハン ド ラ に
__irq の接頭文字を付け、 --cpu=Cortex-M3 の代わ り に --cpu=Cortex-M3-rev0 コ ン
パ イ ラ ス イ ッ チを使用す る 必要があ り ます。
例 7-2 単純な C 例外ハン ド ラ
__irq void SysTickHandler(void)
{
printf("----- SysTick Interrupt -----");
}
注
割 り 込みサービ ス ルーチン では、 割 り 込み ソ ース の ク リ ア を処理す る 必要が
あ り ます。
Cortex-M3 プ ロ セ ッ サは、 例外の優先度付け、 例外のネ ス ト 、 お よ び破壊 さ
れ る 可能性のあ る レ ジ ス タ の保存すべて を コ ア内で効率的に処理で き ます。
つま り 、 割 り 込みは各例外ハン ド ラ の開始時に コ アに よ っ て有効に さ れ ます。
ARM DUI 0203HJ
Copyright © 2007 ARM Limited. All rights reserved.
7-13
Handling Cortex-M3 Processor ExceptionsCortex-M3 プ ロ セ ッ サ例外処理
7.4
例外テーブルの配置
例外テーブルはオブジ ェ ク ト 内の独自のセ ク シ ョ ンに配置 さ れてい る ので、
分散フ ァ イ ルを使用 し て 0x0 に簡単に配置で き ます。
例 7-3 分散フ ァ イルへの例外テーブルの配置
LOAD_REGION 0x00000000 0x00200000
{
;; Maximum of 256 exceptions (256*4 bytes == 0x400)
VECTORS 0x0 0x400
{
exceptions.o (exceptions_area, +FIRST)
}
}
注
+FIRST は、 exceptions_area を領域の先頭に配置 し 、 リ ン カの未使用セ ク シ ョ ン
削除 メ カ ニズ ム に よ っ てベ ク タ テーブルが削除 さ れない よ う に し ます。
7-14
Copyright © 2007 ARM Limited. All rights reserved.
ARM DUI 0203HJ
Handling Cortex-M3 Processor ExceptionsCortex-M3 プ ロ セ ッ サ例外処理
7.5
シス テム制御空間レ ジス タ の設定
シ ス テ ム制御空間 (SCS) レ ジ ス タ は、 0xE000E000 にあ り ます。 個々の レ ジ ス
タ は多数存在す る ので、 構造を使用 し て レ ジ ス タ を表すのが最適です。 こ の
構造は、 例外テーブルの場合 と 同 じ よ う な方法を使用 し て分散フ ァ イ ルに追
加す る こ と で、 正 し い メ モ リ 位置に配置で き ます。 例 7-4 は、 SCS レ ジ ス タ
の構造例を示 し てい ます。
例 7-4 SCS レ ジ ス タ の構造
typedef volatile struct {
int MasterCtrl;
int IntCtrlType;
int zReserved008_00c[2];
/* Reserved space */
struct {
int Ctrl;
int Reload;
int Value;
int Calibration;
} SysTick;
int zReserved020_0fc[(0x100-0x20)/4];
/* Reserved space */
/* Offset 0x0100 */
struct {
int Enable[32];
int Disable[32];
int Set[32];
int Clear[32];
int Active[64];
int Priority[64];
} NVIC;
int zReserved0x500_0xcfc[(0xd00-0x500)/4];
/* Reserved space */
/* Offset 0x0d00 */
int CPUID;
int IRQcontrolState;
int ExceptionTableOffset;
int AIRC;
int SysCtrl;
int ConfigCtrl;
int SystemPriority[3];
int SystemHandlerCtrlAndState;
int ConfigurableFaultStatus;
int HardFaultStatus;
int DebugFaultStatus;
int MemManageAddress;
int BusFaultAddress;
int AuxFaultStatus;
int zReserved0xd40_0xd90[(0xd90-0xd40)/4];
/* Reserved space */
ARM DUI 0203HJ
Copyright © 2007 ARM Limited. All rights reserved.
7-15
Handling Cortex-M3 Processor ExceptionsCortex-M3 プ ロ セ ッ サ例外処理
/* Offset 0x0d90 */
struct {
int
int
int
int
int
} MPU;
} SCS_t;
Type;
Ctrl;
RegionNumber;
RegionBaseAddr;
RegionAttrSize;
注
こ れにはデバ イ ス内の SCS レ ジ ス タ すべてが含まれていない場合があ り ま
す。 デバ イ ス のシ リ コ ン製造元か ら 提供 さ れた リ フ ァ レ ン ス マニ ュ アルを参
照 し て下 さ い。
7-16
Copyright © 2007 ARM Limited. All rights reserved.
ARM DUI 0203HJ
Handling Cortex-M3 Processor ExceptionsCortex-M3 プ ロ セ ッ サ例外処理
7.6
個別の IRQ の設定
各 IRQ は、 NVIC レ ジ ス タ の一部であ る 割 り 込み有効設定レ ジ ス タ 内に、 個
別の有効ビ ッ ト を持っ てい ます。 割 り 込みを有効にす る には、 割 り 込み有効
設定レ ジ ス タ の対応す る ビ ッ ト を 1 に設定 し ます。 割 り 込み有効設定レ ジ ス
タ の詳細については、 使用 し てい る デバ イ ス の リ フ ァ レ ン ス マニ ュ アルを参
照 し て下 さ い。
例 7-5 は、 例 7-4 (ページ 7-15) に示す SCS 構造の割 り 込み有効 コ ー ド 例を示
し てい ます。
例 7-5 IRQ 有効関数
void NVIC_enableISR(unsigned isr)
{
/* The isr argument is the number of the interrupt to enable. */
SCS.NVIC.Enable[ (isr/32) ] = 1<<(isr % 32);
}
注
NVIC 領域内の一部の レ ジ ス タ には、 特権モー ド でのみア ク セ ス で き ます。
個別の IRQ を無効にす る には、 割 り 込み有効 ク リ ア レ ジ ス タ 内の該当す る
ビ ッ ト を 0 に ク リ ア し ます。
7.6.1
割 り 込み優先度
割 り 込み優先度レ ジ ス タ を使用す る と 、 各個別の割 り 込みに優先度レベルを
割 り 当て る こ と がで き ます。 実装に応 じ て、 最高 256 の優先度レベルを各個別
の割 り 込みに割 り 当て ら れ ます。 優先度レベルは、 最高 8 ビ ッ ト を使用 し て表
さ れ ます。 4 つの割 り 込み優先度のグループが、 メ モ リ の 1 ワ ー ド に格納 さ れ
ます。
0 は最高の優先度で、 255 は最低の優先度です。
ARM DUI 0203HJ
Copyright © 2007 ARM Limited. All rights reserved.
7-17
Handling Cortex-M3 Processor ExceptionsCortex-M3 プ ロ セ ッ サ例外処理
7.7
スーパーバイザコ ール
スーパーバ イ ザ コール (以前の ソ フ ト ウ ェ ア割 り
込み) を生成 し ます。 スーパーバ イ ザ コ ールは、 通常は特権操作を要求す る
か、 オペレーテ ィ ン グ シ ス テ ム か ら シ ス テ ム リ ソ ース にア ク セ スす る ために
使用 し ます。
SVC 命令 (以前の SWI) は、
SVC 命令には、 通常 SVC 番号 と 呼ばれ る 番号が埋め込まれてい ます。 ほ と ん ど
の ARM プ ロ セ ッ サでは、 こ の番号を使用 し て、 要求 さ れてい る サービ ス を
示す こ と がで き ま し た。 ただ し 、 Cortex-M3 プ ロ セ ッ サでは最初の例外開始時
に引数レ ジ ス タ を ス タ ッ ク に保存 し ます。
SVC ハン ド ラ の最初の命令が実行 さ れ る 前に発生す る 後続の例外に よ り 、 R0
~ R3 に ま だ保持 さ れてい る 引数の コ ピーが壊 さ れて し ま う こ と があ り ます。
こ のため、 SVC ハン ド ラ では引数の ス タ ッ ク コ ピーを使用す る 必要があ り ま
す。 戻 り 値 も 、 ス タ ッ ク レ ジ ス タ 値を変更す る こ と で、 呼び出 し 元に戻す必
要があ り ます。 こ れを行 う には、 短いアセ ン ブ リ コ ー ド を SVC ハン ド ラ の開
始時に実装す る 必要があ り ます。 こ の コ ー ド は、 レ ジ ス タ の保存先の ス タ ッ
ク を識別 し 、 命令か ら SVC 番号を抽出 し 、 番号お よ び引数のポ イ ン タ を C 言
語で記述 さ れたハン ド ラ の メ イ ン本体に渡 し ます。
例 7-6 は、 SVC ハン ド ラ の例を示 し てい ます。 こ の コ ー ド は、 プ ロ セ ッ サが
設定 し た EXC_RETURN 値を テ ス ト し て、 SVC が呼び出 さ れた と き に ど の ス
タ ッ ク ポ イ ン タ が使用 さ れていたか を判断 し ます。 ほ と ん ど のシ ス テ ム では
こ れは不要です。 通常のシ ス テ ム設計では、 スーパーバ イ ザ コ ールはプ ロ セ
ス ス タ ッ ク を使用す る ユーザ コ ー ド か ら のみ行われ る ためです。 その場合、
アセ ン ブ リ コ ー ド は 1 つの MSR 命令に続いてハン ド ラ の C 本体への末端呼び
出 し 分岐 (B 命令) のみで構成で き ます。
例 7-6 SVC ハン ド ラ例
__asm void SVCHandler(void)
{
IMPORT SVCHandler_main
TST lr, #4
MRSEQ r0, MSP
MRSNE r0, PSP
B SVCHandler_main
}
void SVCHandler_main(unsigned int * svc_args)
{
unsigned int svc_number;
/*
7-18
Copyright © 2007 ARM Limited. All rights reserved.
ARM DUI 0203HJ
Handling Cortex-M3 Processor ExceptionsCortex-M3 プ ロ セ ッ サ例外処理
* Stack contains:
* r0, r1, r2, r3, r12, r14, the return address and xPSR
* First argument (r0) is svc_args[0]
*/
svc_number = ((char *)svc_args[6])[-2];
switch(svc_number)
{
case SVC_00:
/* Handle SVC 00 */
break;
case SVC_01:
/* Handle SVC 01 */
break;
default:
/* Unknown SVC */
break;
}
}
例 7-7 は、 い く つかの SVC に対す る 異な る 宣言方法を示 し てい ます。 __svc は、
指定 し た番号を含む SVC 命令に関数 コ ールを置 き 換え る コ ンパ イ ラ キー ワ ー
ド です。
例 7-7 C コ ー ド からの SVC の呼び出 し 例
#define SVC_00 0x00
#define SVC_01 0x01
void __svc(SVC_00) svc_zero(const char *string);
void __svc(SVC_01) svc_one(const char *string);
int call_system_func(void)
{
svc_zero("String to pass to SVC handler zero");
svc_one("String to pass to a different OS function");
}
ARM DUI 0203HJ
Copyright © 2007 ARM Limited. All rights reserved.
7-19
Handling Cortex-M3 Processor ExceptionsCortex-M3 プ ロ セ ッ サ例外処理
7.8
シ ス テム タ イ マ
SCS には、 オペレーテ ィ ン グ シ ス テ ムが別のプ ラ ッ ト フ ォ ーム か ら の移植を
簡易化す る ために使用で き る シ ス テ ム タ イ マ、 SysTick が用意 さ れてい ます。
SysTick は ソ フ ト ウ ェ アでポー リ ン グす る か、 割 り 込みを生成す る よ う に
SysTick を設定で き ます。 SysTick 割 り 込みはベ ク タ テーブルに独自のエ ン ト リ
を持っ てい る ので、 独自のハン ド ラ を所有で き ます。
表 7-3 は、 SysTick の設定に使用す る 4 つの レ ジ ス タ について説明 し てい ます。
表 7-3
名前
ア ド レス
説明
SysTick Control and Status
0xE000E010
SysTick の基本的な制御 : 有効、 ク ロ ッ ク ソ ース、 割 り 込み、 ま
たはポー リ ン グ
SysTick Reload Value
0xE000E014
0 に達 し た と き に Current Value レ ジ ス タ を ロ ー ド する ための値
SysTick Current Value
0xE000E018
カ ウ ン ト ダ ウ ンの現在値
SysTick Calibration Value
0xE000E01C
10ms 間隔を生成す る ための Tick 数 と 他の情報
7.8.1
SysTick の設定
SysTick を設定す る には、 SysTick イ ベン ト 間に必要な間隔を SysTick Reload
Value レ ジ ス タ に ロ ー ド し ます。 SysTick Control and Status レ ジ ス タ の タ イ マ割
り 込み、 つま り COUNTFLAG ビ ッ ト は、 1 か ら 0 に遷移 し た と き にア ク テ ィ
ブにな る ので、 n+1 ク ロ ッ ク Tick ご と にア ク テ ィ ブにな り ます。 100 の期間が
必要な場合は、 99 を SysTick Reload Value レ ジ ス タ に書 き 込みます。 SysTick
Reload Value レ ジ ス タ は、 1 ~ 0x00FFFFFF の値を サポー ト し てい ます。
SysTick を使用 し て 1ms な ど の一定の間隔で イ ベン ト を生成す る 場合は、
SysTick Calibration Value レ ジ ス タ を使用 し て、 Reload レ ジ ス タ の値を ス ケー
リ ン グで き ます。 SysTick Calibration Value レ ジ ス タ は、 10ms の期間のパル ス
数を TENMS フ ィ ール ド のビ ッ ト [23:0] に含んでい る 読み取 り 専用レ ジ ス タ
です。
こ の レ ジ ス タ には SKEW ビ ッ ト が含ま れてい ます。 ビ ッ ト [30] == 1 は、
TENMS セ ク シ ョ ン内の 10ms の調整が、ク ロ ッ ク 周波数が原因で正確に 10ms
にな っ ていない こ と を示 し ます。 ビ ッ ト [31] == 1 は、 リ フ ァ レ ン ス ク ロ ッ ク
が提供 さ れてい る こ と を示 し ます。
7-20
Copyright © 2007 ARM Limited. All rights reserved.
ARM DUI 0203HJ
Handling Cortex-M3 Processor ExceptionsCortex-M3 プ ロ セ ッ サ例外処理
Control and Status レ ジ ス タ は、 COUNTFLAG の ビ ッ ト [16] を読み取 る か、
割 り 込みを生成す る SysTick に よ っ て タ イ マ を ポー リ ン グで き ます。
デフ ォ ル ト では、 SysTick はポー リ ン グモー ド 用に設定 さ れてい ます。 こ の
モー ド では、 ユーザは COUNTFLAG を ポー リ ン グ し て、 SysTick イ ベン ト が
発生 し たか ど う か を確認 し ます。 イ ベン ト の発生は、 COUNTFLAG が設定 さ
れ る こ と に よ っ て示 さ れます。 Control and Status レ ジ ス タ を読み取 る と 、
COUNTFLAG が ク リ ア さ れ ます。 SysTick が割 り 込みを生成す る よ う に設定す
る には、 SysTick Control and Status レ ジ ス タ の TICKINT の ビ ッ ト [1] を 1 に
設定 し ます。 NVIC 内の該当す る 割 り 込みを有効に し 、 CLKSOURCE の ビ ッ
ト [2] を使用 し て ク ロ ッ ク ソ ース を選択す る 必要 も あ り ます。 こ の ビ ッ ト を
1 に設定す る と コ ア ク ロ ッ ク が選択 さ れ、 0 に設定す る と 外部 リ フ ァ レ ン ス ク
ロ ッ ク が選択 さ れます。
タ イ マは、 SysTick Status and Control レ ジ ス タ の ビ ッ ト [0] を 1 に設定 し て有
効に し ます。
ARM DUI 0203HJ
Copyright © 2007 ARM Limited. All rights reserved.
7-21
Handling Cortex-M3 Processor ExceptionsCortex-M3 プ ロ セ ッ サ例外処理
7.9
他の ARM プ ロ セ ッ サ用に記述 さ れた例外処理 コ ー ド の移植
例外ハン ド ラ は、 Cortex-M3 に適応 さ せ る 必要があ り ます。
アセ ン ブ リ 言語の低レベルハン ド ラ は通常は必要あ り ません。 再入可能は コ
アに よ っ て処理 さ れ る ためです。 低レベルハン ド ラ が追加の作業を行 う 場合
は、 新 し いハン ド ラ が呼び出す こ と がで き る 個別の関数にその一部を分割す
る 必要が生 じ る 場合があ り ます。 明確 さ を保つために、 IRQ ハン ド ラ は __irq
キー ワ ー ド を使用 し てマー ク 付け し 、 コ ンパ イ ラ が Cortex-M3 リ ビ ジ ョ ン 0
ハー ド ウ ェ アの ス タ ッ ク 調整を維持で き る よ う に し て下 さ い。
Cortex-M3 には FIQ 入力がないので、 ARM7TDMI プ ロ ジ ェ ク ト で FIQ を示す
ペ リ フ ェ ラ ルは、 高優先度のベ ク タ 割 り 込みに移動す る 必要があ り ます。
Cortex-M3 プ ロ セ ッ サにはバン ク 付 き レ ジ ス タ がないので、 こ の種の割 り 込
み用のハン ド ラ がバン ク 付 き FIQ レ ジ ス タ を使用 し ない よ う にす る 必要が生
じ る こ と があ り ます。 ま た、 他の通常の IRQ ハン ド ラ と 同 じ よ う に R8 ~ R12
を ス タ ッ ク す る 必要があ り ます。
最後に、 新 し い初期化関数を記述 し 、 割 り 込み優先度を含む NVIC を設定す
る 必要があ り ます。 その後、 メ イ ン アプ リ ケーシ ョ ン コ ー ド を入力す る 前に、
割 り 込みを有効に し ます。
7.9.1
重要なセ ク シ ョ ン および例外動作
Cortex-M3 プ ロ セ ッ サでは、 例外の優先度付け、 例外のネ ス ト 、 お よ び破壊
さ れ る 可能性のあ る レ ジ ス タ の保存はすべて コ アに よ っ て処理 さ れ る ので、
処理は非常に効率が高 く な り 、 割 り 込みレ イ テ ン シが最小化 さ れ ます。 つま
り 、 割 り 込みは各例外ハン ド ラ の開始時に コ アに よ っ て有効に さ れ ます。 ま
た、 例外か ら の復帰時に割 り 込みが無効に さ れ る 場合、 割 り 込みはプ ロ セ ッ
サに よ っ て自動的に再度有効に さ れ ません。 割 り 込み と 例外か ら の復帰の自
動有効化を実行す る こ と はで き ません。 ハン ド ラ で割 り 込みを一時的に無効
に し た場合は、 復帰のための命令を実行す る 前に、 別の命令で割 り 込みを再
度有効にす る 必要があ り ます。 こ のため、 例外が復帰直前に発生す る 場合が
あ り ます。
シ ス テ ム設計に よ っ ては、 こ れ ら の例外モデルの機能が コ ー ド 内の重要なセ
ク シ ョ ン に影響を及ぼす場合があ り ます。 重要なセ ク シ ョ ン と は、 実行中に
割 り 込みを無効に し て、 割 り 込み不可能なブ ロ ッ ク と し て実行す る 必要があ
る セ ク シ ョ ン です。 こ の例には、 オペレーテ ィ ン グ シ ス テ ムの コ ン テ キ ス ト
切 り 替え コ ー ド な ど があ り ます。 一部の従来の コ ー ド では、 例外ハン ド ラ の
開始時に割 り 込みが無効に さ れてお り 、 重要なセ ク シ ョ ンの実行が完了 し た
と き にのみ コ ー ド に よ っ て明示的に有効に さ れ る も の と 想定 し てい る 場合が
7-22
Copyright © 2007 ARM Limited. All rights reserved.
ARM DUI 0203HJ
Handling Cortex-M3 Processor ExceptionsCortex-M3 プ ロ セ ッ サ例外処理
あ り ます。 こ れ ら の想定は、 Cortex-M3 の新 し い例外モデルには当ては ま ら な
いので、 こ の よ う な コ ー ド は新 し いモデルに合わせて記述 し 直す必要が生 じ
る 場合があ り ます。
ARM DUI 0203HJ
Copyright © 2007 ARM Limited. All rights reserved.
7-23
Handling Cortex-M3 Processor ExceptionsCortex-M3 プ ロ セ ッ サ例外処理
7-24
Copyright © 2007 ARM Limited. All rights reserved.
ARM DUI 0203HJ
第 8章
デバ ッ グ通信チ ャ ネル
本章では、 デバ ッ グ通信チ ャ ネル (DCC) の使用方法について説明 し ます。
本章は以下のセ ク シ ョ ンか ら 構成 さ れてい ます。
•
デバ ッ グ通信チ ャ ネルについて (ページ 8-2)
•
•
•
•
ARM DUI 0203HJ
タ ーゲ ッ ト のデー タ 転送 (ページ 8-3)
デバ ッ グ通信のポー リ ン グ (ページ 8-4)
割 り 込み駆動型デバ ッ グ通信 (ページ 8-8)
Thumb 状態か ら のア ク セ ス (ページ 8-9)
Copyright © 2007 ARM Limited. All rights reserved.
8-1
デバ ッ グ通信チ ャ ネル
8.1
デバ ッ グ通信チ ャ ネルについて
ARM® コ アに組み込まれてい る EmbeddedICE® の ロ ジ ッ ク には、 デバ ッ グ通信
チ ャ ネルが実装 さ れてい ます。 デバ ッ グ通信チ ャ ネルに よ り 、 JTAG ポー ト と
プ ロ ト コ ル コ ンバー タ を使用 し て、 プ ロ グ ラ ムの流れを停止 さ せた り デバ ッ
グ状態に入っ た り す る こ と な く 、 タ ーゲ ッ ト と ホ ス ト デバ ッ ガの間でデー タ
の受け渡 し を行 う こ と がで き ます。 本章では、 タ ーゲ ッ ト 上で実行 さ れ る プ
ロ グ ラ ム と ホ ス ト デバ ッ ガか ら DCC にア ク セ スす る 方法について説明 し ま
す。
8-2
Copyright © 2007 ARM Limited. All rights reserved.
ARM DUI 0203HJ
デバ ッ グ通信チ ャ ネル
8.2
タ ーゲ ッ ト のデー タ 転送
DCC には、 ARM 命令の MCR と MRC を使用 し て、 ARM コ ア上の コ プ ロ セ ッ サ
14 と し て タ ーゲ ッ ト か ら ア ク セ ス し ます。
デー タ 転送には以下の 2 つの レ ジ ス タ が使用 さ れ ます。
通信デー タ 読み出 し レ ジ ス タ
デバ ッ ガか ら のデー タ の受信に使用 さ れ る 32 ビ ッ ト 幅の レ ジ ス
タ です。 以下の命令では、 こ の読み出 し レ ジ ス タ の値を Rd に返
し ます。
MRC p14, 0, Rd, c1, c0
通信デー タ 書 き 込みレ ジ ス タ
デバ ッ ガへのデー タ の送信に使用 さ れ る 32 ビ ッ ト 幅の レ ジ ス タ
です。 以下の命令では、 こ の書 き 込みレ ジ ス タ に Rn の値を書 き
込みます。
MCR p14, 0, Rn, c1, c0
注
ARM10 お よ び ARM11 コ アの DCC レ ジ ス タ へのア ク セ ス については、各 コ ア
のテ ク ニ カル リ フ ァ レ ン ス マニ ュ アルを参照 し て下 さ い。 ARM9 以降のプ ロ
セ ッ サでは、 使用 さ れ る 命令、 ス テー タ ス ビ ッ ト の位置、 お よ びス テー タ ス
ビ ッ ト の解釈方法が異な り ます。
ARM DUI 0203HJ
Copyright © 2007 ARM Limited. All rights reserved.
8-3
デバ ッ グ通信チ ャ ネル
8.3
デバ ッ グ通信のポー リ ング
DCC では、 通信デー タ 読み出 し レ ジ ス タ と 通信デー タ 書 き 込みレ ジ ス タ に加
え、 通信デー タ 制御レ ジ ス タ が使用 さ れ ます。
8.3.1
通信デー タ 制御レ ジ ス タ
以下の命令では、 こ の制御レ ジ ス タ の値を Rd に返 し ます。
MRC p14, 0, Rd, c0, c0
こ の制御レ ジ ス タ 内の 2 つの ビ ッ ト に よ っ て、 タ ーゲ ッ ト と ホ ス ト デバ ッ ガ
の間の同期ハン ド シ ェー ク が制御 さ れ ます。
ビ ッ ト 1 (W ビ ッ ト )
通信デー タ 書 き 込みレ ジ ス タ が ( タ ーゲ ッ ト 側か ら 見て)
空いてい る か ど う か を示 し ます。
W=0
タ ーゲ ッ ト アプ リ ケーシ ョ ン が新 し いデー タ を
書 き 込む こ と がで き ます。
W=1
ホ ス ト デバ ッ ガが書 き 込みレ ジ ス タ の新 し い
デー タ を ス キ ャ ン ア ウ ト で き ます。
ビ ッ ト 0 (R ビ ッ ト )
通信デー タ 読み出 し レ ジ ス タ に ( タ ーゲ ッ ト 側か ら 見て)
新 し いデー タ があ る か ど う か を示 し ます。
R=1
タ ーゲ ッ ト アプ リ ケーシ ョ ン が新 し いデー タ を
読み出す こ と がで き ます。
R=0
ホ ス ト デバ ッ ガが新 し いデー タ を読み出 し レ ジ
ス タ に ス キ ャ ン イ ン で き ます。
注
コ プ ロ セ ッ サ 14 はデバ ッ ガに と っ て何の意味 も 持たないため、 デバ ッ ガが コ
プ ロ セ ッ サ 14 を使用 し てデバ ッ グ通信チ ャ ネルに直接ア ク セ スす る こ と はで
き ません。 その代わ り 、 デバ ッ ガは ス キ ャ ンチ ェ イ ン を使用す る こ と に よ っ
て、 DCC レ ジ ス タ と の間で読み出 し ま たは書 き 込みを行 う こ と がで き ます。
DCC のデー タ レ ジ ス タ と 制御レ ジ ス タ は、 EmbeddedICE ロ ジ ッ ク 内のア ド レ
ス にマ ッ プ さ れ ます。 EmbeddedICE ロ ジ ッ ク レ ジ ス タ の表示方法については、
デバ ッ ガ と デバ ッ グ タ ーゲ ッ ト のマニ ュ アルを参照 し て下 さ い。
8-4
Copyright © 2007 ARM Limited. All rights reserved.
ARM DUI 0203HJ
デバ ッ グ通信チ ャ ネル
8.3.2
タ ーゲ ッ ト か ら デバ ッ ガへの通信
以下は、 ARM コ アで実行 さ れてい る アプ リ ケーシ ョ ン か ら ホ ス ト で実行 さ れ
てい る デバ ッ ガへの通信を行 う と き の イ ベン ト シーケ ン ス です。
1.
タ ーゲ ッ ト アプ リ ケーシ ョ ンが、 DCC 書 き 込みレ ジ ス タ が空いてい る
か ど う か を確認 し ます。 こ の操作は、 MRC 命令を使用 し てデバ ッ グ通信
チ ャ ネル制御レ ジ ス タ を読み出 し 、 W ビ ッ ト が ク リ ア さ れてい る か ど う
か を確認す る こ と に よ っ て行われ ます。
2.
W ビ ッ ト が ク リ ア さ れてい る 場合、 通信デー タ 書 き 込みレ ジ ス タ は ク リ
ア さ れてい る ので、 アプ リ ケーシ ョ ンは コ プ ロ セ ッ サ 14 への MCR 命令を
使用 し て こ の レ ジ ス タ に ワー ド を書 き 込みます。 こ の レ ジ ス タ への書 き
込みに よ っ て、 W ビ ッ ト が自動的に設定 さ れます。 W ビ ッ ト が設定 さ れ
てい る 場合は、 デバ ッ ガに よ っ て通信デー タ 書 き 込みレ ジ ス タ が ク リ ア
さ れてい ません。 さ ら に ワ ー ド を送信す る 必要があ る 場合、 アプ リ ケー
シ ョ ン では、 W ビ ッ ト が ク リ ア さ れ る ま で こ のビ ッ ト を ポー リ ン グす る
必要があ り ます。
3.
デバ ッ ガが、 ス キ ャ ンチ ェ イ ン 2 を経由 し て通信デー タ 制御レ ジ ス タ を
ポー リ ン グ し ます。 W ビ ッ ト が設定 さ れてい る こ と を検出 し た場合、 デ
バ ッ ガは DCC デー タ レ ジ ス タ を読み出 し て、 アプ リ ケーシ ョ ン か ら 送
信 さ れた メ ッ セージ を読み出す こ と がで き ます。 こ のデー タ 読み出 し 処
理に よ っ て、 通信デー タ 制御レ ジ ス タ 内の W ビ ッ ト が自動的に ク リ ア
さ れ ます。
例 8-1 は こ れを実装す る コ ー ド を示 し てい ます。 こ のサン プル コ ー ド は、 メ イ
ンサン プルデ ィ レ ク ト リ の ...\dcc\outchan.s に収録 さ れてい ます。
例 8-1
AREA
ENTRY
MOV
ADR
pollout
MRC
TST
BNE
write
LDR
MCR
SUBS
ARM DUI 0203HJ
OutChannel, CODE, READONLY
r1,#3
r2, outdata
; Number of words to send
; Address of data to send
p14,0,r0,c0,c0 ; Read control register
r0, #2
pollout
; if W set, register still full
r3,[r2],#4
;
;
p14,0,r3,c1,c0 ;
r1,r1,#1
;
Read word from outdata
into r3 and update the pointer
Write word from r3
Update counter
Copyright © 2007 ARM Limited. All rights reserved.
8-5
デバ ッ グ通信チ ャ ネル
BNE
pollout
MOV
r0, #0x18
LDR
r1, =0x20026
SVC
0x123456
outdata
DCB "Hello there!"
END
;
;
;
;
Loop if more words to be written
Angel_SWIreason_ReportException
ADP_Stopped_ApplicationExit
ARM semihosting (formerly SWI)
サン プルを実行す る には
1.
以下の コ マ ン ド を入力 し て、 outchan.s を アセ ン ブル し ます。
armasm --debug outchan.s
2.
以下の コ マ ン ド を入力 し て、 出力オブジ ェ ク ト を リ ン ク し ます。
armlink outchan.o -o outchan.axf
こ の リ ン ク 手順で、 実行可能フ ァ イ ル outchan.axf が作成 さ れ ます。
3.
8.3.3
イ メ ージ を ロ ー ド し て実行 し ます。 詳細については、 デバ ッ ガのマニ ュ
アルを参照 し て下 さ い。
デバ ッ ガから タ ーゲ ッ ト への通信
以下は、 ホ ス ト で実行 さ れてい る デバ ッ ガか ら コ アで実行 さ れてい る アプ リ
ケーシ ョ ンに メ ッ セージ を転送す る と き の イ ベン ト シーケ ン ス です。
1.
デバ ッ ガが通信デー タ 制御レ ジ ス タ の R ビ ッ ト を ポー リ ン グ し ます。 R
ビ ッ ト が ク リ ア さ れてい る 場合は、 通信デー タ 読み出 し レ ジ ス タ が ク リ
ア さ れてい る ので、 タ ーゲ ッ ト アプ リ ケーシ ョ ン が読み出すデー タ を こ
の レ ジ ス タ に書 き 込む こ と がで き ます。
2.
デバ ッ ガが ス キ ャ ンチ ェ イ ン 2 を経由 し て、 通信デー タ 読み出 し レ ジ ス
タ にデー タ を ス キ ャ ン イ ン し ます。 こ れに よ っ て通信デー タ 制御レ ジ ス
タ 内の R ビ ッ ト が自動的に設定 さ れます。
3.
タ ーゲ ッ ト アプ リ ケーシ ョ ン が通信デー タ 制御レ ジ ス タ 内の R ビ ッ ト を
ポー リ ン グ し ます。 こ の ビ ッ ト が設定 さ れてい る 場合は、 アプ リ ケー
シ ョ ンが コ プ ロ セ ッ サ 14 か ら の読み出 し を行 う MRC 命令を使用 し て読み
出す こ と がで き る デー タ が、 通信デー タ 読み出 し レ ジ ス タ 内に存在 し ま
す。 R ビ ッ ト は こ の読み出 し 命令に よ っ て ク リ ア さ れ ます。
例 8-2 (ページ 8-7) の タ ーゲ ッ ト アプ リ ケーシ ョ ン コ ー ド は、 こ のシーケ ン
ス を示 し てい ます。 こ のサ ンプル コ ー ド は、 メ イ ンサ ンプルデ ィ レ ク ト リ の
...\dcc\inchan.s にあ り ます。
8-6
Copyright © 2007 ARM Limited. All rights reserved.
ARM DUI 0203HJ
デバ ッ グ通信チ ャ ネル
サ ンプルを実行す る には
1.
And goodbye! な ど の文字列を含んでい る 入力フ ァ イ ルを ホ ス ト 上で作成
し ます。
2.
以下の コ マ ン ド を入力 し て、 inchan.s を アセ ン ブル し ます。
armasm --debug inchan.s
3.
以下の コ マ ン ド を入力 し て、 出力オブジ ェ ク ト を リ ン ク し ます。
armlink inchan.o -o inchan.axf
こ の リ ン ク 手順で、 実行可能フ ァ イ ル inchan.axf が作成 さ れます。
4.
イ メ ージ を ロ ー ド し て実行 し ます。 詳細については、 デバ ッ ガのマニ ュ
アルを参照 し て下 さ い。
例 8-2
AREA
ENTRY
MOV
LDR
pollin
MRC
TST
BEQ
read
MRC
STR
SUBS
BNE
MOV
LDR
SVC
AREA
indata
DCB
END
ARM DUI 0203HJ
InChannel, CODE, READONLY
r1,#3
r2, =indata
; Number of words to read
; Address to store data read
p14,0,r0,c0,c0 ; Read control register
r0, #1
pollin
; If R bit clear then loop
p14,0,r3,c1,c0 ; read word into r3
r3,[r2],#4
; Store to memory and
; update pointer
r1,r1,#1
; Update counter
pollin
; Loop if more words to read
r0, #0x18
; Angel_SWIreason_ReportException
r1, =0x20026
; ADP_Stopped_ApplicationExit
0x123456
; ARM semihosting (formerly SWI)
Storage, DATA, READWRITE
"Duffmessage#"
Copyright © 2007 ARM Limited. All rights reserved.
8-7
デバ ッ グ通信チ ャ ネル
8.4
割 り 込み駆動型デバ ッ グ通信
デバ ッ グ通信のポー リ ン グ (ページ 8-4) で示 し たサン プルでは、 DCC のポー
リ ン グが行われます。 こ れ ら のサ ンプルは、 COMMRX 信号 と COMMTX 信号を
Embedded ICE ロ ジ ッ ク か ら 割 り 込み コ ン ト ロ ー ラ に接続す る こ と に よ り 、 割
り 込み駆動型のサ ンプルに変換で き ます。
割 り 込み駆動型のサン プルに変換後、 例 8-1 (ページ 8-5) と 例 8-2 (ページ
8-7) の読み出 し コ ー ド と 書 き 込み コ ー ド を割 り 込みハン ド ラ 内に移動で き ま
す。
割 り 込みハン ド ラ の書 き 込みの詳細については、 割 り 込みハン ド ラ (ページ
6-30) を参照 し て下 さ い。
8-8
Copyright © 2007 ARM Limited. All rights reserved.
ARM DUI 0203HJ
デバ ッ グ通信チ ャ ネル
8.5
Thumb 状態からのア ク セス
ARMv6T2 以前のプ ロ セ ッ サでは、 コ プ ロ セ ッ サ命令が含まれていないため、
コ アが Thumb 状態の間はデバ ッ グ通信チ ャ ネルを使用で き ません。
こ の問題の解決策 と し ては以下の 3 つの方法が考え ら れ ます。
ARM DUI 0203HJ
•
各ポー リ ン グルーチン を SVC ハン ド ラ 内に記述 し 、 ARM 状態ま たは
Thumb 状態の と き に実行す る 。 SVC ハン ド ラ に入 る と コ アがす ぐ に
ARM 状態にな る ため、 コ プ ロ セ ッ サ命令を使用で き る よ う にな り ます。
SVC の詳細については、 「第 6 章 プ ロ セ ッ サ例外処理」 を参照 し て下 さ
い。
•
Thumb コ ー ド で、 ポー リ ン グ を実装す る ARM サブルーチンへの イ ン
タ ー ワー ク 呼び出 し を発生 さ せ る 。 ARM コ ー ド と Thumb コ ー ド の混用
の詳細については、 「第 4 章 ARM と Thumb の イ ン タ ーワー ク 」 を参照 し
て下 さ い。
•
ポー リ ン グ通信ではな く 、 割 り 込み駆動型通信を使用す る 。 割 り 込みハ
ン ド ラ を ARM 命令セ ッ ト 状態で実行す る こ と に よ り 、 コ プ ロ セ ッ サ命
令に直接ア ク セ ス で き ます。
Copyright © 2007 ARM Limited. All rights reserved.
8-9
デバ ッ グ通信チ ャ ネル
8-10
Copyright © 2007 ARM Limited. All rights reserved.
ARM DUI 0203HJ
付録 A
セ ミ ホス テ ィ ン グ
本章では、 セ ミ ホ ス テ ィ ン グ メ カ ニズ ム について説明 し ます。 本章は以下の
セ ク シ ョ ンか ら 構成 さ れてい ます。
•
セ ミ ホ ス テ ィ ン グについて (ページ A-2)
•
•
•
ARM DUI 0203HJ
セ ミ ホ ス テ ィ ン グの実装 (ページ A-6)
セ ミ ホ ス テ ィ ン グオペレーシ ョ ン (ページ A-8)
デバ ッ グエージ ェ ン ト イ ン タ ラ ク シ ョ ン SVC (ページ A-26)
Copyright © 2007 ARM Limited. All rights reserved.
A-1
セ ミ ホステ ィ ング
A.1
セ ミ ホス テ ィ ングについて
セ ミ ホ ス テ ィ ン グ を使用す る と 、 ARM® タ ーゲ ッ ト 上で実行 さ れてい る コ ー
ド で、 RealView® Debugger を実行 し てい る ホ ス ト コ ン ピ ュ ー タ の I/O 機能を使
用す る こ と がで き ます。 こ れに よ り 、 ホ ス ト コ ン ピ ュ ー タ のキーボー ド 入力、
画面出力、 デ ィ ス ク I/O な ど を使用で き ます。
A.1.1
セ ミ ホス テ ィ ン グ と は
セ ミ ホ ス テ ィ ン グ と は、 ARM タ ーゲ ッ ト 上のアプ リ ケーシ ョ ン コ ー ド か ら 発
行 さ れ る 入出力要求を、 デバ ッ ガが実行 さ れてい る ホ ス ト コ ン ピ ュ ー タ に伝
達す る メ カ ニズ ム です。 例えば、 こ の メ カ ニ ズ ム を使用す る と 、 printf() や
scanf() な ど の C ラ イ ブ ラ リ 関数で、 タ ーゲ ッ ト シ ス テ ム上の画面 と キーボー
ド ではな く 、 ホ ス ト の画面 と キーボー ド を使用す る こ と がで き ます。
開発時に使用す る ハー ド ウ ェ アには、 完成時のシ ス テ ム に備わ る 入出力機能
がすべて用意 さ れてい る と は限 り ません。 セ ミ ホ ス テ ィ ン グ を使用す る こ と
で、 そ う し た機能を ホ ス ト コ ン ピ ュ ー タ の機能に よ り 補完す る こ と がで き ま
す。
セ ミ ホ ス テ ィ ン グは、 プ ロ グ ラ ム制御か ら 例外を生成す る 、 定義済みの ソ フ
ト ウ ェ ア命令 (SVC な ど) のセ ッ ト に よ っ て実装 さ れます。 アプ リ ケーシ ョ
ン が適切なセ ミ ホ ス テ ィ ン グ コ ールを実行す る と 、 デバ ッ グエージ ェ ン ト が
例外を処理 し ます。 デバ ッ グエージ ェ ン ト は、 ホ ス ト と の間で必要 と な る 通
信手段を提供 し ます。
セ ミ ホ ス テ ィ ン グ イ ン タ フ ェース は、 ARM Limited が提供す る すべてのデ
バ ッ グエージ ェ ン ト で共通です。 セ ミ ホ ス テ ッ ド オペレーシ ョ ンは、 RealView
ARMulator® ISS (RVISS)、 Instruction Set System Model (ISSM)、 RealView
ICE、 ま たは RealMonitor を使用す る 場合に機能 し 、 移植作業は必要あ り ませ
ん。 図 A-1 (ページ A-3) を参照 し て下 さ い。
多 く の場合、 セ ミ ホ ス テ ィ ン グは ラ イ ブ ラ リ 関数内の コ ー ド か ら 呼び出 さ れ
ます。 アプ リ ケーシ ョ ン か ら セ ミ ホ ス テ ィ ン グオペレーシ ョ ン を直接呼び出
す こ と も で き ます。 ARM C ラ イ ブ ラ リ でのセ ミ ホ ス テ ィ ン グのサポー ト につ
いては、 『 ラ イ ブ ラ リ ガ イ ド 』 の 「第 2 章 C の ラ イ ブ ラ リ と C++ の ラ イ ブ ラ
リ 」 を参照 し て下 さ い。
A-2
Copyright © 2007 ARM Limited. All rights reserved.
ARM DUI 0203HJ
セ ミ ホス テ ィ ング
printf("hello\n");
Target
Application Code
printf()
SVC
C Library Code
SVC handled by
debug agent
debugger
Communciation with
debugger running
on host
Host
hello
Text displayed
on host screen
図 A-1 セ ミ ホス テ ィ ングの概要
注
ARMv7 よ り 前の ARM プ ロ セ ッ サでは、 SVC 命令 (以前は SWI 命令) を使用 し
てセ ミ ホ ス テ ィ ン グ呼び出 し を行い ます。 ただ し 、 Cortex-M1 や Cortex-M3 な
ど の v6-M ま たは v7-M プ ロ セ ッ サ用に コ ンパ イ ルす る 場合、 セ ミ ホ ス テ ィ ン
グは BKPT 命令を使用 し て実装 さ れ ます。
A.1.2
セ ミ ホス テ ィ ン グ イ ン タ フ ェ ース
ARM と Thumb® の SVC 命令には、 アプ リ ケーシ ョ ン コ ー ド に よ っ て使用 さ れ
る SVC 値がエ ン コ ー ド さ れ る フ ィ ール ド があ り ます。 こ の値はシ ス テ ム内の
SVC ハン ド ラ に よ っ てデ コ ー ド す る こ と がで き ます。
注
Cortex-M1 や Cortex-M3 な ど の v6-M ま たは v7-M プ ロ セ ッ サ用に コ ンパ イ ル
す る 場合、 Thumb SVC 命令ではな く 、 Thumb BKPT 命令を使用 し ます。 BKPT お よ
び SVC には、 いずれ も 8 ビ ッ ト の イ ミ デ ィ エー ト 値を指定 し ます。 それ以外の
点ではセ ミ ホ ス テ ィ ン グは、 サポー ト さ れてい る すべての ARM プ ロ セ ッ サ
において同様に機能 し ます。
ARM DUI 0203HJ
Copyright © 2007 ARM Limited. All rights reserved.
A-3
セ ミ ホステ ィ ング
セ ミ ホ ス テ ィ ン グオペレーシ ョ ンの要求には、 1 つの SVC 値だけが使用 さ れ
ます。 そのため、 他の SVC 値はアプ リ ケーシ ョ ン ま たはオペレーテ ィ ン グ シ
ス テ ム で使用で き ます。 セ ミ ホ ス テ ィ ン グに使用 さ れ る SVC 値は、 タ ーゲ ッ
ト アーキ テ ク チ ャ ま たはプ ロ セ ッ サに応 じ て以下の よ う に異な り ます。
SVC 0x123456 すべてのアーキ テ ク チ ャ の ARM 状態時
SVC 0xAB
Thumb 状態時 (ARMv7-M を除 く )、 お よ び ARM 状態時。 こ の動
作は、 ARM ま たはサー ド パーテ ィ のすべて のデバ ッ グ タ ーゲ ッ
ト で保証 さ れてい る と は限 り ません。
BKPT 0xAB
ARMv7-M の Thumb 状態時のみ
セ ミ ホ ス テ ィ ン グオペレーシ ョ ンの値の変更 (ページ A-5) も 参照 し て下 さ
い。
SVC 値に よ っ て、 その SVC 命令がセ ミ ホ ス テ ィ ン グ要求であ る こ と がデバ ッ
グエージ ェ ン ト に通知 さ れ ます。 操作を区別す る ために、 操作の タ イ プが r0
で渡 さ れ ます。 他のすべてのパ ラ メ ー タ は、 r1 が示すブ ロ ッ ク で渡 さ れ ます。
結果は、 明示的な戻 り 値、 ま たはデー タ ブ ロ ッ ク を指すポ イ ン タ と し て、 r0
に返 さ れ ます。 結果が返 さ れない場合で も 、 r0 の内容は破壊 さ れ ます。
r0 で渡 さ れ る 使用可能なセ ミ ホ ス テ ィ ン グオペレーシ ョ ン の値は、 以下の よ
う に割 り 当て ら れてい ます。
0x00-0x31
ARM 社に よ っ て使用 さ れ ます。
0x32-0xFF
将来の用途に備え て ARM 社に よ っ て予約 さ れてい ます。
0x100-0x1FF
ユーザアプ リ ケーシ ョ ン用に予約 さ れてい ます。 ARM 社に よ っ
て使用 さ れ ません。
ただ し 、 独自の SVC 操作を記述す る 場合は、 セ ミ ホ ス テ ッ ド
SVC 値や こ れ ら の操作の タ イ プ を示す値ではな く 、 別の SVC 値
を使用す る こ と をお勧め し ます。
0x200-0xFFFFFFFF
こ れ ら の値は未定義です。 現在は使用 さ れてい ませんが、 こ れ ら
の値は使用 し ないで下 さ い。
以下のセ ク シ ョ ン では、 操作の名前の後にあ る 括弧内の値が、 r0 に格納す る
値を示 し ます (例 : SYS_OPEN (0x01))。
A-4
Copyright © 2007 ARM Limited. All rights reserved.
ARM DUI 0203HJ
セ ミ ホス テ ィ ング
アセ ン ブ リ 言語の コ ー ド か ら SVC を呼び出す場合は、 semihost.h 内で定義 さ
れてい る 操作の名前を使用す る こ と をお勧め し ます。 semihost.h は RealView
ARMulator Extension Kit の一部 と し て イ ン ス ト ール さ れてい ます。 こ れ ら の操
作の名前は EQU デ ィ レ ク テ ィ ブ を使用 し て定義で き ます。 以下に例を示 し ま
す。
SYS_OPEN
SYS_CLOSE
EQU 0x01
EQU 0x02
セ ミ ホス テ ィ ン グオペ レ ーシ ョ ンの値の変更
セ ミ ホ ス テ ィ ン グオペレーシ ョ ン の値を変更 し ない こ と を強 く お勧め し ます。
変更す る 場合は、 以下の点に従 う 必要があ り ます。
•
新 し い値を使用す る 場合は、 ラ イ ブ ラ リ コ ー ド を含む、 シ ス テ ム内のす
べての コ ー ド を変更す る 必要があ り ます。
•
新 し い値を使用す る よ う にデバ ッ ガ を再設定す る 必要があ り ます。
ARM DUI 0203HJ
Copyright © 2007 ARM Limited. All rights reserved.
A-5
セ ミ ホステ ィ ング
A.2
セ ミ ホス テ ィ ングの実装
通常、 セ ミ ホ ス テ ィ ン グに よ り 提供 さ れ る 機能は、 いずれのデバ ッ グエー
ジ ェ ン ト で も 同 じ です。 し か し 、 セ ミ ホ ス テ ィ ン グの実装はホ ス ト に よ っ て
異な り ます。
こ のセ ク シ ョ ン では、 さ ま ざ ま なデバ ッ グエージ ェ ン ト でのセ ミ ホ ス テ ィ ン
グの実装について説明 し ます。
A.2.1
RealView ARMulator ISS
セ ミ ホ ス テ ィ ン グ要求が検出 さ れ る と 、 RVISS はその SVC を直接 ト ラ ッ プ
し 、 ベ ク タ テーブル内の SVC エ ン ト リ の命令は実行 さ れ ません。
RVISS でセ ミ ホ ス テ ィ ン グのサポー ト を無効にす る には、 default.ami フ ァ イ
ル内の Default_Semihost を No_Semihost に変更 し ます。
詳細については、 『RealView ARMulator ISS ユーザガ イ ド 』 を参照 し て下 さ い。
A.2.2
RealView ICE
RealView ICE DLL を使用す る 場合、 セ ミ ホ ス テ ィ ン グは、 実際の SVC 例外ハ
ン ド ラ 、 ま たはブ レー ク ポ イ ン ト を使用 し たハン ド ラ のエ ミ ュ レー ト に よ っ
て処理 さ れ ます。 RealView ICE を使用 し たセ ミ ホ ス テ ィ ン グの詳細について
は、 『RealView ICE and RealView Trace User Guide』 を参照 し て下 さ い。
A.2.3
Instruction Set System Model
セ ミ ホ ス テ ィ ン グ要求が検出 さ れ る と 、 ISSM はその要求を直接 ト ラ ッ プ し 、
ベ ク タ テーブル内の SVC エ ン ト リ の命令は実行 さ れません。 ISSM を使用 し た
セ ミ ホ ス テ ィ ン グの詳細については、 デバ ッ ガのマニ ュ アルを参照 し て下 さ
い。
ISSM でセ ミ ホ ス テ ィ ン グのサポー ト を無効にす る には、 デバ ッ ガ内の タ ー
ゲ ッ ト を設定す る か、 次の よ う に設定 さ れてい る default.smc フ ァ イ ル内の適
切なエ ン ト リ を変更 し ます。
...Name="semihosting-enable" Type="Bool">1</param>
A-6
Copyright © 2007 ARM Limited. All rights reserved.
ARM DUI 0203HJ
セ ミ ホス テ ィ ング
A.2.4
RealMonitor
RealMonitor でセ ミ ホ ス テ ィ ン グのサポー ト を有効にす る には、 SVC ハン ド ラ
を実装 し 、 シ ス テ ム に統合す る 必要があ り ます。
タ ーゲ ッ ト でセ ミ ホ ス テ ッ ド SVC 命令が実行 さ れ る と 、 RealMonitor の SVC ハ
ン ド ラ では、 ホ ス ト と の間で必要な通信を行い ます。
詳細については、 RealMonitor に付属のマニ ュ アルを参照 し て下 さ い。
ARM DUI 0203HJ
Copyright © 2007 ARM Limited. All rights reserved.
A-7
セ ミ ホステ ィ ング
A.3
セ ミ ホス テ ィ ングオペ レーシ ョ ン
こ のセ ク シ ョ ン では、 ホ ス ト コ ン ピ ュ ー タ と ARM タ ーゲ ッ ト 間でデバ ッ グ
I/O 機能を有効にす る セ ミ ホ ス テ ィ ン グオペレーシ ョ ンについて説明 し ます。
A.3.1
angel_SWIreason_EnterSVC (0x17)
プ ロ セ ッ サ を スーパーバ イ ザモー ド に設定 し 、 新 し い CPSR 内の 2 つの割 り 込
みマ ス ク ビ ッ ト を設定す る こ と で、 すべての割 り 込みを無効に し ます。
RealView ICE ま たは RealMonitor では、 ユーザ ス タ ッ ク ポ イ ン タ r13_USR が
スーパーバ イ ザ ス タ ッ ク ポ イ ン タ r13_SVC に コ ピー さ れ、 現在の CPSR 内の I
ビ ッ ト と F ビ ッ ト が設定 さ れ る こ と に よ り 、 通常割 り 込み と 高速割 り 込みが
無効にな り ます。
注
RVISS を使用 し てデバ ッ グす る 場合、 以下の よ う にな り ます。
•
r0 がゼ ロ に設定 さ れ、 ユーザモー ド に戻 る ために使用で き る 関数がない
•
こ と を示 し ます。
ユーザモー ド の ス タ ッ ク ポ イ ン タ は スーパーバ イ ザモー ド の ス タ ッ ク ポ
イ ン タ に コ ピー さ れません 。
エン ト リ
レ ジ ス タ r1 は使用 さ れ ません。 CPSR に よ っ てユーザモー ド ま たは スーパーバ
イ ザモー ド を指定で き ます。
戻り値
終了時には、 r0 はユーザモー ド に戻 る ために呼び出 さ れ る 関数のア ド レ ス を
保持 し ます。 こ の関数のプ ロ ト タ イ プは次の と お り です。
void ReturnToUSR(void)
EnterSVC がユーザモー ド で呼び出 さ れ る 場合、 こ のルーチンは呼び出 し 元を
ユーザモー ド に戻 し 、 割 り 込みフ ラ グ を復元 し ます。 それ以外の場合、 こ の
ルーチン の動作は定義 さ れてい ません。
ユーザモー ド にな る と 、 ユーザ ス タ ッ ク ポ イ ン タ が コ ピー さ れて、 スーパー
バ イ ザ ス タ ッ ク が失われます。 ユーザモー ド のルーチンに戻 る こ と に よ っ て、
r13_SVC には スーパーバ イ ザモー ド の ス タ ッ ク 値が復元 さ れ ますが、 こ の ス
タ ッ ク を アプ リ ケーシ ョ ン で使用す る こ と はで き ません。
A-8
Copyright © 2007 ARM Limited. All rights reserved.
ARM DUI 0203HJ
セ ミ ホス テ ィ ング
こ の SVC が実行 さ れた後の現在の リ ン ク レ ジ ス タ は r14_USR ではな く 、
r14_SVC です。 呼び出 し 後に r14_USR の値が必要な場合は、 BL 関数呼び出 し と 同
様に、 その値を呼び出す前に ス タ ッ ク にプ ッ シ ュ し 、 後でポ ッ プす る 必要が
あ り ます。
A.3.2
angel_SWIreason_ReportException (0x18)
こ の SVC を アプ リ ケーシ ョ ン で呼び出す こ と に よ っ て、 例外をデバ ッ ガに直
接通知で き ます。 一般的には、 実行が完了 し た こ と を通知す る ために
ADP_Stopped_ApplicationExit が使用 さ れます。
エン ト リ
エ ン ト リ 時には、 表 A-1 お よ び表 A-2 (ページ A-10) に示すいずれかの値に
r1 が設定 さ れ ます。 こ れ ら の値は angel_reasons.h 内で定義 さ れてい ます。
ハー ド ウ ェ ア例外が生成 さ れ る のは、 その例外 タ イ プ を取得す る ためにデ
バ ッ ガ変数 vector_catch が設定 さ れてお り 、 デバ ッ グエージ ェ ン ト がその例外
タ イ プ を通知で き る 場合です。
表 A-1 ハー ド ウ ェ アベ ク タ 要因 コ ー ド
名前
ARM DUI 0203HJ
16 進値
ADP_Stopped_BranchThroughZero
0x20000
ADP_Stopped_UndefinedInstr
0x20001
ADP_Stopped_SoftwareInterrupt
0x20002
ADP_Stopped_PrefetchAbort
0x20003
ADP_Stopped_DataAbort
0x20004
ADP_Stopped_AddressException
0x20005
ADP_Stopped_IRQ
0x20006
ADP_Stopped_FIQ
0x20007
Copyright © 2007 ARM Limited. All rights reserved.
A-9
セ ミ ホステ ィ ング
例外ハン ド ラ では、 ハン ド ラ チ ェ イ ンの最後にデフ ォ ル ト 動作 と し て こ れ ら
の SVC を使用 し 、 例外が処理 さ れなか っ た こ と を通知で き ます。
表 A-2 ソ フ ト ウ ェ ア要因コ ー ド
16 進値
名前
ADP_Stopped_BreakPoint
0x20020
ADP_Stopped_WatchPoint
0x20021
ADP_Stopped_StepComplete
0x20022
ADP_Stopped_RunTimeErrorUnknown
*0x20023
ADP_Stopped_InternalError
*0x20024
ADP_Stopped_UserInterruption
0x20025
ADP_Stopped_ApplicationExit
0x20026
ADP_Stopped_StackOverflow
*0x20027
ADP_Stopped_DivisionByZero
*0x20028
ADP_Stopped_OSSpecific
*0x20029
表 A-2 の値の横にあ る * は、 その値が ARM デバ ッ ガでサポー ト さ れていない
こ と を示 し てい ます。 こ れ ら の値に対 し て、 デバ ッ ガは Unhandled ADP_Stopped
exception を通知 し ます。
戻り値
こ れ ら の呼び出 し か ら 返 さ れ る 値はあ り ません。 し か し 、 デバ ッ ガは
RDI_Execute 要求ま たは こ れ と 同等の要求を実行す る こ と に よ っ て、 アプ リ
ケーシ ョ ンの継続を要求す る こ と がで き ます。 こ の場合は、 SVC へのエ ン ト
リ 時 と 同 じ 状態の レ ジ ス タ を使用す る か、 その後のデバ ッ ガに よ っ て修正 さ
れた レ ジ ス タ を使用 し て、 実行が継続 さ れ ます。
A-10
Copyright © 2007 ARM Limited. All rights reserved.
ARM DUI 0203HJ
セ ミ ホス テ ィ ング
A.3.3
SYS_CLOSE (0x02)
ホ ス ト シ ス テ ム上で フ ァ イ ルを閉 じ ます。 ハン ド ルは、 SYS_OPEN で開かれた
フ ァ イ ルを参照 し てい る 必要があ り ます。
エン ト リ
エ ン ト リ 時には、 r1 は 1 ワー ド 引数ブ ロ ッ ク を指すポ イ ン タ を保持 し ます。
ワー ド 1
開かれた フ ァ イ ルのハン ド ラ を保持 し ます。
戻り値
終了時には、 r0 は以下の情報を保持 し ます。
A.3.4
•
呼び出 し に成功 し た場合は 0
•
呼び出 し に失敗 し た場合は -1
SYS_CLOCK (0x10)
実行開始か ら 経過 し た時間 (単位 : 1/100 秒) を返 し ます。
通信にかか る オーバーヘ ッ ド や他のエージ ェ ン ト 固有の要因に よ り 、 こ の
SVC に よ っ て返 さ れ る 値をベンチマー ク の目的で使用す る 場合には、 何 ら か
の制約が課せ ら れ る 場合があ り ます。 例えば、 RealView ICE を使用す る 場合、
その要求はホ ス ト に戻 さ れてか ら 実行 さ れ ます。 こ のため、 送信やプ ロ セ ス
ス ケ ジ ュ ー リ ン グに予測不能な遅延が生 じ る こ と があ り ます。
こ の関数を使用 し て時間間隔を計算す る には、 時間を計測す る コ ー ド シーケ
ン ス があ る 場合 と ない場合の時間間隔の差を計算 し ます。
シ ス テ ムに よ っ ては、 よ り 精密に時間を計算で き る 場合 も あ り ます。
SYS_ELAPSED (0x30) (ページ A-12) お よ び SYS_TICKFREQ (0x31)
(ページ A-22) を参照 し て下 さ い。
エン ト リ
レ ジ ス タ r1 はゼ ロ を保持 し てい る 必要があ り ます。 その他のパ ラ メ ー タ は使
用で き ません。
ARM DUI 0203HJ
Copyright © 2007 ARM Limited. All rights reserved.
A-11
セ ミ ホステ ィ ング
戻り値
終了時には、 r0 は以下の情報を保持 し ます。
A.3.5
•
呼び出 し に成功 し た場合は、 任意の開始時か ら の時間 (単位 : 1/100 秒)
•
通信エ ラ ーな ど に よ り 呼び出 し に失敗 し た場合は -1
SYS_ELAPSED (0x30)
実行開始か ら の タ ーゲ ッ ト の Tick 単位の経過時間を返 し ます。 SYS_TICKFREQ を
使用 し て、 Tick の周波数を決定 し ます。
エン ト リ
エ ン ト リ 時には、 r1 は Tick 単位の経過時間を返すために使用 さ れ る 2 ワー ド
デー タ ブ ロ ッ ク を指 し ます。
ワー ド 1
ダブル ワー ド 値の最下位 ワ ー ド です。
ワー ド 2
最上位 ワー ド です。
戻り値
終了時には、 以下の よ う にな り ます。
•
r1 が Tick 単位の経過時間を保持す る ダブル ワ ー ド を指 し てい る 場合、r0
は -1 を保持 し ます。 RealView ICE は こ の SVC をサポー ト し てお ら ず、r0
に必ず -1 を返 し ます。
•
r1 は Tick 単位の経過時間を保持す る ダブル ワ ー ド (下位 ワ ー ド か ら )
を指 し ます。
A-12
Copyright © 2007 ARM Limited. All rights reserved.
ARM DUI 0203HJ
セ ミ ホス テ ィ ング
A.3.6
SYS_ERRNO (0x13)
ホ ス ト のセ ミ ホ ス テ ィ ン グ SVC の実装に関連す る C ラ イ ブ ラ リ の errno 変数
の値を返 し ます。 errno 変数は、 以下に示す C ラ イ ブ ラ リ のセ ミ ホ ス テ ッ ド 関
数の値に よ っ て設定 さ れ ます。
•
SYS_REMOVE
•
SYS_OPEN
•
SYS_CLOSE
•
SYS_READ
•
SYS_WRITE
•
SYS_SEEK
errno が設定 さ れ る か ど う か と 、 設定 さ れ る 値については、 ISO C 標準で動作
が定義 さ れてい る 場合を除いて完全にホ ス ト に依存 し ます。
エン ト リ
パ ラ メ ー タ はあ り ません。 レ ジ ス タ r1 はゼ ロ であ る 必要があ り ます。
戻り値
終了時には、 r0 は C ラ イ ブ ラ リ の errno 変数の値を保持 し ます。
A.3.7
SYS_FLEN (0x0C)
指定 さ れた フ ァ イ ルの長 さ を返 し ます。
エン ト リ
エ ン ト リ 時には、 r1 は 1 ワー ド 引数ブ ロ ッ ク を指すポ イ ン タ を保持 し ます。
ワー ド 1
既に開かれてい る 、 シー ク 可能な フ ァ イ ルオブジ ェ ク ト のハン
ド ルです。
戻り値
終了時には、 r0 は以下の情報を保持 し ます。
•
•
ARM DUI 0203HJ
呼び出 し に成功 し た場合は、 フ ァ イ ルオブジ ェ ク ト の現在の長 さ
エ ラ ー発生時は -1
Copyright © 2007 ARM Limited. All rights reserved.
A-13
セ ミ ホステ ィ ング
A.3.8
SYS_GET_CMDLINE (0x15)
実行可能フ ァ イ ルの呼び出 し に使用 さ れた コ マ ン ド ラ イ ン (argc お よ び argv)
を返 し ます。
エン ト リ
エ ン ト リ 時には、 r1 は コ マ ン ド 文字列 と その長 さ を返すために使用 さ れ る 2
ワー ド デー タ ブ ロ ッ ク を指 し ます。
ワー ド 1
ワー ド 2 で指定 さ れ る サ イ ズ以上のバ ッ フ ァ を指すポ イ ン タ で
す。
ワー ド 2
バ ッ フ ァ のバ イ ト 単位の長 さ です。
戻り値
終了時には、 以下の よ う にな り ます。
•
レ ジ ス タ r1 は 2 ワ ー ド デー タ ブ ロ ッ ク を指 し ます。
ワー ド 1 コ マ ン ド ラ イ ンの NULL で終わ る 文字列を指すポ イ ン タ です。
ワー ド 2 文字列の長 さ です。
デバ ッ グエージ ェ ン ト に よ っ ては、 転送可能な文字列の最大長が制限 さ
れ る 場合があ り ます。 ただ し 、 エージ ェ ン ト は 80 バ イ ト 以上の コ マ ン ド
ラ イ ン を転送で き る 必要があ り ます。
•
A.3.9
レ ジ ス タ r0 はエ ラ ー コ ー ド を保持 し ます。
—
呼び出 し に成功 し た場合は 0
—
通信エ ラ ーな ど に よ り 呼び出 し に失敗 し た場合は -1
SYS_HEAPINFO (0x16)
シ ス テ ム の ス タ ッ ク と ヒ ープのパ ラ メ ー タ を返 し ます。 通常は、初期化時に C
ラ イ ブ ラ リ に使用 さ れた値が返 さ れ ます。 RVISS の場合は、 peripherals.ami 内
で指定 さ れてい る 値が返 さ れます。 RealView ICE の場合は、 イ メ ージの位置
と メ モ リ 最上部の値が返 さ れ ます。
こ れ ら の値は C ラ イ ブ ラ リ に よ っ てオーバー ラ イ ド で き ます。 C ラ イ ブ ラ リ
での メ モ リ 管理の詳細については、 『 ラ イ ブ ラ リ ガ イ ド 』 の ス ト レージ管理の
カ ス タ マ イ ズ (ページ 2-94) を参照 し て下 さ い。
A-14
Copyright © 2007 ARM Limited. All rights reserved.
ARM DUI 0203HJ
セ ミ ホス テ ィ ング
ホ ス ト デバ ッ ガは、 top_of_memory デバ ッ ガ変数を使用 し て実際の戻 り 値を決
定 し ます。
エン ト リ
エ ン ト リ 時には、 r1 は 4 ワー ド デー タ ブ ロ ッ ク を指すポ イ ン タ のア ド レ ス を
保持 し ます。 デー タ ブ ロ ッ ク の内容は、 こ の関数に よ っ て充填 さ れ ます。 デー
タ ブ ロ ッ ク の構造 と 戻 り 値については、 例 A-1 を参照 し て下 さ い。
例 A-1
struct block {
int heap_base;
int heap_limit;
int stack_base;
int stack_limit;
};
struct block *mem_block, info;
mem_block = &info;
AngelSWI(SYS_HEAPINFO, (unsigned) &mem_block);
注
デー タ ブ ロ ッ ク の ワー ド 1 にゼ ロ が保持 さ れてい る 場合、 C ラ イ ブ ラ リ はそ
のゼ ロ を Image$$ZI$$Limit に置 き 換え ます。 こ の値は、 メ モ リ マ ッ プ内のデー
タ 領域の先頭に対応 し てい ます。
戻り値
終了時には、 r1 は構造体を指すポ イ ン タ のア ド レ ス を保持 し ます。
構造体のいずれかの値が 0 であ る 場合は、 シ ス テ ムが実際の値を計算で き な
か っ た こ と を示 し ます。
ARM DUI 0203HJ
Copyright © 2007 ARM Limited. All rights reserved.
A-15
セ ミ ホステ ィ ング
A.3.10
SYS_ISERROR (0x08)
別のセ ミ ホ ス テ ィ ン グ呼び出 し か ら の復帰 コ ー ド がエ ラ ース テー タ ス か ど う
か を判断 し ます。 こ の呼び出 し には、 チ ェ ッ ク す る エ ラ ー コ ー ド を保持す る
パ ラ メ ー タ ブ ロ ッ ク が渡 さ れます。
エン ト リ
エ ン ト リ 時には、 r1 は 1 ワー ド デー タ ブ ロ ッ ク を指すポ イ ン タ を保持 し ます。
ワー ド 1
チ ェ ッ ク す る 必要があ る ス テー タ ス ワー ド です。
戻り値
終了時には、 r0 は以下の情報を保持 し ます。
A.3.11
•
ス テー タ ス ワ ー ド がエ ラ ーを示 し ていない場合は 0
•
ス テー タ ス ワ ー ド がエ ラ ーを示 し てい る 場合はゼ ロ 以外の値
SYS_ISTTY (0x09)
フ ァ イ ルが イ ン タ ラ ク テ ィ ブデバ イ ス に接続 さ れてい る か ど う か をチ ェ ッ ク
し ます。
エン ト リ
エ ン ト リ 時には、 r1 は 1 ワー ド 引数ブ ロ ッ ク を指すポ イ ン タ を保持 し ます。
ワー ド 1
前に開かれた フ ァ イ ルオブジ ェ ク ト のハン ド ルです。
戻り値
終了時には、 r0 は以下の情報を保持 し ます。
A-16
•
ハン ド ルに よ っ て イ ン タ ラ ク テ ィ ブデバ イ ス が識別 さ れた場合は 1
•
ハン ド ルに よ っ て フ ァ イ ルが識別 さ れた場合は 0
•
エ ラ ーが発生 し た場合は 1 と 0 以外の値
Copyright © 2007 ARM Limited. All rights reserved.
ARM DUI 0203HJ
セ ミ ホス テ ィ ング
A.3.12
SYS_OPEN (0x01)
ホ ス ト シ ス テ ム上で フ ァ イ ルを開 き ます。 フ ァ イ ルパ ス は、 ホ ス ト プ ロ セ ス
の現在のデ ィ レ ク ト リ への相対パ ス、 ま たはホ ス ト オペレーテ ィ ン グ シ ス テ
ムのパ ス規則を使用 し た絶対パ ス と し て指定 さ れます。
ARM タ ーゲ ッ ト は、 特殊なパ ス名 :tt を、 コ ン ソ ール入力ス ト リ ーム (開 く
- 読み出す) ま たは コ ン ソ ール出力ス ト リ ーム (開 く - 書 き 込む) と し て解釈
し ます。 こ れ ら の ス ト リ ーム を開 く 動作は、 C 言語の stdio ス ト リ ーム を参照
す る アプ リ ケーシ ョ ンの標準的な起動 コ ー ド の中で実行 さ れ ます。
エン ト リ
エ ン ト リ 時には、 r1 は 3 ワー ド 引数ブ ロ ッ ク を指すポ イ ン タ を保持 し ます。
ワー ド 1
フ ァ イ ル名ま たはデバ イ ス名を保持す る NULL で終わ る 文字列
を指すポ イ ン タ です。
ワー ド 2
「フ ァ イ ルを開 く 」 モー ド を指定す る 整数です。 表 A-3 は、 上記
の整数の有効な値 と 、 対応す る ISO C の fopen() モー ド を示 し て
い ます。
ワー ド 3
ワー ド 1 が指す文字列の長 さ を示す整数です。
文字列は NULL で終わ る 必要があ り ますが、 こ の長 さ には終端
の NULL 文字が含まれ ません。
表 A-3 モー ド の値
モー ド
0
1
2
3
4
5
6
7
8
9
10
11
ISO C fopen モー ド a
r
rb
r+
r+b
w
wb
w+
w+b
a
ab
a+
a+b
a. ANSI 以外のオプシ ョ ンはサポー ト さ れてい ません。
戻り値
終了時には、 r0 は以下の情報を保持 し ます。
•
•
ARM DUI 0203HJ
呼び出 し に成功 し た場合はゼ ロ 以外のハン ド ル
呼び出 し に失敗 し た場合は -1
Copyright © 2007 ARM Limited. All rights reserved.
A-17
セ ミ ホステ ィ ング
A.3.13
SYS_READ (0x06)
フ ァ イ ルの内容をバ ッ フ ァ に読み出 し ます。 フ ァ イ ル位置は以下のいずれか
の方法で指定 さ れます。
•
SYS_SEEK に よ っ て明示的に指定 さ れ る 。
•
前の SYS_READ ま たは SYS_WRITE 要求の次の 1 バ イ ト と し て暗黙に指定 さ れ
る。
フ ァ イ ルの位置は、 フ ァ イ ルが開かれた時点で フ ァ イ ルの先頭 と な り 、 フ ァ
イ ルを閉 じ る と 失われ ます。 フ ァ イ ル操作は、 で き る 限 り 1 回の動作で実行 し
て下 さ い。 例えば、 16KB を 4KB のチ ャ ン ク に 4 分割 し て書 き 込む こ と は、 や
むを得ない場合以外は行わないで下 さ い。
エン ト リ
エ ン ト リ 時には、 r1 は 4 ワー ド デー タ ブ ロ ッ ク を指すポ イ ン タ を保持 し ます。
ワー ド 1
SYS_OPEN で前に開かれた フ ァ イ ルのハン ド ルを保持 し ます。
ワー ド 2
ワー ド 3
バ ッ フ ァ を指 し ます。
フ ァ イ ルか ら バ ッ フ ァ に読み出 さ れ る バ イ ト 数を保持 し ます。
戻り値
終了時には、 以下の よ う にな り ます。
•
呼び出 し に成功 し た場合、 r0 はゼ ロ を保持 し ます。
•
r0 が ワ ー ド 3 と 同 じ 値を保持 し てい る 場合、 その呼び出 し は失敗 し てお
り 、 EOF と 見な さ れ ます。
•
r0 が ワ ー ド 3 よ り 小 さ い値を保持 し てい る 場合は、 呼び出 し が部分的に
成功 し た こ と を示 し ます。 エ ラ ー と は見な さ れ ませんが、 バ ッ フ ァ は充
填 さ れてい ません。
ハン ド ルが イ ン タ ラ ク テ ィ ブデバ イ ス のハン ド ルであ る 場合、 SYS_ISTTY は -1
を返 し ます。 SYS_READ か ら ゼ ロ 以外の値が返 さ れ る と 、 行読み出 し に よ り バ ッ
フ ァ が充填 さ れなか っ た こ と を示 し ます。
A-18
Copyright © 2007 ARM Limited. All rights reserved.
ARM DUI 0203HJ
セ ミ ホス テ ィ ング
A.3.14
SYS_READC (0x07)
コ ン ソ ールか ら 1 バ イ ト を読み出 し ます。
エン ト リ
レ ジ ス タ r1 はゼ ロ を保持 し てい る 必要があ り ます。 他のパ ラ メ ー タ ま たは値
は使用で き ません。
戻り値
終了時には、 r0 は コ ン ソ ールか ら 読み出 さ れたバ イ ト を保持 し ます。
A.3.15
SYS_REMOVE (0x0E)
注意
ホ ス ト フ ァ イ ルシ ス テ ム上で指定 さ れた フ ァ イ ルを削除 し ます。
エン ト リ
エ ン ト リ 時には、 r1 は 2 ワー ド 引数ブ ロ ッ ク を指すポ イ ン タ を保持 し ます。
ワー ド 1
削除す る フ ァ イ ルのパ ス名を示す、 NULL で終わ る 文字列を指 し
ます。
ワー ド 2
文字列の長 さ です。
戻り値
終了時には、 r0 は以下の情報を保持 し ます。
ARM DUI 0203HJ
•
削除に成功 し た場合は 0
•
削除に失敗 し た場合はゼ ロ 以外の、 ホ ス ト 固有のエ ラ ー コ ー ド
Copyright © 2007 ARM Limited. All rights reserved.
A-19
セ ミ ホステ ィ ング
A.3.16
SYS_RENAME (0x0F)
指定 さ れた フ ァ イ ルの名前を変更 し ます。
エン ト リ
エ ン ト リ 時には、 r1 は 4 ワー ド デー タ ブ ロ ッ ク を指すポ イ ン タ を保持 し ます。
ワー ド
ワー ド
ワー ド
ワー ド
1.
2.
3.
4.
旧フ ァ イ ル名を指すポ イ ン タ です。
旧フ ァ イ ル名の長 さ です。
新 し い フ ァ イ ル名を指すポ イ ン タ です。
新 し い フ ァ イ ル名の長 さ です。
いずれの文字列 も NULL で終わ り ます。
戻り値
終了時には、 r0 は以下の情報を保持 し ます。
A-20
•
名前の変更に成功 し た場合は 0
•
名前の変更に失敗 し た場合はゼ ロ 以外の、 ホ ス ト 固有のエ ラ ー コ ー ド
Copyright © 2007 ARM Limited. All rights reserved.
ARM DUI 0203HJ
セ ミ ホス テ ィ ング
A.3.17
SYS_SEEK (0x0A)
フ ァ イ ルの先頭を基準に指定 さ れたオ フ セ ッ ト を使用 し て、 フ ァ イ ル内の指
定 さ れた位置にシー ク し ます。 フ ァ イ ルはバ イ ト の配列 と 見な さ れ、 オ フ
セ ッ ト はバ イ ト 単位で渡 さ れ ます。
エン ト リ
エ ン ト リ 時には、 r1 は 2 ワー ド デー タ ブ ロ ッ ク を指すポ イ ン タ を保持 し ます。
ワー ド 1
ワー ド 2
シー ク 可能な フ ァ イ ルオブジ ェ ク ト のハン ド ルです。
検索す る 絶対バ イ ト 位置を示 し ます。
戻り値
終了時には、 r0 は以下の情報を保持 し ます。
•
要求に成功 し た場合は 0
•
要求に失敗 し た場合は負の値。 SYS_ERRNO を使用 し て、 エ ラ ーを表す、 ホ
ス ト の errno 変数の値を読み出す こ と がで き ます。
注
現在の フ ァ イ ルオブジ ェ ク ト の範囲外にシー ク し た場合の影響は定義 さ れて
い ません。
ARM DUI 0203HJ
Copyright © 2007 ARM Limited. All rights reserved.
A-21
セ ミ ホステ ィ ング
A.3.18
SYS_SYSTEM (0x12)
ホ ス ト の コ マ ン ド ラ イ ン イ ン タ ープ リ タ に コ マ ン ド を渡 し ます。 こ の SVC を
使用 し て、 dir、 ls、 pwd な ど のシ ス テ ム コ マ ン ド を実行で き ます。 端末 I/O は
ホ ス ト 上で実行 さ れ、 タ ーゲ ッ ト には表示 さ れ ません。
注意
ホ ス ト に渡 さ れ る コ マ ン ド はホ ス ト 上で実行 さ れます。 意図 し ない影響が生
じ る よ う な コ マ ン ド が渡 さ れない よ う に注意す る 必要があ り ます。
エン ト リ
エ ン ト リ 時には、 r1 は 2 ワー ド 引数ブ ロ ッ ク を指すポ イ ン タ を保持 し ます。
ワー ド 1
ワー ド 2
ホ ス ト の コ マ ン ド ラ イ ン イ ン タ ープ リ タ に渡 さ れ る 文字列を指
し ます。
文字列の長 さ です。
戻り値
終了時には、 r0 は復帰ス テー タ ス を保持 し ます。
A.3.19
SYS_TICKFREQ (0x31)
Tick の周波数を返 し ます。
エン ト リ
こ のルーチンのエ ン ト リ 時には、 レ ジ ス タ r1 は 0 を保持 し てい る 必要があ り
ます。
戻り値
終了時には、 r0 は以下のいずれか を保持 し ます。
A-22
•
1 秒間当た り の Tick 数
•
タ ーゲ ッ ト が 1 Tick の値を認識 し ていない場合は -1。 RealView ICE は こ
の SVC をサポー ト し てお ら ず、 r0 に必ず -1 を返 し ます。
Copyright © 2007 ARM Limited. All rights reserved.
ARM DUI 0203HJ
セ ミ ホス テ ィ ング
A.3.20
SYS_TIME (0x11)
1970 年 1 月 1 日 00:00 か ら の秒数を返 し ます。 RVISS、ISSM、お よ び RealView
ICE のすべての コ ン フ ィ グ レーシ ョ ン において、 こ の値は実際の時間を示 し
ます。
エン ト リ
パ ラ メ ー タ はあ り ません。
戻り値
終了時には、 r0 は秒数を保持 し ます。
A.3.21
SYS_TMPNAM (0x0D)
シ ス テ ム フ ァ イ ルの識別子に よ っ て識別 さ れ る フ ァ イ ルの一時的な名前を返
し ます。
エン ト リ
エ ン ト リ 時には、 r1 は 3 ワー ド 引数ブ ロ ッ ク を指すポ イ ン タ を保持 し ます。
ワー ド 1
バ ッ フ ァ を指すポ イ ン タ です。
ワー ド 2
こ の フ ァ イ ル名の タ ーゲ ッ ト 識別子です。 こ の値は、 0 ~ 255 の
範囲内の整数であ る 必要があ り ます。
ワー ド 3
バ ッ フ ァ の長 さ を保持 し ます。 こ の値は、 ホ ス ト シ ス テ ム上の
L_tmpnam の値以上であ る 必要があ り ます。
戻り値
終了時には、 r0 は以下の情報を保持 し ます。
•
呼び出 し に成功 し た場合は 0
•
エ ラ ー発生時は -1
r1 が指すバ ッ フ ァ は、 適切なデ ィ レ ク ト リ 名が前に付いた フ ァ イ ル名を保持
し ます。
同 じ タ ーゲ ッ ト 識別子を再度使用す る と 、 同 じ フ ァ イ ル名が返 さ れ ます。
ARM DUI 0203HJ
Copyright © 2007 ARM Limited. All rights reserved.
A-23
セ ミ ホステ ィ ング
注
返 さ れ る 文字列は NULL で終わ る 必要があ り ます。
A.3.22
SYS_WRITE (0x05)
バ ッ フ ァ の内容を、 指定 さ れた フ ァ イ ルの現在の フ ァ イ ル位置に書 き 込みま
す。 フ ァ イ ル位置は以下のいずれかの方法で指定 さ れ ます。
•
SYS_SEEK に よ っ て明示的に指定 さ れ る 。
•
前の SYS_READ ま たは SYS_WRITE 要求の次の 1 バ イ ト と し て暗黙に指定 さ れ
る。
フ ァ イ ルの位置は、 フ ァ イ ルが開かれた時点で フ ァ イ ルの先頭 と な り 、 フ ァ
イ ルが閉 じ ら れ る と 失われ ます。
フ ァ イ ル操作は、 で き る 限 り 1 回の動作で実行 し て下 さ い。 例えば、 16KB を
4KB のチ ャ ン ク に 4 分割 し て書 き 込む こ と は、 やむを得ない場合以外は行わ
ないで下 さ い。
エン ト リ
エ ン ト リ 時には、 r1 は 3 ワー ド デー タ ブ ロ ッ ク を指すポ イ ン タ を保持 し ます。
ワー ド 1
SYS_OPEN で前に開かれた フ ァ イ ルのハン ド ルを保持 し ます。
ワー ド 2
ワー ド 3
書 き 込ま れ る デー タ を保持す る メ モ リ を指 し ます。
バ ッ フ ァ か ら フ ァ イ ルに書 き 込まれ る バ イ ト 数を保持 し ます。
戻り値
終了時には、 r0 は以下の情報を保持 し ます。
A-24
•
呼び出 し に成功 し た場合は 0
•
エ ラ ーが発生 し た場合は、 書 き 込まれなか っ たバ イ ト 数
Copyright © 2007 ARM Limited. All rights reserved.
ARM DUI 0203HJ
セ ミ ホス テ ィ ング
A.3.23
SYS_WRITEC (0x03)
r1 が指す文字バ イ ト をデバ ッ グチ ャ ネルに書 き 込みます。 ARM デバ ッ ガの下
で実行 さ れ る 場合、 こ の文字はホ ス ト デバ ッ ガ コ ン ソ ールに表示 さ れます。
エン ト リ
エ ン ト リ 時には、 r1 は文字を指すポ イ ン タ を保持 し ます。
戻り値
な し 。 レ ジ ス タ r0 の内容は破壊 さ れます。
A.3.24
SYS_WRITE0 (0x04)
NULL で終わ る 文字列をデバ ッ グチ ャ ン ネルに書 き 込みます。 ARM デバ ッ ガ
の下で実行 さ れ る 場合、 こ れ ら の文字はホ ス ト デバ ッ ガ コ ン ソ ールに表示 さ
れます。
エン ト リ
エ ン ト リ 時には、 r1 は文字列の先頭のバ イ ト を指すポ イ ン タ を保持 し ます。
戻り値
な し 。 レ ジ ス タ r0 の内容は破壊 さ れます。
ARM DUI 0203HJ
Copyright © 2007 ARM Limited. All rights reserved.
A-25
セ ミ ホステ ィ ング
A.4
デバ ッ グエージ ェ ン ト イ ン タ ラ ク シ ョ ン SVC
セ ミ ホ ス テ ィ ン グオペレーシ ョ ン (ページ A-8) で説明す る C ラ イ ブ ラ リ のセ
ミ ホ ス テ ッ ド 関数に加え、 デバ ッ グエージ ェ ン ト と の イ ン タ ラ ク シ ョ ン を サ
ポー ト す る 以下の SVC があ り ます。
A-26
•
angel_SWIreason_EnterSVC (0x17) (ページ A-8)
•
angel_SWIreason_ReportException (0x18) (ページ A-9)
Copyright © 2007 ARM Limited. All rights reserved.
ARM DUI 0203HJ