source: azure_iot_hub_f767zi/trunk/asp_baseplatform/monitor/monitor.c@ 457

Last change on this file since 457 was 457, checked in by coas-nagasima, 4 years ago

ファイルを追加

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc;charset=UTF-8
File size: 28.1 KB
Line 
1/*
2 * TOPPERS/ASP Kernel
3 * Toyohashi Open Platform for Embedded Real-Time Systems/
4 * Advanced Standard Profile Kernel
5 *
6 * Copyright (C) 2003-2015 by Ryosuke Takeuchi
7 * GJ Business Division RICOH COMPANY,LTD. JAPAN
8 * Copyright (C) 2017-2019 by TOPPERS PROJECT Educational Working Group.
9 *
10 * 上記著作権者は,Free Software Foundation によって公表されている
11 * GNU General Public License の Version 2 に記述されている条件か,以
12 * 下の(1)~(4)の条件を満たす場合に限り,本ソフトウェア(本ソフトウェ
13 * アを改変したものを含む.以下同じ)を使用・複製・改変・再配布(以下,
14 * 利用と呼ぶ)することを無償で許諾する.
15 * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
16 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
17 * スコード中に含まれていること.
18 * (2) 本ソフトウェアを再利用可能なバイナリコード(リロケータブルオブ
19 * ジェクトファイルやライブラリなど)の形で利用する場合には,利用
20 * に伴うドキュメント(利用者マニュアルなど)に,上記の著作権表示,
21 * この利用条件および下記の無保証規定を掲載すること.
22 * (3) 本ソフトウェアを再利用不可能なバイナリコードの形または機器に組
23 * み込んだ形で利用する場合には,次のいずれかの条件を満たすこと.
24 * (a) 利用に伴うドキュメント(利用者マニュアルなど)に,上記の著作
25 * 権表示,この利用条件および下記の無保証規定を掲載すること.
26 * (b) 利用の形態を,別に定める方法によって,上記著作権者に報告する
27 * こと.
28 * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
29 * 害からも,上記著作権者を免責すること.
30 *
31 * 本ソフトウェアは,無保証で提供されているものである.上記著作権者は,
32 * 本ソフトウェアに関して,その適用可能性も含めて,いかなる保証も行わ
33 * ない.また,本ソフトウェアの利用により直接的または間接的に生じたい
34 * かなる損害に関しても,その責任を負わない.
35 *
36 * @(#) $Id$
37 */
38
39/*
40 * TOPPERS/ASP用タスクモニタプログラム.
41 *
42 */
43
44#include <kernel.h>
45#include <stdio.h>
46#include <t_syslog.h>
47#include <t_stdlib.h>
48#include <string.h>
49#include "syssvc/serial.h"
50#include "syssvc/syslog.h"
51#include "task_expansion.h"
52#include "task.h"
53#include "kernel_cfg.h"
54#include "monitor.h"
55
56#ifndef NUM_ARGC
57#define NUM_ARGC 16
58#endif
59
60/*
61 * サービスコールのエラーのログ出力
62 */
63Inline void
64svc_perror(const char *file, int_t line, const char *expr, ER ercd)
65{
66 if (ercd < 0) {
67 t_perror(LOG_ERROR, file, line, expr, ercd);
68 }
69}
70
71#define SVC_PERROR(expr) svc_perror(__FILE__, __LINE__, #expr, (expr))
72
73/*
74 * モニタ内定義
75 */
76#define HEX_VALUE 16 /* 16進指定 */
77#define DEC_VALUE 10 /* 10進指定 */
78
79#define MONDISPLAY_BYTE DATA_BYTE /* バイト単位メモリ表示 */
80#define MONDISPLAY_HALF DATA_HALF /* ハーフ単位メモリ表示 */
81#define MONDISPLAY_WORD DATA_WORD /* ワード単位メモリ表示 */
82#define MONDISPLAY_TASK 3 /* タスク状態表示 */
83#define MONDISPLAY_REG 5 /* レジスタの表示 */
84#define MONDISPLAY_ASM 6
85
86#define MONSET_BYTE DATA_BYTE /* バイト単位メモリ設定 */
87#define MONSET_HALF DATA_HALF /* ハーフ単位メモリ設定 */
88#define MONSET_WORD DATA_WORD /* ワード単位メモリ設定 */
89#define MONSET_COMMAND 3 /* コマンドモード設定 */
90#define MONSET_SERIAL 5 /* シリアル設定 */
91#define MONSET_TASK 6 /* タスク設定 */
92#define MONSET_IN 7 /* 入力設定 */
93
94struct SUBCOMMAND_TABLE {
95 const char *subcommand; /* サブコマンド文 */
96 const char type; /* 実行タイプ */
97};
98
99/*
100 * プロトタイプ宣言
101 *
102 * このモジュール内で使用している関数
103 */
104static void prompt(ID tskid);
105static int_t dispatch_command(int argc, char **argv);
106static int_t display_command(int argc, char **argv);
107static int_t set_command(int argc, char **argv);
108static int_t help_command(int argc, char **argv);
109static int_t task_activate(int argc, char **argv);
110static int_t task_terminate(int argc, char **argv);
111static int_t task_suspend(int argc, char **argv);
112static int_t task_resume(int argc, char **argv);
113static int_t task_release(int argc, char **argv);
114static int_t task_wakeup(int argc, char **argv);
115static int_t task_priority(int argc, char **argv);
116static int_t log_mode(int argc, char **argv);
117static int_t log_task(int argc, char **argv);
118static int_t log_port(int argc, char **argv);
119static uint_t get_taskstate(STAT tskstat);
120static char monitor_getstring(char *s, int *len);
121
122extern const char *itron_strerror(ER ercd);
123
124/*
125 * モニタバナー表示
126 */
127static char const banner[] = "\n"
128"ASP TASK Monitor Release %d.%d.%d for " TARGET_NAME
129" (" __DATE__ ", " __TIME__ ")\n"
130"Copyright (C) 2016-2019 by TOPPERS PROJECT Educational Working Group\n";
131
132/*
133 * ヘルプメッセージ
134 */
135static char const display_help[] =
136" Display BYTE [start address] [end address]\n"
137" HALF [start address] [end address]\n"
138" WORD [start address] [end address]\n"
139" TASK\n"
140" REGISTER\n";
141
142static char const set_help[] =
143" Set BYTE [start address]\n"
144" HALF [start address]\n"
145" WORD [start address]\n"
146" COMMAND [mode] mode=1 or (2)\n"
147" SERIAL [port id]\n"
148" TASK [task id]\n";
149
150static char const task_help[] =
151" Task ACTIVATE (act_tsk)\n"
152" TERMINATE (ter_tsk)\n"
153" SUSPEND (sus_tsk)\n"
154" RESUME (rsm_tsk)\n"
155" RELEASE (rel_tsk)\n"
156" WAKEUP (wup_tsk)\n"
157" PRIORITY [pri] (chg_pri)\n";
158
159static char const log_help[] =
160" Log MODE [logmask] [lowmask]\n"
161" TASK [cycle time(ms)] [count]\n"
162" PORT [no] [logno] [portaddress]\n";
163
164static char const help_help[] =
165" Help [arg1]\n";
166
167/*
168 * タスクコマンドサブテーブル
169 */
170static const COMMAND_INFO task_command_info[] = {
171 {"ACTIVATE", task_activate},
172 {"TERMINATE", task_terminate},
173 {"SUSPEND", task_suspend},
174 {"RESUME", task_resume},
175 {"RELEASE", task_release},
176 {"WAKEUP", task_wakeup},
177 {"PRIORITY", task_priority}
178};
179
180/*
181 * ログコマンドサブテーブル
182 */
183static const COMMAND_INFO log_command_info[] = {
184 {"MODE", log_mode},
185 {"TASK", log_task},
186 {"PORT", log_port}
187};
188
189/*
190 * メインコマンドテーブル
191 */
192static COMMAND_LINK const standard_command[] = {
193 {NULL, 0, "DISPLAY", display_command, display_help, NULL },
194 {NULL, 0, "SET", set_command, set_help, NULL },
195 {NULL, 7, "TASK", NULL, task_help, task_command_info },
196 {NULL, 3, "LOG", NULL, log_help, log_command_info },
197 {NULL, 0, "HELP", help_command, help_help, NULL }
198};
199
200/*
201 * 表示コマンドテーブル
202 */
203static struct SUBCOMMAND_TABLE const mon_display[] = {
204 {"BYTE", MONDISPLAY_BYTE }, /* バイト単位メモリ表示 */
205 {"HALF", MONDISPLAY_HALF }, /* ハーフ単位メモリ表示 */
206 {"WORD", MONDISPLAY_WORD }, /* ワード単位メモリ表示 */
207 {"TASK", MONDISPLAY_TASK }, /* タスク状態表示 */
208 {"REGISTER", MONDISPLAY_REG }, /* タスクレジスター表示 */
209 {"ASSEMBLER", MONDISPLAY_ASM } /* アセンブラー表示 */
210};
211
212/*
213 * 設定コマンドテーブル
214 */
215static struct SUBCOMMAND_TABLE const mon_set[] = {
216 {"BYTE", MONSET_BYTE }, /* バイト単位メモリ設定 */
217 {"HALF", MONSET_HALF }, /* ハーフ単位メモリ設定 */
218 {"WORD", MONSET_WORD }, /* ワード単位メモリ設定 */
219 {"COMMAND", MONSET_COMMAND }, /* コマンドモード設定 */
220 {"SERIAL", MONSET_SERIAL }, /* シリアル設定 */
221 {"TASK", MONSET_TASK }, /* タスク選択 */
222 {"IN", MONSET_IN } /* 入力設定 */
223};
224
225/*
226 * バックスペース
227 */
228static const char backspace[] = "\b \b";
229
230/*
231 * タスクモード表示テーブル
232 */
233#define TSTATE_LEN 11
234
235static char const task_state[6][TSTATE_LEN] = {
236 "RUNNING", /* 実行中 */
237 "RUNNABLE", /* 実行できる状態 */
238 "WAITING", /* 待ち状態 */
239 "SUSPENDED", /* 強制待ち状態 */
240 "WSUSPENDED", /* 二重待ち状態 */
241 "DORMANT" /* 休止状態 */
242};
243
244/*
245 * ロギングモード表示テーブル
246 */
247static char const log_mode_name[8][12] = {
248 "LOG_EMERG", /* シャットダウンに値するエラー */
249 "LOG_ALERT",
250 "LOG_CRIT",
251 "LOG_ERROR", /* システムエラー */
252 "LOG_WARNING", /* 警告メッセージ */
253 "LOG_NOTICE",
254 "LOG_INFO",
255 "LOG_DEBUG" /* デバッグ用メッセージ */
256};
257
258/*
259 * モニタで使用されるデータ領域
260 */
261static ID current_tskid; /* モニタが対象とするタスク */
262static char mon_command[MAX_COMMAND_LENGTH+1];
263static char mon_datatype; /* モニタが指定するデータタイプのデフォルト値 */
264static ulong_t mon_address; /* モニタが指定するアドレスのデフォルト値 */
265static int_t mon_mode; /* モニタが指定するコマンドモード */
266static uint_t mon_logmask; /* モニタが指定する記録/出力すべき重要度 */
267static uint_t mon_lowmask; /* モニタが指定する低レベル出力すべき重要度 */
268static ID mon_default_portid; /* モニタのデフォルトポートID */
269static FILE *mon_infile; /* モニタの入力ファイル */
270static COMMAND_LINK *pheadcmd;
271
272ID mon_portid; /* モニタのデバイスポートID */
273
274/*
275 * モニタタスク
276 */
277void monitor(intptr_t exinf)
278{
279 int no, argc, cno, len;
280 char *argv[NUM_ARGC], c;
281
282 /* モニタで使用するデータの初期化 */
283
284 mon_portid = mon_default_portid = (ID)exinf;
285 mon_datatype = DATA_BYTE;
286 mon_logmask = LOG_NOTICE;
287 mon_lowmask = LOG_EMERG;
288 current_tskid = MONTASK;
289 mon_infile = stdin;
290
291 if(mon_portid != CONSOLE_PORTID)
292 SVC_PERROR(serial_opn_por(mon_portid));
293#ifdef NEED_MONITOR
294 if(!need_monitor())
295 ext_tsk();
296#endif /* NEED_MONITOR */
297#ifndef NOINIT_STDIO_MONITOR
298 _setup_stdio(&mon_portid);
299#endif /* NOTSET_STDIO_MONITOR */
300#ifdef MONITOR_DELAY
301 dly_tsk(MONITOR_DELAY);
302#endif /* MONITOR_DELAY */
303 printf(banner,
304 (TMONITOR_PRVER >> 12) & 0x0f,
305 (TMONITOR_PRVER >> 4) & 0xff,
306 TMONITOR_PRVER & 0x0f);
307 SVC_PERROR(syslog_msk_log(LOG_UPTO(mon_logmask), LOG_UPTO(mon_lowmask)));
308 SVC_PERROR(serial_ctl_por(mon_portid, (IOCTL_CRLF | IOCTL_FCSND | IOCTL_FCRCV)));
309
310 /* モニタのメインのデスパッチ */
311
312 do{
313 prompt(current_tskid);
314 c = monitor_getstring(mon_command, &len);
315 /*
316 * 引数の設定
317 */
318 for(no = argc = cno = 0 ; argc < 16 && no < len ; no++){
319 if(test_next_char(mon_command[no])){
320 mon_command[no] = 0;
321 cno = 0;
322 }
323 else if(no < len){
324 if(cno == 0)
325 argv[argc++] = &mon_command[no];
326 cno++;
327 }
328 }
329 mon_command[no] = 0;
330
331 putecho('\n');
332 no = dispatch_command(argc, argv);
333 fflush(NULL);
334 }while(c != KEY_EXT);
335 printf("exit monitor !!\n");
336}
337
338/*
339 * モニタのプロンプトの表示
340 *
341 * 指定のタスクIDがモニタ以外の場合は
342 * タスクの状態によってプロンプトの表示内容を変更する.
343 */
344static void
345prompt(ID tskid)
346{
347 T_RTSK rtsk;
348
349 if(tskid == MONTASK)
350 printf("mon");
351 else{
352 ref_tsk(tskid, &rtsk);
353 printf("%03d(%s)", tskid, task_state[get_taskstate(rtsk.tskstat)]);
354 }
355 putchar('>');
356 fflush(NULL);
357}
358
359/*
360 * コマンドのデスパッチ
361 */
362static int_t
363dispatch_command(int argc, char **argv)
364{
365 COMMAND_LINK *pcmd = (COMMAND_LINK *)standard_command;
366 const COMMAND_INFO *pscmd;
367 int no, sno, count;
368
369 if(argc > 0){
370 count = sizeof(standard_command) / sizeof(COMMAND_LINK);
371 for(no = 0 ; no < count ; no++, pcmd++){
372 if(compare_word(pcmd->command, argv[0], mon_mode)){
373 if(pcmd->num_command == 0){
374 if(pcmd->func != NULL){
375 pcmd->func(argc-1, &argv[1]);
376 return no;
377 }
378 else
379 return -1;
380 }
381 for(sno = 0, pscmd = pcmd->pcinfo ; sno < pcmd->num_command; sno++, pscmd++){
382 if(compare_word(pscmd->command, argv[1], mon_mode)){
383 pscmd->func(argc-1, &argv[1]);
384 return sno;
385 }
386 }
387 }
388 }
389 pcmd = pheadcmd;
390 while(pcmd){
391 if(compare_word(pcmd->command, argv[0], mon_mode)){
392 for(sno = 0, pscmd = pcmd->pcinfo ; sno < pcmd->num_command; sno++, pscmd++){
393 if(compare_word(pscmd->command, argv[1], mon_mode)){
394 pscmd->func(argc-1, &argv[1]);
395 return sno;
396 }
397 }
398 }
399 pcmd = pcmd->pcnext;
400 }
401 }
402 return -1;
403}
404
405/*
406 * コマンドセットアップ
407 */
408int
409setup_command(COMMAND_LINK *pcmd)
410{
411 COMMAND_LINK *pbcmd = pheadcmd;
412
413 if(pcmd == NULL)
414 return -1;
415 pcmd->pcnext = NULL;
416 if(pbcmd == NULL){
417 pheadcmd = pcmd;
418 return 0;
419 }
420 while(pbcmd != NULL){
421 if(pbcmd == pcmd)
422 return -1;
423 else if(pbcmd->pcnext == NULL)
424 break;
425 pbcmd = pbcmd->pcnext;
426 }
427 pbcmd->pcnext = pcmd;
428 return 0;
429}
430
431/*
432 * 表示コマンド
433 */
434static int_t
435display_command(int argc, char **argv)
436{
437 char cmd=0;
438 T_RTST rtst;
439 char b;
440 uint16_t h;
441 ulong_t w, value1, value2;
442 int no, count;
443
444 count = sizeof(mon_display) / sizeof(struct SUBCOMMAND_TABLE);
445 if(argc > 0){
446 for(no = 0 ; no < count ; no++){
447 if(compare_word(mon_display[no].subcommand, argv[0], 0)){
448 cmd = mon_display[no].type;
449 break;
450 }
451 }
452 }
453 switch(cmd){
454 default: /* デフォルト */
455 cmd = mon_datatype;
456 case MONDISPLAY_BYTE: /* バイト単位メモリ表示 */
457 case MONDISPLAY_HALF: /* ハーフ単位メモリ表示 */
458 case MONDISPLAY_WORD: /* ワード単位メモリ表示 */
459 value2 = 128;
460 if(argc < 2 || !get_value(argv[1], &value1, HEX_VALUE))
461 value1 = mon_address;
462 value1 = MonAlignAddress(value1);
463 if(argc > 2){
464 if(*argv[2] == '+'){
465 if(!get_value(argv[2]+1, &value2, HEX_VALUE))
466 value2 = 128;
467 }
468 else{
469 if(!get_value(argv[2], &value2, HEX_VALUE))
470 value2 = value1 + 128;
471 value2 -= value1;
472 }
473 }
474 mon_datatype = cmd;
475 while((W)value2 > 0){
476 printf("%08lx ", (long)value1);
477 for(no = 0 ; no < 16 ; no += mon_datatype){
478 if(no == 8)
479 putchar(' ');
480 switch(mon_datatype){
481 case DATA_HALF:
482 if(MemoryRead(value1+no, (intptr_t)&h, 2) == 0)
483 h = -1;
484 printf("%04x ", h);
485 break;
486 case DATA_WORD:
487 if(MemoryRead(value1+no, (intptr_t)&w, 4) == 0)
488 w = -1;
489 printf("%08lx ", (long)w);
490 break;
491 default:
492 if(MemoryRead(value1+no, (intptr_t)&b, 1) == 0)
493 b = -1;
494 printf("%02x ", b);
495 break;
496 }
497 }
498 if(getMemoryType(value1+no, 0) == MEMORY_AREA){
499 for(no = 0 ; no < 16 ; no++){
500 if(MemoryRead(value1+no, (intptr_t)&b, 1)){
501 if(b < ' ' || b >= 0xE0)
502 b = '.';
503 else if(b >= 127 && b < 0xA0)
504 b = '.';
505 }
506 else
507 b = '.';
508 putchar(b);
509 }
510 }
511 putchar('\n');
512 value1 += 16;
513 value2 -= 16;
514 tslp_tsk(50);
515 if(monitor_break())
516 value2 = 0;
517 }
518 mon_address = value1;
519 break;
520 case MONDISPLAY_TASK: /* タスク状態表示 */
521 printf("cur id pri state pc stack inistack inisize\n");
522 for(no = 0 ; no < tmax_tskid ; no++){
523 ref_tst(no+TMIN_TSKID, &rtst);
524 if(current_tskid == (no+TMIN_TSKID))
525 printf(" * ");
526 else
527 printf(" ");
528 if(MONTASK == (no+TMIN_TSKID))
529 printf(" mon");
530 else
531 printf(" %03d", no+TMIN_TSKID);
532 printf(" %3d ", rtst.tskpri);
533 value1 = get_taskstate(rtst.tskstat);
534 for(count = 0 ; count < TSTATE_LEN-1 ; count++){
535 if(task_state[value1][count] == 0)
536 putchar(' ');
537 else
538 putchar(task_state[value1][count]);
539 }
540 if(rtst.tskstat == TTS_RUN)
541 printf(" ");
542 else
543 printf(" %08lx", (unsigned long)rtst.tskpc);
544 printf(" %08lx %08lx %5ld\n", (unsigned long)rtst.tsksp, (unsigned long)rtst.inistk, (unsigned long)rtst.inistksz);
545 }
546 putchar('\n');
547 break;
548 case MONDISPLAY_REG: /* レジスタの表示 */
549 if(current_tskid != MONTASK)
550 display_registers(current_tskid);
551 break;
552 }
553 return 0;
554}
555
556/*
557 * 設定コマンド
558 */
559static int_t
560set_command(int argc, char **argv)
561{
562 char cmd=0;
563 char b;
564 uint16_t h;
565 ulong_t w, value1, value2;
566 int no, count;
567 bool_t cont;
568
569 count = sizeof(mon_set) / sizeof(struct SUBCOMMAND_TABLE);
570 if(argc > 0){
571 for(no = 0 ; no < count ; no++){
572 if(compare_word(mon_set[no].subcommand, argv[0], 0)){
573 cmd = mon_set[no].type;
574 break;
575 }
576 }
577 }
578 switch(cmd){
579 default: /* デフォルト */
580 cmd = mon_datatype;
581 case MONSET_BYTE: /* バイト単位メモリ設定 */
582 case MONSET_HALF: /* ハーフ単位メモリ設定 */
583 case MONSET_WORD: /* ワード単位メモリ設定 */
584 if(argc < 2 || !get_value(argv[1], &value1, HEX_VALUE))
585 value1 = mon_address;
586 value1 = MonAlignAddress(value1);
587 mon_datatype = cmd;
588 do{
589 printf(" %08lx", (unsigned long)value1);
590 switch(mon_datatype){
591 case DATA_HALF:
592 if(MemoryRead(value1, (intptr_t)&h, 2) == 0)
593 h = -1;
594 printf(" %04x =", h);
595 break;
596 case DATA_WORD:
597 if(MemoryRead(value1, (intptr_t)&w, 4) == 0)
598 w = -1;
599 printf(" %08lx =", (unsigned long)w);
600 break;
601 default:
602 if(MemoryRead(value1, (intptr_t)&b, 1) == 0)
603 b = -1;
604 printf(" %02x =", b);
605 break;
606 }
607 monitor_getstring(mon_command, &count);
608 if(get_value(mon_command, &value2, HEX_VALUE)){
609 switch(mon_datatype){
610 case DATA_HALF:
611 h = value2;
612 MemoryWrite(value1, (intptr_t)&h, 2);
613 if(MemoryRead(value1, (intptr_t)&h, 2) == 0)
614 h = -1;
615 printf(" %04x\n", h);
616 break;
617 case DATA_WORD:
618 w = value2;
619 MemoryWrite(value1, (intptr_t)&w, 4);
620 if(MemoryRead(value1, (intptr_t)&w, 4) == 0)
621 w = -1;
622 printf(" %08lx\n", (unsigned long)w);
623 break;
624 default:
625 b = value2;
626 MemoryWrite(value1, (intptr_t)&b, 1);
627 if(MemoryRead(value1, (intptr_t)&b, 1) == 0)
628 b = -1;
629 printf(" %02x\n", b);
630 break;
631 }
632 value1 += mon_datatype;
633 cont = true;
634 }
635 else
636 cont = false;
637 }while(cont);
638 putchar('\n');
639 mon_address = value1;
640 break;
641 case MONSET_COMMAND: /* コマンドモード設定 */
642 if(argc > 1 && get_value(argv[1], &value1, DEC_VALUE)){
643 if(value1 == 1 || value1 == 2){
644 printf(" set %d command(s) mode !\n", (int)value1);
645 mon_mode = value1;
646 }
647 }
648 printf(" set command mode=%d word(s) !\n", mon_mode);
649 break;
650 case MONSET_SERIAL: /* シリアル設定 */
651 if(argc > 1 && get_value(argv[1], &value1, DEC_VALUE)){
652 if(value1 > 0 && mon_portid != value1){
653 if(mon_portid != mon_default_portid && mon_portid != CONSOLE_PORTID)
654 SVC_PERROR(serial_cls_por(mon_portid));
655 mon_portid = value1;
656 if(mon_portid != mon_default_portid && mon_portid != CONSOLE_PORTID)
657 SVC_PERROR(serial_opn_por(mon_portid));
658 SVC_PERROR(serial_ctl_por(mon_portid, (IOCTL_CRLF | IOCTL_FCSND | IOCTL_FCRCV)));
659 printf(banner,
660 (TMONITOR_PRVER >> 12) & 0x0f,
661 (TMONITOR_PRVER >> 4) & 0xff,
662 TMONITOR_PRVER & 0x0f);
663 }
664 }
665 printf(" set serial port id=%d !\n", mon_portid);
666 break;
667 case MONSET_TASK: /* タスク選択 */
668 if(argc > 1 && get_value(argv[1], &value1, DEC_VALUE)){
669 if(value1 >= TMIN_TSKID && value1 < (TMIN_TSKID+tmax_tskid))
670 current_tskid = value1;
671 else
672 current_tskid = MONTASK;
673 }
674 else
675 current_tskid = MONTASK;
676 break;
677 case MONSET_IN: /* 入力設定 */
678 value1 = 0;
679 if(argc > 1)
680 get_value(argv[1], &value1, DEC_VALUE);
681 if(value1 == 1)
682 mon_infile = stdout;
683 else if(value1 == 2)
684 mon_infile = stderr;
685 else
686 mon_infile = stdin;
687 break;
688 }
689 return 0;
690}
691
692/*
693 * ヘルプコマンド
694 */
695static int_t
696help_command(int argc, char **argv)
697{
698 COMMAND_LINK *pcmd = (COMMAND_LINK *)standard_command;
699 int no, count;
700
701 count = sizeof(standard_command) / sizeof(COMMAND_LINK);
702 for(no = 0 ; no < count ; no++, pcmd++){
703 if(argc > 0){
704 if(compare_word(pcmd->command, argv[0], 0)){
705 printf(pcmd->help);
706 return no;
707 }
708 }
709 else
710 printf(pcmd->help);
711 }
712 pcmd = pheadcmd;
713 while(pcmd){
714 if(argc > 0){
715 if(compare_word(pcmd->command, argv[0], 0)){
716 printf(pcmd->help);
717 return no;
718 }
719 }
720 else
721 printf(pcmd->help);
722 pcmd = pcmd->pcnext;
723 }
724 return 0;
725}
726
727/*
728 * タスクコマンド、起動要求(act_tsk)
729 */
730static int_t
731task_activate(int argc, char **argv)
732{
733 ER ercd = E_OK;
734
735 if(current_tskid == MONTASK){ /* モニタ自体の制御はできない */
736 printf(" Can't control the monitor!!\n");
737 return 0;
738 }
739 ercd = act_tsk(current_tskid);
740 printf(" execute act_tsk(%d) :: result = %s !\n", current_tskid, itron_strerror(ercd));
741 tslp_tsk(100); /* スイッチング */
742 return 0;
743}
744
745/*
746 * タスクコマンド、強制終了(ter_tsk)
747 */
748static int_t
749task_terminate(int argc, char **argv)
750{
751 ER ercd = E_OK;
752
753 if(current_tskid == MONTASK){ /* モニタ自体の制御はできない */
754 printf(" Can't control the monitor!!\n");
755 return 0;
756 }
757 ercd = ter_tsk(current_tskid);
758 printf(" execute ter_tsk(%d) :: result = %s !\n", current_tskid, itron_strerror(ercd));
759 tslp_tsk(100); /* スイッチング */
760 return 0;
761}
762
763/*
764 * タスクコマンド、待ち要求(sus_tsk)
765 */
766static int_t
767task_suspend(int argc, char **argv)
768{
769 ER ercd = E_OK;
770
771 if(current_tskid == MONTASK){ /* モニタ自体の制御はできない */
772 printf(" Can't control the monitor!!\n");
773 return 0;
774 }
775 ercd = sus_tsk(current_tskid);
776 printf(" execute sus_tsk(%d) :: result = %s !\n", current_tskid, itron_strerror(ercd));
777 tslp_tsk(100); /* スイッチング */
778 return 0;
779}
780
781/*
782 * タスクコマンド、待ち再開(rsm_tsk)
783 */
784static int_t
785task_resume(int argc, char **argv)
786{
787 ER ercd = E_OK;
788
789 if(current_tskid == MONTASK){ /* モニタ自体の制御はできない */
790 printf(" Can't control the monitor!!\n");
791 return 0;
792 }
793 ercd = rsm_tsk(current_tskid);
794 printf(" execute rsm_tsk(%d) :: result = %s !\n", current_tskid, itron_strerror(ercd));
795 tslp_tsk(100); /* スイッチング */
796 return 0;
797}
798
799/*
800 * タスクコマンド、待ち解除(rel_wai)
801 */
802static int_t
803task_release(int argc, char **argv)
804{
805 ER ercd = E_OK;
806
807 if(current_tskid == MONTASK){ /* モニタ自体の制御はできない */
808 printf(" Can't control the monitor!!\n");
809 return 0;
810 }
811 ercd = rel_wai(current_tskid);
812 printf(" execute rel_wai(%d) :: result = %s !\n", current_tskid, itron_strerror(ercd));
813 tslp_tsk(100); /* スイッチング */
814 return 0;
815}
816
817/*
818 * タスクコマンド、タスク起床(wup_tsk)
819 */
820static int_t
821task_wakeup(int argc, char **argv)
822{
823 ER ercd = E_OK;
824
825 if(current_tskid == MONTASK){ /* モニタ自体の制御はできない */
826 printf(" Can't control the monitor!!\n");
827 return 0;
828 }
829 ercd = wup_tsk(current_tskid);
830 printf(" execute wup_tsk(%d) :: result = %s !\n", current_tskid, itron_strerror(ercd));
831 tslp_tsk(100); /* スイッチング */
832 return 0;
833}
834
835/*
836 * タスクコマンド、優先度変更(chg_pri)
837 */
838static int_t
839task_priority(int argc, char **argv)
840{
841 ER ercd = E_OK;
842 ulong_t w;
843
844 if(current_tskid == MONTASK){ /* モニタ自体の制御はできない */
845 printf(" Can't control the monitor!!\n");
846 return 0;
847 }
848 if(argc > 1 && get_value(argv[1], &w, DEC_VALUE)){
849 ercd = chg_pri(current_tskid, w);
850 printf(" execute chg_pri(%d, %d) :: result = %s !\n", current_tskid, (int)w, itron_strerror(ercd));
851 tslp_tsk(100); /* スイッチング */
852 return 0;
853 }
854 return -1;
855}
856
857/*
858 * ログコマンド、ロギングモード設定
859 */
860static int_t
861log_mode(int argc, char **argv)
862{
863 ulong_t value1, value2;
864
865 if(argc < 2 || !get_value(argv[1], &value1, DEC_VALUE))
866 value1 = mon_logmask;
867 if(argc < 3 || !get_value(argv[2], &value2, DEC_VALUE))
868 value2 = mon_lowmask;
869 if(value1 <= LOG_DEBUG)
870 mon_logmask = value1;
871 if(value2 <= LOG_DEBUG)
872 mon_lowmask = value2;
873 syslog_msk_log(LOG_UPTO(mon_logmask), LOG_UPTO(mon_lowmask));
874 printf(" set logmask=%s lowmask=%s !\n", log_mode_name[mon_logmask], log_mode_name[mon_lowmask]);
875 return 0;
876}
877
878/*
879 * ログコマンド、タスクモニタ設定
880 */
881static int_t
882log_task(int argc, char **argv)
883{
884 T_TPRM loglist;
885 ulong_t value1, value2, value3 = 0;
886 ulong_t tcount, ttime;
887 ulong_t sno = MONTASK;
888 ulong_t xno = MONTASK+NUM_LOG_DISP;
889 int no, count;
890
891 if(argc < 2 || !get_value(argv[1], &value1, DEC_VALUE))
892 value1 = 0;
893 else if(argc < 3 || !get_value(argv[2], &value3, DEC_VALUE))
894 value3 = 0;
895 if(value1 < 100)
896 value1 = 0;
897 value2 = 0;
898 do{
899 count = get_tsklog(&loglist);
900 if(value2 == 0){ /* はじめの1回 */
901 value2 =loglist.currtime;
902 if(xno > count){
903 int i = xno - count;
904 if(i > MONTASK)
905 i = MONTASK;
906 sno -= xno - count;
907 xno -= xno - count;
908 }
909 printf("-- time --");
910 for(no = 1 ; no <= xno ; no++){
911 if(no > sno)
912 printf(" --id=%04u --", no);
913 }
914 printf(" -- others -- -vacancy-\n");
915 }
916 value2 += value1;
917 if(value1 == 0)
918 printf("%010lu\n", (unsigned long)loglist.pervtime);
919 printf("%010lu", (unsigned long)loglist.currtime);
920 tcount = ttime = 0;
921 for(no = 1 ; no <= count ; no++){
922 if(no > sno && no <= xno){
923 printf(" %04u %05lu.%01u", loglist.tlog[no].runcount, (unsigned long)(loglist.tlog[no].runtimes/10),
924 (int)(loglist.tlog[no].runtimes%10));
925 }
926 else{
927 tcount += loglist.tlog[no].runcount;
928 ttime += loglist.tlog[no].runtimes;
929 }
930 }
931 printf(" %04u %05lu.%01u", (int)tcount, (unsigned long)(ttime/10), (int)(ttime%10));
932 printf(" %07lu.%01u\n", (unsigned long)(loglist.tlog[0].runtimes/10), (int)(loglist.tlog[0].runtimes%10));
933 if(value1){
934 tslp_tsk(value2 - loglist.currtime);
935 if(monitor_break())
936 value1 = 0;
937 }
938 value3--;
939 }while(value1 && value3 != 0);
940 return 0;
941}
942
943/*
944 * ログコマンド、ポートモニタ設定
945 */
946static int_t
947log_port(int argc, char **argv)
948{
949 T_PCHK *p;
950 ulong_t type, address;
951 ulong_t value1, value2;
952
953 value2 = NUM_PCHK-1;
954 if(argc > 1 && get_value(argv[1], &value1, DEC_VALUE)){
955 if((p = get_device_log(value1)) != 0){
956 value2 = value1;
957 if(argc < 3 || !get_value(argv[2], &type, DEC_VALUE)){
958 type = p->logtype;
959 }
960 if(type >= LOG_DEBUG)
961 type = 0;
962 p->logtype = type;
963 if(argc < 4 || !get_value(argv[4], &address, HEX_VALUE)){
964 address = p->portaddress;
965 }
966 p->portaddress = address;
967 }
968 }
969 else
970 value1 = 0;
971 while(value1 <= value2){
972 if((p = get_device_log(value1)) != 0){
973 if(p->logtype > 0)
974 printf(" %02d %s port=%08lx\n", (int)value1, log_mode_name[p->logtype], (unsigned long)p->portaddress);
975 else
976 printf(" %02d OFF port=%08lx\n", (int)value1, (unsigned long)p->portaddress);
977 }
978 else
979 break;
980 value1++;
981 }
982 return 0;
983}
984
985
986/*
987 * キャラクタの比較
988 */
989bool_t
990compare_word(const char *s, char *d, int_t mode)
991{
992 char c1, c2;
993
994 if(*d == 0)
995 return false;
996 while(*s != 0 && *d != 0 && *d != ' ' && *d != ','){
997 c2 = *d++;
998 if(c2 >= 'a' && c2 <= 'z')
999 c2 -= 0x20;
1000 c1 = *s++;
1001 if(c1 >= 'a' && c1 <= 'z')
1002 c1 -= 0x20;
1003 if(c1 != c2)
1004 return false;
1005 if(mode == 1)
1006 break;
1007 }
1008 return true;
1009}
1010
1011/*
1012 * タスク状態番号を取り出す
1013 */
1014static uint_t
1015get_taskstate(STAT tskstat)
1016{
1017 uint_t no;
1018
1019 if(tskstat == TTS_RUN)
1020 no = 0;
1021 else if(tskstat == TTS_RDY)
1022 no = 1;
1023 else if(tskstat == TTS_WAI)
1024 no = 2;
1025 else if(tskstat == TTS_SUS)
1026 no = 3;
1027 else if(tskstat == TTS_DMT)
1028 no = 5;
1029 else
1030 no = 4;
1031 return no;
1032}
1033
1034/*
1035 * モニタのコマンド読み込み文
1036 */
1037char
1038monitor_getstring(char *s, int *len)
1039{
1040 char c;
1041 int no = 0;
1042
1043 *len = 0;
1044 do{
1045 c = getc(mon_infile);
1046 if(c >= ' ' && no < MAX_COMMAND_LENGTH){
1047 putecho((int)c);
1048 s[no++] = c;
1049 }
1050 else if((c == KEY_BS || c == KEY_DEL) && no > 0){
1051 printecho(backspace);
1052 no--;
1053 }
1054 }while(c != KEY_NL && c != KEY_CR && c != KEY_EXT);
1055 s[no] = 0;
1056 *len = no;
1057 return c;
1058}
1059
1060/*
1061 * モニタコマンドブレークの判定
1062 */
1063bool_t
1064monitor_break(void)
1065{
1066 T_SERIAL_RPOR k_rpor;
1067
1068 if(mon_infile != stdin)
1069 return false;
1070 serial_ref_por(mon_portid, &k_rpor);
1071 if(k_rpor.reacnt > 0){
1072 getc(mon_infile);
1073 return true;
1074 }
1075 else
1076 return false;
1077}
1078
1079/*
1080 * モニタ入力ファイルの切り替え
1081 */
1082void *
1083monitor_infile(void *file)
1084{
1085 void *ofile = mon_infile;
1086
1087 if(file != NULL)
1088 mon_infile = file;
1089 return ofile;
1090}
1091
Note: See TracBrowser for help on using the repository browser.