3 * Toyohashi Open Platform for Embedded Real-Time Systems/
4 * Advanced Standard Profile Kernel
6 * Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
7 * Toyohashi Univ. of Technology, JAPAN
8 * Copyright (C) 2004-2010 by Embedded and Real-Time Systems Laboratory
9 * Graduate School of Information Science, Nagoya Univ., JAPAN
11 * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
12 * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
13 * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
14 * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
15 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
17 * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
18 * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
19 * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
21 * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
22 * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
24 * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
25 * 作権表示,この利用条件および下記の無保証規定を掲載すること.
26 * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
28 * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
29 * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
30 * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
31 * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
34 * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
35 * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
36 * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
37 * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
40 * @(#) $Id: sample1.c 1797 2010-06-07 04:24:19Z ertl-hiro $
46 * ASPカーネルの基本的な動作を確認するためのサンプルプログラム.
50 * ユーザインタフェースを受け持つメインタスク(タスクID: MAIN_TASK,優
51 * 先度: MAIN_PRIORITY)と,3つの並列実行されるタスク(タスクID:
52 * TASK1〜TASK3,初期優先度: MID_PRIORITY)で構成される.また,起動周
53 * 期が2秒の周期ハンドラ(周期ハンドラID: CYCHDR1)を用いる.
55 * 並列実行されるタスクは,task_loop回空ループを実行する度に,タスクが
56 * 実行中であることをあらわすメッセージを表示する.
58 * 周期ハンドラは,三つの優先度(HIGH_PRIORITY,MID_PRIORITY,
59 * LOW_PRIORITY)のレディキューを回転させる.プログラムの起動直後は,
62 * メインタスクは,シリアルI/Oポートからの文字入力を行い(文字入力を
63 * 待っている間は,並列実行されるタスクが実行されている),入力された
64 * 文字に対応した処理を実行する.入力された文字と処理の関係は次の通り.
65 * Control-Cまたは'Q'が入力されると,プログラムを終了する.
67 * '1' : 対象タスクをTASK1に切り換える(初期設定).
68 * '2' : 対象タスクをTASK2に切り換える.
69 * '3' : 対象タスクをTASK3に切り換える.
70 * 'a' : 対象タスクをact_tskにより起動する.
71 * 'A' : 対象タスクに対する起動要求をcan_actによりキャンセルする.
72 * 'e' : 対象タスクにext_tskを呼び出させ,終了させる.
73 * 't' : 対象タスクをter_tskにより強制終了する.
74 * '>' : 対象タスクの優先度をHIGH_PRIORITYにする.
75 * '=' : 対象タスクの優先度をMID_PRIORITYにする.
76 * '<' : 対象タスクの優先度をLOW_PRIORITYにする.
77 * 'G' : 対象タスクの優先度をget_priで読み出す.
78 * 's' : 対象タスクにslp_tskを呼び出させ,起床待ちにさせる.
79 * 'S' : 対象タスクにtslp_tsk(10秒)を呼び出させ,起床待ちにさせる.
80 * 'w' : 対象タスクをwup_tskにより起床する.
81 * 'W' : 対象タスクに対する起床要求をcan_wupによりキャンセルする.
82 * 'l' : 対象タスクをrel_waiにより強制的に待ち解除にする.
83 * 'u' : 対象タスクをsus_tskにより強制待ち状態にする.
84 * 'm' : 対象タスクの強制待ち状態をrsm_tskにより解除する.
85 * 'd' : 対象タスクにdly_tsk(10秒)を呼び出させ,時間経過待ちにさせる.
86 * 'x' : 対象タスクに例外パターン0x0001の例外処理を要求する.
87 * 'X' : 対象タスクに例外パターン0x0002の例外処理を要求する.
88 * 'y' : 対象タスクにdis_texを呼び出させ,タスク例外を禁止する.
89 * 'Y' : 対象タスクにena_texを呼び出させ,タスク例外を許可する.
90 * 'r' : 3つの優先度(HIGH_PRIORITY,MID_PRIORITY,LOW_PRIORITY)のレ
92 * 'c' : 周期ハンドラを動作開始させる.
93 * 'C' : 周期ハンドラを動作停止させる.
94 * 'b' : アラームハンドラを5秒後に起動するよう動作開始させる.
95 * 'B' : アラームハンドラを動作停止させる.
96 * 'z' : 対象タスクにCPU例外を発生させる(タスクを終了させる).
97 * 'Z' : 対象タスクにCPUロック状態でCPU例外を発生させる(プログラムを
99 * 'V' : get_utmで性能評価用システム時刻を2回読む.
100 * 'v' : 発行したシステムコールを表示する(デフォルト).
101 * 'q' : 発行したシステムコールを表示しない.
105 #include <t_syslog.h>
106 #include <t_stdlib.h>
107 #include "syssvc/serial.h"
108 #include "syssvc/syslog.h"
109 #include "kernel_cfg.h"
116 svc_perror(const char *file, int_t line, const char *expr, ER ercd)
119 t_perror(LOG_ERROR, file, line, expr, ercd);
123 #define SVC_PERROR(expr) svc_perror(__FILE__, __LINE__, #expr, (expr))
126 * 並行実行されるタスクへのメッセージ領域
133 ulong_t task_loop; /* タスク内でのループ回数 */
134 ulong_t tex_loop; /* 例外処理ルーチン内でのループ回数 */
139 void task(intptr_t exinf)
143 int_t tskno = (int_t) exinf;
144 const char *graph[] = { "|", " +", " *" };
147 SVC_PERROR(ena_tex());
149 syslog(LOG_NOTICE, "task%d is running (%03d). %s",
150 tskno, ++n, graph[tskno-1]);
151 for (i = 0; i < task_loop; i++);
152 c = message[tskno-1];
153 message[tskno-1] = 0;
156 syslog(LOG_INFO, "#%d#ext_tsk()", tskno);
157 SVC_PERROR(ext_tsk());
160 syslog(LOG_INFO, "#%d#slp_tsk()", tskno);
161 SVC_PERROR(slp_tsk());
164 syslog(LOG_INFO, "#%d#tslp_tsk(10000)", tskno);
165 SVC_PERROR(tslp_tsk(10000));
168 syslog(LOG_INFO, "#%d#dly_tsk(10000)", tskno);
169 SVC_PERROR(dly_tsk(10000));
172 syslog(LOG_INFO, "#%d#dis_tex()", tskno);
173 SVC_PERROR(dis_tex());
176 syslog(LOG_INFO, "#%d#ena_tex()", tskno);
177 SVC_PERROR(ena_tex());
181 syslog(LOG_NOTICE, "#%d#raise CPU exception", tskno);
185 SVC_PERROR(loc_cpu());
186 syslog(LOG_NOTICE, "#%d#raise CPU exception", tskno);
188 SVC_PERROR(unl_cpu());
198 * 並行して実行されるタスク用のタスク例外処理ルーチン
200 void tex_routine(TEXPTN texptn, intptr_t exinf)
203 int_t tskno = (int_t) exinf;
205 syslog(LOG_NOTICE, "task%d receives exception 0x%04x.", tskno, texptn);
206 for (i = 0; i < tex_loop; i++);
208 if ((texptn & 0x8000U) != 0U) {
209 syslog(LOG_INFO, "#%d#ext_tsk()", tskno);
210 SVC_PERROR(ext_tsk());
221 cpuexc_handler(void *p_excinf)
225 syslog(LOG_NOTICE, "CPU exception handler (p_excinf = %08p).", p_excinf);
226 if (sns_ctx() != true) {
228 "sns_ctx() is not true in CPU exception handler.");
230 if (sns_dpn() != true) {
232 "sns_dpn() is not true in CPU exception handler.");
234 syslog(LOG_INFO, "sns_loc = %d sns_dsp = %d sns_tex = %d",
235 sns_loc(), sns_dsp(), sns_tex());
236 syslog(LOG_INFO, "xsns_dpn = %d xsns_xpn = %d",
237 xsns_dpn(p_excinf), xsns_xpn(p_excinf));
239 if (xsns_xpn(p_excinf)) {
240 syslog(LOG_NOTICE, "Sample program ends with exception.");
241 SVC_PERROR(ext_ker());
245 SVC_PERROR(iget_tid(&tskid));
246 SVC_PERROR(iras_tex(tskid, 0x8000U));
254 * HIGH_PRIORITY,MID_PRIORITY,LOW_PRIORITY の各優先度のレディキュー
257 void cyclic_handler(intptr_t exinf)
259 SVC_PERROR(irot_rdq(HIGH_PRIORITY));
260 SVC_PERROR(irot_rdq(MID_PRIORITY));
261 SVC_PERROR(irot_rdq(LOW_PRIORITY));
267 * HIGH_PRIORITY,MID_PRIORITY,LOW_PRIORITY の各優先度のレディキュー
270 void alarm_handler(intptr_t exinf)
272 SVC_PERROR(irot_rdq(HIGH_PRIORITY));
273 SVC_PERROR(irot_rdq(MID_PRIORITY));
274 SVC_PERROR(irot_rdq(LOW_PRIORITY));
280 void main_task(intptr_t exinf)
289 SYSTIM stime1, stime2;
290 #endif /* TASK_LOOP */
291 #ifdef TOPPERS_SUPPORT_GET_UTM
292 SYSUTM utime1, utime2;
293 #endif /* TOPPERS_SUPPORT_GET_UTM */
295 SVC_PERROR(syslog_msk_log(LOG_UPTO(LOG_INFO), LOG_UPTO(LOG_EMERG)));
296 syslog(LOG_NOTICE, "Sample program starts (exinf = %d).", (int_t) exinf);
301 * システムログタスクと同じシリアルポートを使う場合など,シリアル
302 * ポートがオープン済みの場合にはここでE_OBJエラーになるが,支障は
305 ercd = serial_opn_por(TASK_PORTID);
306 if (ercd < 0 && MERCD(ercd) != E_OBJ) {
307 syslog(LOG_ERROR, "%s (%d) reported by `serial_opn_por'.",
308 itron_strerror(ercd), SERCD(ercd));
310 SVC_PERROR(serial_ctl_por(TASK_PORTID,
311 (IOCTL_CRLF | IOCTL_FCSND | IOCTL_FCRCV)));
316 * TASK_LOOPがマクロ定義されている場合,測定せずに,TASK_LOOPに定
317 * 義された値を,タスク内でのループ回数とする.
319 * MEASURE_TWICEがマクロ定義されている場合,1回目の測定結果を捨て
320 * て,2回目の測定結果を使う.1回目の測定は長めの時間が出るため.
323 task_loop = TASK_LOOP;
324 #else /* TASK_LOOP */
327 task_loop = LOOP_REF;
328 SVC_PERROR(get_tim(&stime1));
329 for (i = 0; i < task_loop; i++);
330 SVC_PERROR(get_tim(&stime2));
331 #endif /* MEASURE_TWICE */
333 task_loop = LOOP_REF;
334 SVC_PERROR(get_tim(&stime1));
335 for (i = 0; i < task_loop; i++);
336 SVC_PERROR(get_tim(&stime2));
337 task_loop = LOOP_REF * 400UL / (stime2 - stime1);
339 #endif /* TASK_LOOP */
340 tex_loop = task_loop / 5;
345 SVC_PERROR(act_tsk(TASK1));
346 SVC_PERROR(act_tsk(TASK2));
347 SVC_PERROR(act_tsk(TASK3));
353 SVC_PERROR(serial_rea_dat(TASK_PORTID, &c, 1));
363 message[tskno-1] = c;
378 syslog(LOG_INFO, "#act_tsk(%d)", tskno);
379 SVC_PERROR(act_tsk(tskid));
382 syslog(LOG_INFO, "#can_act(%d)", tskno);
383 SVC_PERROR(ercd = can_act(tskid));
385 syslog(LOG_NOTICE, "can_act(%d) returns %d", tskno, ercd);
389 syslog(LOG_INFO, "#ter_tsk(%d)", tskno);
390 SVC_PERROR(ter_tsk(tskid));
393 syslog(LOG_INFO, "#chg_pri(%d, HIGH_PRIORITY)", tskno);
394 SVC_PERROR(chg_pri(tskid, HIGH_PRIORITY));
397 syslog(LOG_INFO, "#chg_pri(%d, MID_PRIORITY)", tskno);
398 SVC_PERROR(chg_pri(tskid, MID_PRIORITY));
401 syslog(LOG_INFO, "#chg_pri(%d, LOW_PRIORITY)", tskno);
402 SVC_PERROR(chg_pri(tskid, LOW_PRIORITY));
405 syslog(LOG_INFO, "#get_pri(%d, &tskpri)", tskno);
406 SVC_PERROR(ercd = get_pri(tskid, &tskpri));
408 syslog(LOG_NOTICE, "priority of task %d is %d", tskno, tskpri);
412 syslog(LOG_INFO, "#wup_tsk(%d)", tskno);
413 SVC_PERROR(wup_tsk(tskid));
416 syslog(LOG_INFO, "#can_wup(%d)", tskno);
417 SVC_PERROR(ercd = can_wup(tskid));
419 syslog(LOG_NOTICE, "can_wup(%d) returns %d", tskno, ercd);
423 syslog(LOG_INFO, "#rel_wai(%d)", tskno);
424 SVC_PERROR(rel_wai(tskid));
427 syslog(LOG_INFO, "#sus_tsk(%d)", tskno);
428 SVC_PERROR(sus_tsk(tskid));
431 syslog(LOG_INFO, "#rsm_tsk(%d)", tskno);
432 SVC_PERROR(rsm_tsk(tskid));
435 syslog(LOG_INFO, "#ras_tex(%d, 0x0001U)", tskno);
436 SVC_PERROR(ras_tex(tskid, 0x0001U));
439 syslog(LOG_INFO, "#ras_tex(%d, 0x0002U)", tskno);
440 SVC_PERROR(ras_tex(tskid, 0x0002U));
443 syslog(LOG_INFO, "#rot_rdq(three priorities)");
444 SVC_PERROR(rot_rdq(HIGH_PRIORITY));
445 SVC_PERROR(rot_rdq(MID_PRIORITY));
446 SVC_PERROR(rot_rdq(LOW_PRIORITY));
449 syslog(LOG_INFO, "#sta_cyc(1)");
450 SVC_PERROR(sta_cyc(CYCHDR1));
453 syslog(LOG_INFO, "#stp_cyc(1)");
454 SVC_PERROR(stp_cyc(CYCHDR1));
457 syslog(LOG_INFO, "#sta_alm(1, 5000)");
458 SVC_PERROR(sta_alm(ALMHDR1, 5000));
461 syslog(LOG_INFO, "#stp_alm(1)");
462 SVC_PERROR(stp_alm(ALMHDR1));
466 #ifdef TOPPERS_SUPPORT_GET_UTM
467 SVC_PERROR(get_utm(&utime1));
468 SVC_PERROR(get_utm(&utime2));
469 syslog(LOG_NOTICE, "utime1 = %ld, utime2 = %ld",
470 (ulong_t) utime1, (ulong_t) utime2);
471 #else /* TOPPERS_SUPPORT_GET_UTM */
472 syslog(LOG_NOTICE, "get_utm is not supported.");
473 #endif /* TOPPERS_SUPPORT_GET_UTM */
477 SVC_PERROR(syslog_msk_log(LOG_UPTO(LOG_INFO),
478 LOG_UPTO(LOG_EMERG)));
481 SVC_PERROR(syslog_msk_log(LOG_UPTO(LOG_NOTICE),
482 LOG_UPTO(LOG_EMERG)));
487 SVC_PERROR(loc_cpu());
489 extern ER bit_kernel(void);
491 SVC_PERROR(ercd = bit_kernel());
493 syslog(LOG_NOTICE, "bit_kernel passed.");
496 SVC_PERROR(unl_cpu());
498 #endif /* BIT_KERNEL */
503 } while (c != '\003' && c != 'Q');
505 syslog(LOG_NOTICE, "Sample program ends.");
506 SVC_PERROR(ext_ker());