OSDN Git Service

Doxygenコメントを追加した。
[uzume/uzume_bfin.git] / uzumeapp / kernel / cfg / jsp / jsp_check.cpp
1 /*
2  *  TOPPERS/JSP Kernel
3  *      Toyohashi Open Platform for Embedded Real-Time Systems/
4  *      Just Standard Profile Kernel
5  * 
6  *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
7  *                              Toyohashi Univ. of Technology, JAPAN
8  * 
9  *  上記著作権者は,以下の (1)〜(4) の条件か,Free Software Foundation 
10  *  によって公表されている GNU General Public License の Version 2 に記
11  *  述されている条件を満たす場合に限り,本ソフトウェア(本ソフトウェア
12  *  を改変したものを含む.以下同じ)を使用・複製・改変・再配布(以下,
13  *  利用と呼ぶ)することを無償で許諾する.
14  *  (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
15  *      権表示,この利用条件および下記の無保証規定が,そのままの形でソー
16  *      スコード中に含まれていること.
17  *  (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
18  *      用できる形で再配布する場合には,再配布に伴うドキュメント(利用
19  *      者マニュアルなど)に,上記の著作権表示,この利用条件および下記
20  *      の無保証規定を掲載すること.
21  *  (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
22  *      用できない形で再配布する場合には,次のいずれかの条件を満たすこ
23  *      と.
24  *    (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
25  *        作権表示,この利用条件および下記の無保証規定を掲載すること.
26  *    (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
27  *        報告すること.
28  *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
29  *      害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
30  * 
31  *  本ソフトウェアは,無保証で提供されているものである.上記著作権者お
32  *  よびTOPPERSプロジェクトは,本ソフトウェアに関して,その適用可能性も
33  *  含めて,いかなる保証も行わない.また,本ソフトウェアの利用により直
34  *  接的または間接的に生じたいかなる損害に関しても,その責任を負わない.
35  * 
36  *  @(#) $Id: jsp_check.cpp,v 1.1 2009/01/31 05:27:37 suikan Exp $
37  */
38
39 // $Header: /cvsroot/toppersjsp4bf/jsp/cfg/jsp/jsp_check.cpp,v 1.1 2009/01/31 05:27:37 suikan Exp $
40
41 #include "base/defs.h"
42 #include "jsp/jsp_defs.h"
43 #include "base/message.h"
44 #include "base/component.h"
45 #include "base/filecontainer.h"
46
47 #include <fstream>
48 #include <iomanip>
49
50 class ConfigurationChecker : public Component
51 {
52 public:
53
54     enum tagCheckLevel
55     {
56         UNKNOWN    = 0,
57         LAZY       = 1,     /* 致命的 (行き過ぎ改造防止用)  */
58         STANDARD   = 2,     /* ITRON仕様の範囲 (改造を許容) */
59         TOPPERS    = 4,     /* TOPPERS/JSPの範囲内          */
60         RESTRICTED = 8,     /* 片っ端から捕まえる           */
61
62         NORMAL     = 8
63     };
64
65 protected:
66     enum tagCheckLevel current_level;
67
68     unsigned int error_count;
69     std::string banner;
70
71     void set_banner(Directory &, Formatter , const char *, int);
72     void notify(enum tagCheckLevel, Formatter , bool = true);
73
74     bool check_taskblock(Directory &, FileContainer *);
75     bool check_semaphoreblock(Directory &, FileContainer *);
76     bool check_eventflagblock(Directory &, FileContainer *);
77     bool check_dataqueueblock(Directory &, FileContainer *);
78     bool check_mailboxblock(Directory &, FileContainer *);
79     bool check_fixed_memorypoolblock(Directory &, FileContainer *);
80     bool check_cyclic_handlerblock(Directory &, FileContainer *);
81     bool check_interrupt_handlerblock(Directory &, FileContainer *);
82     bool check_exception_handlerblock(Directory &, FileContainer *);
83
84     virtual void parseOption(Directory &);
85     virtual void body(Directory &);
86
87 public:
88     ConfigurationChecker(void) throw();
89     ~ConfigurationChecker(void) throw() {}
90 };
91
92 //------------------------------------------------------
93 using namespace std;
94
95 static ConfigurationChecker  instance_of_ConfigurationChecker;
96
97 //------------------------------------------------------
98     //ターゲットの同名の型よりも大きな型の定義
99     // (注) 値比較, 演算が可能な型であること
100
101 typedef          int  DT_INT;
102 typedef unsigned int  DT_UINT;
103 typedef unsigned long DT_FP;
104 typedef unsigned long DT_VP_INT;
105 typedef unsigned long DT_VP;
106 typedef          long DT_RELTIM;
107
108 //------------------------------------------------------
109
110 ConfigurationChecker::ConfigurationChecker(void) throw()
111 {
112     setBanner("--- TOPPERS/JSP Configuration Checker (ver 2.4) ---");
113 }
114
115 void ConfigurationChecker::set_banner(Directory & container, Formatter object, const char * type, int id)
116 {
117     Directory * node;
118     char buffer[32];
119
120     banner = string("    ") + object.str() + " : ";
121
122     sprintf(buffer, "id = %d", id);
123
124     node = container.findChild(OBJECTTREE, type, NULL)->getFirstChild();
125     while(node != 0 && node->toInteger() != id)
126         node = node->getNext();
127
128     if( node != 0 ) {
129         banner += node->getKey() + " (" + buffer + ") ";
130
131         node = node->findChild("position");
132         if(node != 0)
133             banner += string("at ") + node->toString();
134     }
135     else
136         banner += buffer;
137
138     if(VerboseMessage::getVerbose())
139     {
140         cout << banner << endl;
141         banner.erase();
142     }
143 }
144
145 void ConfigurationChecker::notify(enum tagCheckLevel level, Formatter msg, bool error)
146 {
147     if((level & current_level) != 0)
148     {
149
150         if(!banner.empty())
151         {
152             cout << banner << endl;
153             banner.erase();
154         }
155
156         cout << "      ";
157
158         if(error)
159         {
160             cout << Message("[ Error ] ","[エラー] ");
161             error_count ++;
162         }else
163             cout << Message("[Warning] ","[ 警告 ] ");
164         cout << msg << endl;
165     }
166 }
167
168     /*
169      * タスクオブジェクトに関するエラー検出
170      */
171
172 bool ConfigurationChecker::check_taskblock(Directory & parameter, FileContainer * container)
173 {
174     unsigned int id;
175     unsigned int maxpri;
176     unsigned int minpri;
177     unsigned int old_error_count = error_count;
178
179     TargetVariable<unsigned int> _kernel_tmax_tskid("_kernel_tmax_tskid");
180
181     Message object("Task","タスク");
182
183     if(!_kernel_tmax_tskid.isValid())
184         ExceptionMessage(
185             "Internal error: Unknown symbol (Probably, Symbol table was stripped)",
186             "内部エラー: 不正なシンボル名 (実行形式がシンボルテーブルを含んでない可能性があります)").throwException();
187
188     if(*_kernel_tmax_tskid < 1)
189     {
190         notify(RESTRICTED,
191             Message("  [Task] : No tasks created\n","  [タスク] : タスクオブジェクトがありません\n"));
192         return true;
193     }
194
195     TargetVariable<DT_UINT> tskatr("_kernel_tinib_table", "task_initialization_block::tskatr");
196     TargetVariable<DT_FP>   task("_kernel_tinib_table", "task_initialization_block::task");
197     TargetVariable<DT_INT>  ipriority("_kernel_tinib_table", "task_initialization_block::ipriority");
198     TargetVariable<DT_UINT> texatr("_kernel_tinib_table", "task_initialization_block::texatr");
199     TargetVariable<DT_UINT> stksz("_kernel_tinib_table", "task_initialization_block::stksz");
200
201     maxpri = container->getVariableInfo("TMAX_TPRI").value;
202     minpri = container->getVariableInfo("TMIN_TPRI").value;
203
204     VerboseMessage("% object : % items\n","%オブジェクト : % 個\n") << object << *_kernel_tmax_tskid;
205     for(id = 1; id <= *_kernel_tmax_tskid; id++)
206     {
207         set_banner(parameter, object, TASK, id);
208
209             /*
210              *  属性チェック
211              */
212
213             // 属性値が TA_HLNG|TA_ASM|TA_ACT 以外の値をとっている
214         if((*tskatr & ~0x3) != 0)
215             notify( STANDARD,
216                 Message("Illegal task attribute (It should be ((TA_HLNG||TA_ASM)|TA_ACT))",
217                         "不正なタスク属性 ((TA_HLNG||TA_ASM)|TA_ACT)以外"));
218
219             // 属性値に TA_ASM が含まれている
220         if((*tskatr & 0x1) != 0)
221             notify( RESTRICTED,
222                 Message("TA_ASM specified as task attribute takes no effect.",
223                         "タスク属性にTA_ASMが指定されている"));
224
225             /* 起動番地が0 */
226         if(*task == 0)
227             notify(RESTRICTED,
228                 Message("The address of task routine is equal to zero.",
229                         "開始番地に0が設定されています"));
230
231             /*
232              *  優先度チェック
233              */
234
235             // 最大優先度と最小優先度の設定がおかしい
236         if(maxpri < minpri)
237             notify(LAZY,
238                 Message("Illegal Priority Settings found (TMAX_TPRI(%) < TMIN_TPRI).",
239                         "初期優先度が最低優先度(%)を超えている") << minpri);
240
241             // 優先度の範囲が[最小優先度, 最大優先度]の範囲を超えている
242         if(*ipriority > (signed)(maxpri - minpri))
243             notify(TOPPERS,
244                 Message("Initial priority is greater than maximum priority (%).",
245                         "初期優先度が最大優先度(%)を超えている") << maxpri);
246         if(*ipriority < 0)
247             notify(STANDARD,
248                 Message("Initial priority is less than the minimum priority (%).",
249                         "初期優先度が最低優先度(%)を下回る") << minpri);
250
251             /*
252              *   タスク例外属性チェック
253              */
254
255             // 属性値がTA_HLNG or TA_ASMでない
256         if((*texatr & ~0x3) != 0)
257             notify(STANDARD,
258                 Message("Task exception routine has an illegal attribute specifier.",
259                         "タスク例外に無効な属性(TA_HLNG,TA_ASM以外) が設定されています"));
260
261             // 属性値に TA_ASM が含まれている
262         if((*texatr & 0x1) != 0)
263             notify( RESTRICTED,
264                 Message("TA_ASM, specified as texatr, does not always take effect.",
265                         "タスク例外にTA_ASMが指定されています"));
266
267             /*
268              *   スタックチェック
269              */
270
271             // スタックサイズが0
272         if(*stksz == 0)
273             notify(RESTRICTED,
274                 Message("Stack size is equal to zero.",
275                         "スタックサイズに0が設定されています"));
276
277             // スタックの番地が0
278         if(*stksz == 0)
279             notify(RESTRICTED,
280                 Message("The address of task stack is equal to zero.",
281                         "スタック開始番地に0が設定されています"));
282
283         ++ tskatr, ++ task, ++ ipriority, ++ texatr, ++ stksz;
284     }
285
286     return old_error_count == error_count;
287 }
288
289 bool ConfigurationChecker::check_semaphoreblock(Directory & parameter, FileContainer * container)
290 {
291     unsigned int id;
292     unsigned int old_error_count = error_count;
293
294     Message object("Semaphore","セマフォ");
295
296     TargetVariable<DT_UINT> _kernel_tmax_semid("_kernel_tmax_semid");
297     if(*_kernel_tmax_semid < 1)
298         return true;
299
300     TargetVariable<DT_UINT> sematr("_kernel_seminib_table","semaphore_initialization_block::sematr");
301     TargetVariable<DT_UINT> maxsem("_kernel_seminib_table","semaphore_initialization_block::maxsem");
302     TargetVariable<DT_UINT> isemcnt("_kernel_seminib_table","semaphore_initialization_block::isemcnt");
303
304     VerboseMessage("% object : % items\n","%オブジェクト : % 個\n")
305         << object << *_kernel_tmax_semid;
306
307     for(id = 1; id <= *_kernel_tmax_semid; id++)
308     {
309         set_banner(parameter, object, SEMAPHORE, id);
310
311             //attribute validation check
312         if((*sematr & ~0x1) != 0)
313             notify(STANDARD,
314                 Message("Illegal attribute (It should be (TA_TFIFO||TA_TPRI)).",
315                         "(TA_TFIFO||TA_TPRI)以外の属性が指定されている"));
316
317             //maxcnt < isemcnt
318         if(*maxsem < *isemcnt)
319             notify(STANDARD,
320                 Message("Initial count[%] is greater than the maximum count[%] of this semaphore",
321                         "初期値[%]が最大値[%]を超えている") << *isemcnt << *maxsem);
322
323         if(*maxsem == 0)
324             notify(STANDARD,
325                 Message("Maximum count must be greater than zero.",
326                         "セマフォの最大カウントは1以上でなければいけません"));
327
328         ++ sematr, ++ maxsem, ++ isemcnt;
329     }
330
331     return old_error_count == error_count;
332 }
333
334
335 bool ConfigurationChecker::check_eventflagblock(Directory & parameter, FileContainer * container)
336 {
337     unsigned int id;
338     unsigned int old_error_count = error_count;
339
340     Message object("Event flag","イベントフラグ");
341
342     TargetVariable<DT_UINT> _kernel_tmax_flgid("_kernel_tmax_flgid");
343     if(*_kernel_tmax_flgid < 1)
344         return true;
345
346     TargetVariable<DT_UINT> flgatr("_kernel_flginib_table","eventflag_initialization_block::flgatr");
347
348     VerboseMessage("% object : % items\n","%オブジェクト : % 個\n")
349          << object << *_kernel_tmax_flgid;
350
351     for(id = 1; id <= *_kernel_tmax_flgid; id++)
352     {
353         set_banner(parameter, object, EVENTFLAG, id);
354             
355             //attribute validation check
356         if((*flgatr & ~0x7) != 0)
357             notify(STANDARD,
358                 Message("Illegal attribute value [0x%]",
359                         "おかしな属性値 [0x%]") << setbase(16) << (*flgatr & ~0x7));
360
361         if((*flgatr & 0x2) != 0)
362             notify(TOPPERS,     //依存部で直らないのでRESTRICTEDにしない
363                 Message("Attribute TA_WMUL is not supported in current version.",
364                         "TA_WMULはサポート外"));
365     
366         ++ flgatr;
367     }
368
369     return old_error_count == error_count;
370 }
371
372
373 bool ConfigurationChecker::check_dataqueueblock(Directory & parameter, FileContainer * container)
374 {
375     unsigned int id;
376     unsigned int old_error_count = error_count;
377
378     Message object("Data queue","データキュー");
379
380     TargetVariable<DT_UINT> _kernel_tmax_dtqid("_kernel_tmax_dtqid");
381     if(*_kernel_tmax_dtqid < 1)
382         return true;
383
384     TargetVariable<DT_UINT> dtqatr("_kernel_dtqinib_table", "dataqueue_initialization_block::dtqatr");
385     TargetVariable<DT_UINT> dtqcnt("_kernel_dtqinib_table", "dataqueue_initialization_block::dtqcnt");
386     TargetVariable<DT_VP_INT> dtq("_kernel_dtqinib_table", "dataqueue_initialization_block::dtq");
387
388     VerboseMessage("% object : % items\n","%オブジェクト : % 個\n")
389         << object << *_kernel_tmax_dtqid;
390
391     for(id = 1; id <= *_kernel_tmax_dtqid; id++)
392     {
393         set_banner(parameter, object, DATAQUEUE, id);
394
395             //attribute validation check
396         if((*dtqatr & ~0x1) != 0)
397             notify(STANDARD,
398                 Message("Illegal attribute value [0x%]",
399                         "おかしな属性値 [0x%]") << setbase(16) << (*dtqatr & ~0x1));
400
401         if(*dtqcnt != 0 && *dtq == 0)
402             notify(TOPPERS,
403                 Message("Dataqueue buffer should not be NULL", "データキューのバッファがNULL値"));
404
405         ++ dtqatr, ++ dtqcnt, ++ dtq;
406     }
407
408     return old_error_count == error_count;
409 }
410
411
412 bool ConfigurationChecker::check_mailboxblock(Directory & parameter, FileContainer * container)
413 {
414     unsigned int id;
415     unsigned int old_error_count = error_count;
416
417     Message object("Mailbox","メールボックス");
418
419     TargetVariable<DT_UINT> _kernel_tmax_mbxid("_kernel_tmax_mbxid");
420     if(*_kernel_tmax_mbxid < 1)
421         return true;
422     
423     TargetVariable<DT_UINT> mbxatr("_kernel_mbxinib_table","mailbox_initialization_block::mbxatr");
424     TargetVariable<DT_INT>  maxmpri("_kernel_mbxinib_table","mailbox_initialization_block::maxmpri");
425
426     DT_INT maxpri = container->getVariableInfo("TMAX_MPRI").value;
427     DT_INT minpri = container->getVariableInfo("TMIN_MPRI").value;
428
429     VerboseMessage("% object : % items\n","%オブジェクト : % 個\n") << object << *_kernel_tmax_mbxid;
430     for(id = 1; id <= *_kernel_tmax_mbxid; id++)
431     {
432         set_banner(parameter, object, MAILBOX, id);
433
434             //attribute validation check
435         if((*mbxatr & ~0x3) != 0)
436             notify(STANDARD,
437                 Message("Illegal attribute value [0x%]",
438                         "おかしな属性値 [0x%]") << setbase(16) << (*mbxatr & ~0x3));
439     
440             //mailbox message priority check
441         if(*maxmpri < 0)
442             notify(STANDARD,
443                 Message("Priority must not be a negative number.","優先度が負値"));
444
445         if(*maxmpri < minpri)
446             notify(STANDARD,
447                 Message("Message priority should be greater than or equal to %.",
448                         "メッセージ優先度は%以上でなければいけません") << minpri);
449
450         if(*maxmpri > maxpri)
451             notify(STANDARD,
452                 Message("Message priority should be less than or equal to %.",
453                         "メッセージ優先度は%以下でなければいけません") << maxpri);
454
455         ++ mbxatr, ++ maxmpri;
456     }
457
458     return old_error_count == error_count;
459 }
460
461 bool ConfigurationChecker::check_fixed_memorypoolblock(Directory & parameter, FileContainer * container)
462 {
463     unsigned int id;
464     unsigned int old_error_count = error_count;
465
466     Message object("Fixed size memory pool","固定長メモリプール");
467
468     TargetVariable<DT_UINT> _kernel_tmax_mpfid("_kernel_tmax_mpfid");
469     if(*_kernel_tmax_mpfid < 1)
470         return true;
471
472     TargetVariable<DT_UINT> mpfatr("_kernel_mpfinib_table", "fixed_memorypool_initialization_block::mpfatr");
473     TargetVariable<DT_UINT> limit ("_kernel_mpfinib_table", "fixed_memorypool_initialization_block::limit");
474     TargetVariable<DT_VP>   mpf   ("_kernel_mpfinib_table", "fixed_memorypool_initialization_block::mpf");
475     TargetVariable<DT_UINT> blksz ("_kernel_mpfinib_table", "fixed_memorypool_initialization_block::blksz");
476
477     VerboseMessage("% object : % items\n","%オブジェクト : % 個\n") << object << *_kernel_tmax_mpfid;
478     for(id = 1; id <= *_kernel_tmax_mpfid; id++)
479     {
480         set_banner(parameter, object, FIXEDSIZEMEMORYPOOL, id);
481
482             //attribute validation check
483         if((*mpfatr & ~0x1) != 0)
484             notify(STANDARD,
485                 Message("Illegal attribute value [0x%]","おかしな属性値 [0x%]") << (*mpfatr & ~0x1));
486
487             //ブロック数が0
488         if(*mpf == *limit)
489             notify(STANDARD,
490                 Message("blkcnt should be a non-zero value.","ブロック数が0です"));
491
492             //ブロックサイズが0
493         if(*blksz == 0)
494             notify(STANDARD,
495                 Message("blksz should be a non-zero value.","ブロックサイズが0です"));
496
497             //バッファアドレスが0
498         if(*mpf == 0)
499             notify(TOPPERS,
500                 Message("buffer address is a NULL pointer.","バッファアドレスがNULLポインタになっています"));
501
502         ++ mpfatr, ++ limit, ++ mpf, ++ blksz;
503     }
504
505     return old_error_count == error_count;
506 }
507
508
509 bool ConfigurationChecker::check_cyclic_handlerblock(Directory & parameter, FileContainer * container)
510 {
511     unsigned int id;
512     unsigned int old_error_count = error_count;
513
514     Message object("Cyclic handler","周期ハンドラ");
515
516     TargetVariable<DT_UINT> _kernel_tmax_cycid("_kernel_tmax_cycid");
517     if(*_kernel_tmax_cycid < 1)
518         return true;
519
520     DT_RELTIM maxreltim = container->getVariableInfo("TMAX_RELTIM").value;
521     TargetVariable<DT_UINT> cycatr("_kernel_cycinib_table", "cyclic_handler_initialization_block::cycatr");
522     TargetVariable<DT_RELTIM> cyctim("_kernel_cycinib_table", "cyclic_handler_initialization_block::cyctim");
523     TargetVariable<DT_RELTIM> cycphs("_kernel_cycinib_table", "cyclic_handler_initialization_block::cycphs");
524
525     VerboseMessage("% object : % items\n","%オブジェクト : % 個\n") << object << *_kernel_tmax_cycid;
526     for(id = 1; id <= *_kernel_tmax_cycid; id++)
527     {
528         set_banner(parameter, object, CYCLICHANDLER, id);
529
530             //attribute validation check
531         if((*cycatr & ~0x7) != 0)
532             notify(STANDARD,
533                 Message("Illegal attribute value [0x%]","おかしな属性値 [0x%]") << (*cycatr & ~0x1));
534
535         if((*cycatr & 0x4) != 0)
536             notify(TOPPERS,     //非依存部なのでRESTRICTEDにしない
537                 Message("TA_PHS is not supported in this kernel.","TA_PHSはサポート外"));
538
539             // 属性値に TA_ASM が含まれている
540         if((*cycatr & 0x1) != 0)
541             notify( RESTRICTED,
542                 Message("TOPPERS/JSP Kernel never minds the flag 'TA_ASM'.",
543                         "TOPPERS/JSPカーネルの全ての機種依存部でTA_ASMをサポートするとは限らない"));
544
545             //RELTIMでの表現範囲内にあるかどうかのチェック
546         if(*cyctim > maxreltim)
547             notify(STANDARD,
548                 Message("The cyclic object has a period (%) that exceeds the maximum period (%)",
549                         "起動周期(%)が表現可能な相対時間の範囲(%)を超えています") << *cyctim << maxreltim);
550
551             //起動周期が0でないことのチェック
552         if(*cyctim == 0)
553             notify(STANDARD,
554                 Message("The cyclic object has a ZERO period.",
555                         "起動周期が0になっています"));
556
557         if(*cycphs > maxreltim)
558             notify(STANDARD,
559                 Message("The cyclic object has a initial delay (%) that exceeds the maximum period (%)",
560                         "起動位相(%)が表現可能な相対時間の範囲(%)を超えています") << *cycphs << maxreltim);
561
562         ++ cycatr, ++ cyctim, ++ cycphs;
563     }
564
565     return old_error_count == error_count;
566 }
567
568 bool ConfigurationChecker::check_interrupt_handlerblock(Directory & parameter, FileContainer * container)
569 {
570     unsigned int id;
571     unsigned int old_error_count = error_count;
572
573     Message object("Interrupt handler","割込みハンドラ");
574
575     TargetVariable<DT_UINT> _kernel_tnum_inhno("_kernel_tnum_inhno");
576     if(*_kernel_tnum_inhno == 0)
577         return true;
578
579     TargetVariable<DT_UINT> inhatr("_kernel_inhinib_table", "interrupt_handler_initialization_block::inhatr");
580     TargetVariable<DT_FP>   inthdr("_kernel_inhinib_table", "interrupt_handler_initialization_block::inthdr");
581
582     VerboseMessage("% object : % items\n","%オブジェクト : % 個\n") << object << *_kernel_tnum_inhno;
583     for(id = 0; id < *_kernel_tnum_inhno; id++)
584     {
585         set_banner(parameter, object, INTERRUPTHANDLER, id);
586
587             //attribute validation check
588         if((*inhatr & 0x1) != 0)
589             notify(STANDARD,
590                 Message("The attribute can take only TA_HLNG|TA_ASM",
591                         "TA_HLNG|TA_ASM以外の属性は設定できません"));
592
593             // 属性値に TA_ASM が含まれている
594         if((*inhatr & 0x1) != 0)
595             notify(RESTRICTED,
596                 Message("TOPPERS/JSP Kernel never minds the flag 'TA_ASM'.",
597                         "TA_ASMが使用されている"));
598
599             // 起動番地チェック
600         if(*inthdr == 0)
601             notify(RESTRICTED,
602                 Message("NULL pointer is specified as an inthdr address.",
603                         "割込みハンドラの番地がNULLです"));
604
605         ++ inhatr, ++ inthdr;
606     }
607
608     return old_error_count == error_count;
609 }
610
611 bool ConfigurationChecker::check_exception_handlerblock(Directory & parameter, FileContainer * container)
612 {
613     unsigned int id;
614     unsigned int old_error_count = error_count;
615
616     Message object("Exception handler","例外ハンドラ");
617
618     TargetVariable<DT_UINT> _kernel_tnum_excno("_kernel_tnum_excno");
619     if(*_kernel_tnum_excno == 0)
620         return true;
621
622     TargetVariable<DT_UINT> excatr("_kernel_excinib_table", "cpu_exception_handler_initialization_block::excatr");
623     TargetVariable<DT_FP>   exchdr("_kernel_excinib_table", "cpu_exception_handler_initialization_block::exchdr");
624
625     VerboseMessage("% object : % items\n","%オブジェクト : % 個\n") << object << *_kernel_tnum_excno;
626     for(id = 0; id < *_kernel_tnum_excno; id++)
627     {
628         set_banner(parameter, object, EXCEPTIONHANDLER, id);
629
630             //attribute validation check
631         if((*excatr & 0x1) != 0)
632             notify(STANDARD,
633                 Message("The attribute can take only TA_HLNG|TA_ASM",
634                         "TA_HLNG|TA_ASM以外の属性は設定できません"));
635
636             // 属性値に TA_ASM が含まれている
637         if((*excatr & 0x1) != 0)
638             notify(RESTRICTED,
639                 Message("TOPPERS/JSP Kernel never minds the flag 'TA_ASM'.",
640                         "TOPPERS/JSPカーネルの全ての機種依存部でTA_ASMをサポートするとは限らない"));
641
642             // 起動番地チェック
643         if(*exchdr == 0)
644             notify(RESTRICTED,
645                 Message("NULL pointer is specified as an exchdr address.",
646                         "例外ハンドラの番地がNULLです"));
647
648         ++ excatr, ++ exchdr;
649     }
650
651     return old_error_count == error_count;
652 }
653
654 //------------------------------------------------------
655
656 void ConfigurationChecker::parseOption(Directory & parameter)
657 {
658     string loadmodule;
659     string work;
660
661     if(findOption("h","help"))
662     {
663         cout << endl << Message(
664             "Configuration checker - option\n"
665             "  -m, --module=filename : Specify the load module (essential option)\n"
666             "  -cs, --script=filename  : Specify the checker script file\n"
667             "  -cl, --checklevel=level : Specify one of the check levels below \n"
668             "    l(azy)       : Minimum check will be performed.\n"
669             "    s(tandard)   : includes some ITRON Standard check items.\n"
670             "    t(oppers)    : checks whether it meets TOPPERS/JSP restrictions\n"
671             "    r(estricted) : All of check items will be performed.\n",
672             "コンフィギュレーションチェッカ - オプション\n"
673             "  -m, --module=ファイル名 : ロードモジュール名を指定します (必須項目)\n"
674             "  -cs, --script=ファイル名  : チェッカスクリプトを指定します\n"
675             "  -cl, --checklevel=level : Specify one of the check levels below \n"
676             "    l(azy)       : 最小限のチェックのみを行います\n"
677             "    s(tandard)   : ITRON仕様の範囲でチェックを行います\n"
678             "    t(oppers)    : TOPPERS/JSPカーネルの制限を満たすことを確認します\n"
679             "    r(estricted) : 機種依存部を含め全てのチェック項目を実施します\n");
680         cout << endl 
681              << Message("Supported architecture : ", "対応アーキテクチャ : ")
682              << FileContainer::getInstance()->getArchitecture()
683              << endl;
684         return;
685     }
686
687     if(findOption("m","module",&loadmodule) || findOption(DEFAULT_PARAMETER,NULL,&loadmodule))
688     {
689         if(findOption("s","source"))
690             ExceptionMessage("Configuration checker can not execute while Configurator executes","コンフィギュレータとチェッカは同時に起動できません").throwException();
691
692         parameter["/file/loadmodule"] = loadmodule;
693         activateComponent();
694     }
695
696     if(!findOption("cs","script",&work))
697         work = loadmodule.substr(0,loadmodule.find_last_of('.')) + ".chk";
698     parameter["/file/checkerscript"] = work;
699
700     work.erase();
701     if(findOption("obj","load-object",&work))
702     {
703         if(work.empty())
704             work.assign("kernel_obj.dat");
705
706         fstream f(work.c_str(), ios::in|ios::binary);
707         if(f.is_open())
708         {
709             parameter["/object"].Load(&f);
710             f.close();
711         }else
712             ExceptionMessage(" Failed to open the file '%' for storing object definitions"," オブジェクト情報を格納するためのファイル(%)が開けません") << work << throwException;
713     }
714
715     if(findOption("cl","checklevel",&work))
716     {
717         current_level = UNKNOWN;
718
719         if(work.compare("lazy") == 0 || work[0] == 'l')
720             current_level = LAZY;
721         if(work.compare("standard") == 0 || work[0] == 's')
722             current_level = STANDARD;
723         if(work.compare("toppers") == 0 || work[0] == 't')
724             current_level = TOPPERS;
725         if(work.compare("restricted") == 0 || work[0] == 'r')
726             current_level = RESTRICTED;
727
728         if(current_level == UNKNOWN)
729             ExceptionMessage(" Unknown check level [%] specified"," 無効なチェックレベル指定 [%]") << work << throwException;
730     }else
731         current_level = NORMAL;
732
733     checkOption("cpu", "cpu");
734     checkOption("system", "system");
735 }
736
737 void ConfigurationChecker::body(Directory & parameter)
738 {
739     FileContainer * container;
740     bool result = true;
741
742         /* より優先度の高いエラーも対象に */
743     current_level = static_cast<enum tagCheckLevel>(static_cast<int>(current_level) * 2 - 1);
744
745     container = FileContainer::getInstance();
746     container->attachInfo(parameter["/file/checkerscript"].toString());
747     container->attachModule(parameter["/file/loadmodule"].toString());
748
749     if(VerboseMessage::getVerbose())
750     {
751         cout << Message("  Target architecture : ","  ターゲットアーキテクチャ : ")
752              << container->getArchitecture() << endl;
753     }
754
755     error_count = 0;
756     result &= check_taskblock(parameter,container);
757     result &= check_semaphoreblock(parameter,container);
758     result &= check_eventflagblock(parameter,container);
759     result &= check_dataqueueblock(parameter,container);
760     result &= check_mailboxblock(parameter,container);
761     result &= check_fixed_memorypoolblock(parameter,container);
762     result &= check_cyclic_handlerblock(parameter,container);
763     result &= check_interrupt_handlerblock(parameter,container);
764     result &= check_exception_handlerblock(parameter,container);
765
766     if(!result)
767         ExceptionMessage("Total % errors found in current configuration.\n","全部で%個のエラーが検出されました\n") << error_count << throwException;
768
769     VerboseMessage("No error found in current configuration\n","構成に異常はありませんでした\n");
770 }
771