source: anotherchoice/tags/jsp-1.4.4-full-UTF8/doc/c++.txt@ 26

Last change on this file since 26 was 26, checked in by ykominami, 12 years ago

initial

File size: 33.8 KB
Line 
1
2 = TOPPERS/JSPカーネル ユーザズマニュアル =
3 (C++バインディング)
4
5 (Release 1.4.1 対応,最終更新: 16-Sep-2004)
6
7------------------------------------------------------------------------
8 TOPPERS/JSP Kernel
9 Toyohashi Open Platform for Embedded Real-Time Systems/
10 Just Standard Profile Kernel
11
12 Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
13 Toyohashi Univ. of Technology, JAPAN
14 Copyright (C) 2003-2004 by Takagi Nobuhisa
15
16 上記著作権者
17は,以下の (1)〜(4) の条件か,Free Software Foundation
18 によってå…
19¬è¡¨ã•ã‚Œã¦ã„ã‚‹ GNU General Public License の Version 2 に記
20 述されている条件を満たす場合に限り,本ソフトウェア(本ソフトウェア
21 を改変したものを含む.以下同じ)を使用・複製・改変・再é…
22å¸ƒï¼ˆä»¥ä¸‹ï¼Œ
23 利用と呼ぶ)することを無償で許諾する.
24 (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
25 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
26 スコード中に含まれていること.
27 (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
28 用できる形で再é…
29å¸ƒã™ã‚‹å ´åˆã«ã¯ï¼Œå†é…
30å¸ƒã«ä¼´ã†ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆï¼ˆåˆ©ç”¨
31 者
32マニュアルなど)に,上記の著作権表示,この利用条件および下記
33 の無保証規定を掲載すること.
34 (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
35 用できない形で再é…
36å¸ƒã™ã‚‹å ´åˆã«ã¯ï¼Œæ¬¡ã®ã„ずれかの条件を満たすこ
37 と.
38 (a) 再é…
39å¸ƒã«ä¼´ã†ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆï¼ˆåˆ©ç”¨è€…
40マニュアルなど)に,上記の著
41 作権表示,この利用条件および下記の無保証規定を掲載すること.
42 (b) 再é…
43å¸ƒã®å½¢æ…
44‹ã‚’,別に定める方法によって,TOPPERSプロジェクトに
45 報告すること.
46 (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
47 害からも,上記著作権者
48およびTOPPERSプロジェクトをå…
49è²¬ã™ã‚‹ã“と.
50
51 本ソフトウェアは,無保証で提供されているものである.上記著作権者
52お
53 よびTOPPERSプロジェクトは,本ソフトウェアに関して,その適用可能性も
54 含めて,いかなる保証も行わない.また,本ソフトウェアの利用により直
55 接的または間接的に生じたいかなる損害に関しても,その責任を負わない.
56------------------------------------------------------------------------
57
581.C++バインディングの概要
59
601.1 目的
61
62TOPPERS/JSPカーネルは、本来C言語APIを提供するものであり、そのままでは
63C++を用いたアプリケーション開発を行う上で支障がある。
64C++バインディングは、TOPPERS/JSPカーネルが提供するサービスコールをC++
65から呼出すことを可能にし、かつTOPPERS/JSPカーネル上で標準C++の機能を
66利用できるようにするものである。
67
681.2 開発環境と実行環境
69
70C++バインディングでは、GCC等のGNU開発環境を使用する。なお、Windows上
71のシミュレーション環境(Visual C++)でC++を使用する際は、C++バインデ
72ィングの機能を必
73要としない。
74
75現在、C++バインディングがサポートする実行環境は、MS7727CP01(SH3)およ
76びAKI-H8/3069Fである。他の実行環境で使用するには、ターゲット依存部の
77Makefile.configおよびリンカスクリプトの修正が必
78要となる。
79また、Linux上のシミュレーション環境では使用することができない。
80
811.3 C++バインディングの機能の概要
82
83標準C++の機能のうち、実行環境に依存する部分について、TOPPERS/JSPカー
84ネルに対応させている。å…
85·ä½“的には、非ローカルオブジェクトの初期化処理、
86終了処理、グローバルなnew演算子とdelete演算子、例外処理、およびフリー
87スタンディング環境における標準ライブラリ関数である。
88
89GCC自体が未サポートの機能(export、ユニバーサル文字名等)を補完するも
90のではない。
91
921.4 C++バインディングの使用方法
93
94TOPPERS/JSPカーネルでC++バインディングを使用するには、コンフィギュレ
95ーションファイル(.cfg)から、jsp/systask/cxxrt.cfgをインクルードする
96だけでよい。(静的APIのINCLUDEではなく、プロプロセッサ指令の#include
97を使用すること)
98
99TOPPERS/JSPカーネルのconfigureを使用する場合、C++を使うには"-l c++"
100オプションを付加する必
101要がある。
102
103
1042.C++バインディングの機能
105
1062.1 非ローカルオブジェクトの初期化処理
107
108関数の外部で宣言されたオブジェクト(特定の名前空間やクラスの静的デー
109タメンバを含む)のコンストラクタを、起動時に呼出す機能を提供する。
110
111非ローカルオブジェクトのコンストラクタは、kernel_start関数の呼出しよ
112り前に実行され、syslogの機能を使用することはできない。
113また、コンストラクタの内
114部では、vsns_iniを除くサービスコールを呼出す
115ことはできない。
116
117関数の内
118部で宣言されたオブジェクトは、起動時ではなく、宣言された箇所
119に最初に実行パスが差し掛かったときにコンストラクタが呼出されるため、
120起動時の初期化処理には含まれない。
121そうしたコンストラクタの呼出しはマルチタスクに対応しないため、ユーザ
122は必
123要に応じて排他制御を独自に行う必
124要がある。
125
1262.2 終了処理
127
128静的なオブジェクト(関数内
129で宣言されたものを含む)のデストラクタは、
130std::exit関数の中から呼出される。明示的にstd::exit関数を呼出さない限
131り、å…
132¨ã‚¿ã‚¹ã‚¯ãŒçµ‚了したとしてもデストラクタが呼出されることはない。
133なお、kernel_exit関数を呼出した場合も、std::exit関数を呼出した場合と
134同様に、静的なオブジェクトのデストラクタは呼出される。
135
136終了時の動作順序は、静的APIのVATT_TERで登録した終了処理ルーチンが呼出
137された後、std::atexit関数で登録した終了時関数が呼出され、最後にデスト
138ラクタが呼出される。
139デフォルトの標準ストリーム(stdin, stdout, stderr)をサポートする場合、
140それらのクローズ処理はデストラクタの呼出し後に行わなければならない。
141(ユーザの手でカスタマイズする必
142要がある)
143
1442.3 グローバルなnew演算子とdelete演算子
145
146TOPPERS/JSPカーネルのマルチタスク環境および非マルチタスク環境(初期化
147または終了処理時)で動作するnewおよびdelete演算子を提供する。
148GCCはグローバルなnewおよびdelete演算子をstd::mallocおよびstd:free関数
149を用いて実装
150しているため、NEWLIBのmallocおよびfree関数に排他制御を追
151加することで実現している。
152
153C++バインディングは、C++のフリースタンディング環境を対象としているが、
154上記の理由により、本来フリースタンディング環境ではサポートされない、
155std::mallocおよびstd::free関数も結果的にサポートしている。
156おそらくはstd::callocおよびstd::realloc関数も動作すると思われるが、検
157証は行っていない。
158
159標準C++のグローバルなnewおよびdelete演算子には、例外をスローすること
160がない、const std::nothrow_t&を引数にとるé…
161ç½®æ§‹æ–‡åž‹ã®ã‚‚のもあるが、通
162常のもの同様に使用することができる。
163
1642.4 例外処理
165
166C++の言語機能である例外処理機能(try、catchおよびthrow)を提供する。
167例外処理はコンパイラの実装
168に密接に絡むため、コンパイラ自体にパッチが
169必
170要になる。
171
172例外処理は、tryおよびcatchの位置と、throwからcatchまでの間に存在する
173ローカルオブジェクトのデストラクタを管理する必
174要がある。したがって、
175コンパイラにとって未知の方法でコンテキストが切り替わった場合には、例
176外処理用の管理情
177報も切り替える必
178要が生じる。
179C++バインディングは、マルチタスク環境および非マルチタスク環境(初期化
180または終了処理時)で、コンテキストに応じて管理情
181報を切り替える機能や
182同期機能を実現している。
183
184GCCでは、コンパイル時に-fno-exceptionsオプションを指定することで、例
185外処理を無効にすることができるが、これはオプションを指定した翻訳単位
186に対してのみ通用することであり、ライブラリ等は、通常通り、例外処理が
187使える場合と同様に振舞うことになる。したがって、new、dynamic_cast、
188あるいはtypeid演算子が失敗した場合等には、予期せぬ誤動作につながる危
189険性があるため、必
190ずしも推奨しない。
191
1922.5 標準ライブラリ関数
193
194フリースタンディング環境のC++では、終了処理に関する標準ライブラリ関数
195として、std::abort、std::atexit、およびstd::exit関数がサポートされる。
196C++バインディングでも、これら3種類の関数を提供している。
197
198(1) std::abort
199
200std::abort関数は、静的APIのVATT_TERで登録された終了処理ルーチンや、
201std::atexit関数で登録された終了時関数、オブジェクトのデストラクタを呼
202出すことなく、システムを異常終了する。
203システムの終了処理は、マルチタスク動作中はターゲット依存部で定義され
204るkernel_abort関数に従い、非マルチタスク動作中(初期化または終了処理時)
205はNEWLIBの_exit関数に従う。
206
207C++バインディングでは、関数へのポインタvoid (*_atabort)(void)が0以外
208に定義されている場合、実際の終了処理より前にそれを呼出すようになって
209いる。
210ホスト環境のstd::abortは、実際の終了処理の前にstd::raise(SIGABRT);を
211呼出すが、_atabortを適切に設定することで同様の機能をエミュレートする
212ことができる。
213
214(2) std::atexit
215
216std::atexit関数は、std::exitまたはkernel_exit関数から呼出される終了時
217関数を登録する。std::atexit関数で登録した関数は、std::abort関数で終了
218した場合や、vsns_iniがTRUEを返す期間にstd::exit関数を用いた場合には、
219呼出されることがない。
220
221静的なオブジェクトのデストラクタは、実際にはstd::atexit関数を用いるこ
222とで実現している。ただし、デストラクタの呼出しは、std::atexit関数で登
223録されたその他のいかなる終了時関数よりも後に呼出される。
224
225std::atexit関数で登録できる終了時関数は、(デストラクタの登録を除いて)
22632個までである。
227
228(3) std::exit
229
230std::exit関数は、C++の標準的な終了処理を行う。詳細な動作は、2.2 終了
231処理を参ç…
232§ã®ã“と。
233
234std::exit関数を用いて終了した場合、ローカルオブジェクトのデストラクタ
235が呼出されることはない。
236
237
2383.C++実行環境としてのTOPPERS/JSPカーネル
239
2403.1 BOOL型
241
242標準C++には、論理型であるbool型と、論理値であるtrueおよびfalseが存在
243する。しかし、TOPPERS/JSPカーネルがC言語で実装
244されているため、言語間
245の互換性をとる意味でもBOOL型にはint型を使用する必
246要がある。
247カーネルのコンパイルにC99を用いた場合でも、_Bool型とbool型の間には、
248厳密な互換性があるとは言いがたいため、やはりint型を使用した方が無難で
249ある。
250
2513.2 タスクからの例外リーク
252
253タスクのエントリ関数からキャッチされない例外がリークした場合の動作は
254未定義である。
255
2563.3 ATT_INIとVATT_TER
257
258静的APIのATT_INIおよびVATT_TERで登録された関数から例外がリークした場
259合の動作は未定義である。
260
2613.4 非タスクコンテキストとタスク例外処理ルーチン
262
263非タスクコンテキストとタスク例外処理ルーチンでは、例外処理、newおよび
264delete演算子を使用することができない。参ç…
265§åž‹ã«å¯¾ã™ã‚‹dynamic_castや、
266仮想関数を持つクラスへの参ç…
267§ã‚„ポインタに対するtypeidも、例外が発生す
268る可能性があるため、使用することができない。また、標準ライブラリ関数
269を呼出すこともできない。
270
271なお、タスク例外許可状æ…
272‹ã§è‡ªã‚¿ã‚¹ã‚¯ã«å¯¾ã™ã‚‹ras_texによって呼出されたタ
273スク例外処理ルーチンに限り、上記の制約は受けない。ただし、タスク例外
274処理ルーチンから例外をリークした場合の動作は未定義である。
275
2763.5 サービスコールの例外指定
277
278TOPPERS/JSPカーネルが提供するå…
279¨ã‚µãƒ¼ãƒ“スコールは例外をスローすることが
280ないため、例外指定throw()が付加される。
281これにより、例外処理のためのテーブルが生成されることを最小限に抑えら
282れる場合があり、主として空間効率の向上が期待
283できる。
284
285
2864.開発環境の構築
287
288C++開発環境の構築は、基本的には「GNU開発環境構築マニュアル」の内
289容に
290従うが、一部異なる点があるので、相違点を中心に解説する。
291なお、動作確認には、ホスト環境としてはCygwin 1.3.22を使用した。
292
2934.1 必
294要なソフトウェア
295
296C++開発環境を構築するには、GCC-COREおよびG++、またはGCCが必
297要になる。
298また、NEWLIBは必
299須である。
300
301 GNU開発環境
302 BINUTILS(アセンブラ,リンカなど)
303 GCC(C/C++コンパイラ)
304 GDB(デバッガ)
305 NEWLIB(標準Cライブラリ)
306 Perl(動作確認は 5.8.0)
307 GNU Make(動作確認は 3.80)
308 GNU sed(動作確認は 4.0.7)
309 patch(動作確認は 2.5.8)
310
3114.2 BINUTILSのインストール
312
313BINUTILSは、GCCのインストールに必
314要なため,GCCにå…
315ˆã ã£ã¦ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«
316する。BINUTILSのインストール手順は次の通り。
317
318 % mkdir <BINUTILS-OBJDIR>
319 % cd <BINUTILS-OBJDIR>
320 % <BINUTILS-SRCDIR>/configure --target=<TARGET> --prefix=<PREFIX>\
321 --disable-nls
322 % make
323 % make install
324
3254.3 GCCへのパッチ
326
327Cygwin上でGCC 3.2.3をmakeする場合に一部障害が発生するため、次のパッチ
328が必
329要となる。(SH版のみ。GCC 3.3.x以降では不要)
330
331 % cp gcc-3.2.3_fixinc_gnu-regex.patch <GCC-SRCDIR>
332 % cd <GCC-SRCDIR>
333 % patch -p1 < gcc-3.2.3_fixinc_gnu-regex.patch
334
335以下の手順に従って、GCCをTOPPERS/JSPカーネルに対応させるためのパッチ
336をあてる。
337
338 % cp gcc-3.2.3_gthr-toppers-1.patch <GCC-SRCDIR>
339 % cd <GCC-SRCDIR>
340 % patch -p1 < gcc-3.2.3_gthr-toppers-1.patch
341
3424.4 GCCのインストール(1)
343
344GCCのインストールにはNEWLIBが必
345要であるが、NEWLIBをインストールするに
346はGCCが必
347要なため、若干の工夫が必
348要になる。
349
350 % mkdir <GCC-OBJDIR>
351 % cd <GCC-OBJDIR>
352 % <GCC-SRCDIR>/configure --target=<TARGET> --prefix=<PREFIX>\
353 --enable-languages=c,c++ --enable-threads=toppers\
354 --disable-nls
355 % make all-gcc
356 % make install-host
357
3584.5 NEWLIBのインストール
359
360次の手順に従って、NEWLIBをインストールする.
361
362 % mkdir <NEWLIB-OBJDIR>
363 % cd <NEWLIB-OBJDIR>
364 % <NEWLIB-SRCDIR>/configure --target=<TARGET> --prefix=<PREFIX>
365 % make
366 % make install
367
368なお、CygwinのバージョンによってはNEWLIBのインストールに失敗する場合
369がある。そのような場合は、Cygwinのバージョンを変更するか、NEWLIBをバ
370イナリでå…
371¥æ‰‹ã™ã‚‹ã“と。
372
3734.6 GCCのインストール(2)
374
375次の手順に従って、GCCの残り部分をインストールする.
376
377 % cd <GCC-OBJDIR>
378 % make
379 % make install
380
381
3825.C++バインディングの実装
383詳細
384
3855.1 ファイル構成
386
387(1) cxxrt.cfg
388
389cxxrt.cfgはC++対応ランタイムの内
390部で使用するオブジェクトを生成する。
391C++の機能を使用する場合には、必
392ずコンフィギュレーションファイルから、
393cxxrt.cfgをインクルードする必
394要がある。
395
396(2) cxxrt.c
397
398cxxrt.cはC++対応ランタイムの本体であり、例外処理等で必
399要となる関数や
400変数の定義が行われる。
401
402(3) newlibrt.c
403
404newlibrt.cはNEWLIBの関数をTOPPERS/JSPカーネルに対応させるためのランタ
405イムであり、C++を使用する場合には必
406須である。
407このランタイムは、C++を使用しない場合でも、NEWLIBを使用する際には単独
408で使用することができる。
409
4105.2 同期機能
411
412例外処理および標準C++ライブラリ内
413部で使用する同期機能を提供する関数群。
414標準C++ライブラリはフリースタンディング環境ではサポートされないが、お
415そらくlibstdc++のå…
416¨æ©Ÿèƒ½ã‚’使用することができると思われる。(ただし、動
417作は確認していない)
418
419(1) int _toppers_cxxrt_lock(_toppers_cxxrt_sync_t *sync);
420
421マルチタスク動作時では、ロックを掛け、クリティカルセクションを開始す
422る。非マルチタスク動作時には何もしない。
423成功時には0を返し、失敗時には負の値を返す。
424
425この関数はネスティング可能である。
426
427(2) int _toppers_cxxrt_trylock(_toppers_cxxrt_sync_t *sync);
428
429_toppers_cxxrt_lock関数とほぼ同じであるが、既に他のタスクによってロック
430中の場合でも待
431機状æ…
432‹ã«ã¯ç§»è¡Œã›ãšã€å˜ã«å‘¼å‡ºã—に失敗する。
433現在の実装
434では、_toppers_cxxrt_lock関数はディスパッチ禁止を用いて実現し
435ているため、どちらも同じである。
436
437(3) int _toppers_cxxrt_unlock(_toppers_cxxrt_sync_t *sync);
438
439マルチタスク動作時では、ロックを解除し、クリティカルセクションを終了
440する。非マルチタスク動作時には何もしない。
441成功時には0を返し、失敗時には負の値を返す。
442
443(4) int _toppers_cxxrt_once(_toppers_cxxrt_once_t *once,
444 void (*func)(void));
445
446指定した関数を、システムå…
447¨ä½“で一度だけ実行させる。funcを実行中に、異
448なるタスクでも同じ関数を実行させようとした場合、funcの実行が完了する
449まで待
450機状æ…
451‹ã«ç§»è¡Œã™ã‚‹ã€‚
452成功時には0を返し、失敗時には負の値を返す。
453
4545.3 タスクローカル記憶域機能
455
456タスクごとに用意される、見かけ上静的な記憶域を提供する関数群であり、
457例外処理で使用される。
458タスクローカル記憶域として確保できるのは、デフォルトでは2個までである
459が、_CXXRT_KEY_MAXマクロをユーザ定義することで、3個以上に拡張すること
460ができる。
461
462(1) int _toppers_cxxrt_key_create(struct _toppers_cxxrt_tls **key,
463 void (*dtor)(void*))
464
465タスクローカル記憶域に確保する変数を新規作成する。
466成功時には0を返し、*keyに変数を識別するためのキーが格納される。
467dtorには、キーを削除する際に、タスクごとの各変数に対して実行すべき終
468了処理を指定する。
469失敗時には負の値を返す。
470
471(2) int _toppers_cxxrt_key_delete(struct _toppers_cxxrt_tls *key);
472
473_toppers_cxxrt_key_create関数で作成したキーを削除する。
474成功時には0を返し、失敗時には負の値を返す。
475
4765.4 NEWLIBのカスタマイズ
477
478(1) void __malloc_lock(struct _reent *ptr);
479
480mallocおよびfreeの排他制御を行う。他のタスクによってロックされている
481状況で呼出された場合は待
482機状æ…
483‹ã«ç§»è¡Œã™ã‚‹ã€‚
484
485(2) void __malloc_unlock(struct _reent *ptr);
486
487__malloc_lock関数によるロックを解除する。
488
489(3) void *_sbrk_r(struct _reent *ptr, ptrdiff_t nbytes);
490
491プログラムのヒープ領域をnbyteだけ拡大する。成功時には、新しい領域のå…
492ˆ
493頭へのポインタを返す。失敗時は負の値を返し、errnoおよびptr->_errnoに
494ENOMEMを設定する。
495
496ヒープ領域には、外部識別子end(.bssセクションの終端)から、マルチタス
497ク動作開始前のスタックポインタまでを使用する。
498メモリマップ上、複数のメモリイメージが発生するターゲットでは、.bssセ
499クションとスタックポインタの初期値を同一イメージ上にé…
500ç½®ã™ã‚‹å¿…
501要があ
502る。
503ヒープ領域と起動時のスタック領域が連続していない場合、sys_config.h内
504
505でHEAP_TOPマクロをヒープの終端アドレスに定義する必
506要がある。
507
508本来であれば、_sbrk_r関数の原始関数にあたる_sbrk関数をカスタマイズす
509べきであるが、ターゲットによっては、_write関数等と同一の翻訳単位にオ
510リジナルの_sbrk関数が定義されており、リンク時に障害が発生する原因とな
511るため、_sbrk_r関数をカスタマイズしている。
512
5135.5 その他
514
515(1) int main();
516
517JSPカーネル上で動作するC/C++プログラムはフリースタンディング環境であ
518るため、エントリ関数はmainではなくkernel_startである。しかし、NEWLIB
519ではエントリポイントとしてmainが使用されることを期待
520しているため、
521main関数がなければリンクエラーになる場合がある。
522C++対応ランタイムでは、リンクを解決することのみを目的としてmain関数を
523定義する。
524
525
5266.ターゲット依存部の実装
527
528
529現在、C++バインディングがサポートする実行環境は、MS7727CP01(SH3)およ
530びAKI-H8/3069Fである。
531また、GNU開発環境のターゲットとして、SH用にはsh-hitachi-elf、H8用には
532h8300-hmsを使用している。
533
5346.1 GNU開発環境に関するもの
535
536GNU開発環境å…
537¨èˆ¬ã«é–¢ã™ã‚‹è¦ç´ ã¨ã—て、以下のものがある。
538
539(1) リンカスクリプトの対応
540
541C++を用いる場合のリンカスクリプトには、.ctorおよび.dtor、すなわちグロ
542ーバルなコンストラクタやデストラクタのポインタテーブルを形成するため
543のセクション定義が必
544要である。
545また、.eh_frameや.gcc_except_tableなどの例外処理用のセクション定義も
546必
547要になる。
548
5496.2 ELF形式に関連するもの
550
551SHに限らず、ELF形式に依存する要素として、下記内
552容の対応が必
553要である。
554
555(1) crti.o, crtbegin.o, crtend.o, crtn.oのリンク
556
557グローバルなコンストラクタおよびデストラクタの呼出しや、例外処理関連
558に必
559要なため、これらのファイルを正しい順序でリンクする必
560要がある。
561リンクの順序は、
562
563start.o crti.o crtbegin.o ユーザプログラム libkernel.a libstdc++.a
564libm.a libc.a libgcc.a crtend.o crtn.o
565
566である。
567この指定には、ターゲット依存部のconfig/sh3/Makefile.configにおいて、
568
569START_OBJS = \
570 start.o \
571 $(shell $(CC) $(COPTS) -print-file-name=crti.o | sed -e 's/\\/\//g') \
572 $(shell $(CC) $(COPTS) -print-file-name=crtbegin.o | sed -e 's/\\/\//g')
573END_OBJS = \
574 $(shell $(CC) $(COPTS) -print-file-name=crtend.o | sed -e 's/\\/\//g') \
575 $(shell $(CC) $(COPTS) -print-file-name=crtn.o | sed -e 's/\\/\//g')
576
577のように定義されている。
578なお、文字'\'を'/'に置換しているのは、MinGW + MSysの環境で使用できる
579ようにするためである。
580また、make時に誤ってcrti.oなどのコンパイルを試みようとすることを回避
581する目的で、START_OBJSとEND_OBJS(およびstart.o)のmakeルールを特化し
582ている。
583
584(2) リンカスクリプトの対応
585
586.initや.fini等のELF形式特有のセクション定義が必
587要である。
588
5896.3 SHに特有のもの
590
591ターゲットがSHの場合に特有な要素として、以下のものがある。
592
593(1) _init関数および_fini関数
594
595GCCの多くのターゲットでは、ELF形式の場合、初期化関数および終了時関数
596として、_init関数と_fini関数を使用する。しかし、SHの場合にはinit関数
597とfini関数(å…
598ˆé ­ã®ä¸‹ç·šãŒãªã„)を使用している。そのため、tool_defs.h
599において、initおよびfiniにそれぞれマクロ置換している。
600
601
6027.アプリケーション作成におけるヒント
603
6047.1 静的なオブジェクト
605
606静的なオブジェクトは普通に定義することができるが、以下の点に注意する
607必
608要がある。
609
610(1) カーネル非動作状æ…
611‹
612
613グローバルなコンストラクタやデストラクタは、カーネル非動作状æ…
614‹ã§å‘¼å‡º
615される。したがって、これらの関数内
616では、μITRONのサービスコールを呼出
617すことは出来ない。唯一呼出すことが出来るサービスコールは、JSPカーネル
618の独自拡張であるvsns_iniだけである。
619
620クラスをグローバルでもローカルでも使えるようにするには、必
621要に応じて、
622vsns_iniでカーネルの動作状æ…
623‹ã‚’判別し、状æ…
624‹ã«å¿œã˜ã¦å‡¦ç†ã‚’分ける必
625要が
626ある。
627
628(2) 関数内
629の静的オブジェクト
630
631関数内
632で定義された静的オブジェクトのコンストラクタは、必
633ずしも起動時
634に呼出される訳ではなく、実行パスが最初にそのオブジェクトの定義箇所に
635差掛かった時点で呼出される。
636したがって、コンストラクタがカーネル動作状æ…
637‹ã§å‘¼å‡ºã•ã‚Œã‚‹ã‹ã€éžå‹•ä½œçŠ¶
638æ…
639‹ã§å‘¼å‡ºã•ã‚Œã‚‹ã‹ã¯ã€ãã®ã‚ªãƒ–ジェクトが定義された関数が最初に呼出され
640るタイミングに依存する。
641
642一般的に、この問題を回避するにはDouble-Checked Lockingと呼ばれる手法
643が用いられる。
644
645class foo
646{
647 // クラス定義
648};
649
650void func()
651{
652 static foo* ptr = 0;
653 if (ptr == 0)
654 {
655 wai_sem(SEMID);
656 if (ptr == 0)
657 {
658 static foo x;
659 ptr = &x;
660 }
661 sig_sem(SEMID);
662 }
663 // 関数本体の処理
664}
665
666(3) システムログの使用
667
668デストラクタでは、システムログを制限なく使用することができるが、グロ
669ーバルなコンストラクタでは、デフォルトではシステムログを使用すること
670ができない。
671
6727.2 new演算子とdelete演算子
673
674(1) 排他制御について
675
676new演算子とdelete演算子は、処理速度を向上するため、フリーストアからの
677メモリ割付け(std::malloc関数を用いて実装
678)はディスパッチ禁止状æ…
679‹ã§è¡Œ
680っている。
681アプリケーションの要求によって、他の方法で排他制御を行う必
682要がある場
683合には、systask/cxxrt.cの中の__malloc_lock関数と__malloc_unlock関数を
684カスタマイズすればよい。
685
686(2) 使用に関する制約
687
688非タスクコンテキストやタスク例外処理ルーチンで呼出すことはできない。
689カーネル非動作状æ…
690‹ï¼ˆvsns_ini関数がTRUEを返す期間)では、通常通り使用
691することができる。
692
693(3) オーバーロードについて
694
695グローバルなnew演算子とdelete演算子は、実行効率はまずまずであるが、空
696間効率は決して高いとはいえない。また、特定のクラスの最低生成数につい
697ても評価しにくいため、厳密な動作保証を必
698要とするクラスに関しては、new
699演算子とdelete演算子をオーバーロードすることを推奨する。
700
701オーバーロードに際しては、固定長メモリプール等を用いることが出来る。
702例えば、以下のようにクラスを定義することが出来る。
703
704#include <t_services.h>
705#include <cstddef>
706#include "kernel_id.h"
707
708class foo
709{
710 static ID mpfid_;
711public:
712 static void* operator new(std::size_t size) throw()
713 {
714 VP ptr;
715 get_mpf(mpfid_, &ptr);
716 assert(ptr != 0);
717 return ptr;
718 }
719 static void operator delete(void* ptr) throw()
720 {
721 rel_mpf(mpfid_, ptr);
722 }
723};
724
725static ID foo::mpfid_ = FOO_MPF; // 固定長メモリプールのID番号
726
727また、new演算子のé…
728ç½®æ§‹æ–‡ã‚’使用することで、タイムアウト指定等の機能を
729追加することも可能である。
730
731static void* operator new(std::size_t size, TMO tmout);
732static void operator delete(void* ptr, TMO) throw();
733
734なお、new演算子をオーバーロードする場合、必
735ず対応するdelete演算子も合
736わせてオーバーロードしなければならない。
737上記の場合、delete演算子でTMO型の引数を使用することはないが、newされ
738たクラスのコンストラクタから例外がスローされた場合(new演算子そのもの
739ではない)、対応するdelete演算子が必
740要になる。
741
7427.3 例外処理
743
744(1) 例外処理の内
745部処理
746
747GCCでは、configure時に--enable-sjlj-exceptionsを指定した場合、例外処
748理を実現するためにsetjmpおよびlongjmp関数を使用している。ターゲットに
749よっては他の実現方法を選択することもできるが、動作確認は行っていない。
750
751例外をT型のオブジェクトをthrowした場合、内
752部的には以下の順序で処理が
753行われる。
754
755 1) std::malloc関数により、T型のオブジェクトを格納可能なメモリブロ
756 ックが割付けられる。
757 割付けに失敗した場合、緊急用の静的なバッファが当てられる。
758
759 2) T型のコピーコンストラクタが呼出され、throwされたオブジェクトの
760 コピーが、1)で割付けたブロックを用いて生成される。
761 コピーコンストラクタ内
762で例外がthrowされた場合はstd::terminate
763 関数が呼出された後、std::abort関数により異常終了する。
764
765 3) 例外処理フレームを検索し、catchされるまでの経路に存在するロー
766 カルなオブジェクトのデストラクタが呼出される。
767 ここで、デストラクタ内
768で例外がthrowされた場合はstd::terminate
769 関数が呼出された後、std::abort関数により異常終了する。
770
771 4) T型(またはその基底クラス)に対応するcatchブロックが見つかった
772 場合は、そのブロックに広域分岐する。catchブロックのパラメータ
773 が値渡しの場合、コピーコンストラクタによって新しいローカルなオ
774 ブジェクトが生成される。
775 対応するcatchブロックが見つからなかった場合や値渡しの際に例外
776 がthrowされた場合はstd::terminate関数が呼出された後、std::abort
777 関数により異常終了する。
778
779 5) catchブロック内
780の処理が実行される。
781
782 6) 上記2)で生成されたオブジェクトのデストラクタが呼出される。
783
784(2) タスク再起動時の初期化
785
786JSP 1.4では再起動時の初期化処理として_toppers_cxxrt_reset_specific関
787数を呼び出す必
788要があったが、JSP 1.4.1では_toppers_cxxrt_reset_specific
789関数の呼び出しは必
790要としない。
791その代わり、タスクのエントリ関数から例外が動作した場合の動作は未定義
792である。
793
794(3) 効率の向上
795
796configure時に--enable-sjlj-exceptionsを指定した場合、例外をthrowしな
797い場合でも、若干の実行効率の低下が起こる。また、空間効率が著しく低下
798する場合がある。
799効率を少しでも改善するには、以下の方法が有効である。
800
801 1) できるだけインライン関数を使用する。例外処理に関するオーバーヘ
802 ッドの多くは、関数の呼出しに付随して発生する。
803
804 2) 決して例外を発生しない関数には、必
805ず例外指定throw()を付加する。
806 特に、C言語で実装
807された関数は、必
808ずthrow()を付けること。
809
810 3) 例外が発生するかもしれない関数には例外指定を付けない。
811 例外指定を付けるとフィルタリング処理が暗黙的に展開される。
812
813 4) 可能な限りデストラクタを定義しない。
814 関数内
815でデストラクタを持つローカルなオブジェクトを使わなければ、
816 例外をthrowするかもしれない関数を呼んでも、オーバーヘッドにな
817 らない場合がある。
818
819 5) 一時オブジェクトの生成を避ける
820 一時オブジェクト生成はそれ自体がオーバーヘッドであるだけでなく、
821 コンストラクタで例外が発生する機会を作り、またデストラクタが呼
822 び出される機会を増やす。
823
8247.4 C言語との混在
825
826C++からC言語で定義した関数を呼出す場合、extern "C"により"C"リンケージ
827であることを明示的に指定しなければならない。
828
829extern "C" int foo();
830
831extern "C" {
832 void hoge();
833 void bar();
834}
835
836また、C言語から呼出す可能性のある関数をC++で定義する場合もextern "C"
837を関数定義に付加する必
838要がある。
839
840CとC++では互換性のない型もあるため、両方から使用する関数に、そうした
841型を使用すべきではない。例えば、boolやクラス型などである。
842特に、kernel_cfg.cはC言語であるため、タスク等の拡張情
843報にクラスのポイ
844ンタを指定することはできない。
845
846C関数からC++関数の呼出しは、原則として行うべきではない。内
847部で例外が
848発生した場合、動作が保証できないのがその理由である。
849通常の呼出しの他、コールバック関数を用いる場合も例外ではない。
850
851C++関数からC関数を呼出す場合、C関数には例外指定throw()を付加すべきで
852ある。こうすることで大幅
853に効率の向上が期待
854できる。
855
856以上
857
Note: See TracBrowser for help on using the repository browser.