OSDN Git Service

最初のコミット。sample1が通る。
[uzume/uzume_bfin.git] / uzume_prototype / kernel / sample / cxx_sample1.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  *  Copyright (C) 2003-2004 Takagi Nobuhisa
9  * 
10  *  上記著作権者は,以下の (1)〜(4) の条件か,Free Software Foundation 
11  *  によって公表されている GNU General Public License の Version 2 に記
12  *  述されている条件を満たす場合に限り,本ソフトウェア(本ソフトウェア
13  *  を改変したものを含む.以下同じ)を使用・複製・改変・再配布(以下,
14  *  利用と呼ぶ)することを無償で許諾する.
15  *  (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
16  *      権表示,この利用条件および下記の無保証規定が,そのままの形でソー
17  *      スコード中に含まれていること.
18  *  (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
19  *      用できる形で再配布する場合には,再配布に伴うドキュメント(利用
20  *      者マニュアルなど)に,上記の著作権表示,この利用条件および下記
21  *      の無保証規定を掲載すること.
22  *  (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
23  *      用できない形で再配布する場合には,次のいずれかの条件を満たすこ
24  *      と.
25  *    (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
26  *        作権表示,この利用条件および下記の無保証規定を掲載すること.
27  *    (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
28  *        報告すること.
29  *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
30  *      害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
31  * 
32  *  本ソフトウェアは,無保証で提供されているものである.上記著作権者お
33  *  よびTOPPERSプロジェクトは,本ソフトウェアに関して,その適用可能性も
34  *  含めて,いかなる保証も行わない.また,本ソフトウェアの利用により直
35  *  接的または間接的に生じたいかなる損害に関しても,その責任を負わない.
36  * 
37  *  @(#) $Id: cxx_sample1.cpp,v 1.1 2009/01/31 05:27:37 suikan Exp $
38  */
39
40 /* 
41  *  C++サンプルプログラム(1)の本体
42  *
43  *  JSPカーネルの基本的な動作を確認するためのサンプルプログラム.
44  *
45  *  プログラムの概要:
46  *
47  *  ユーザインタフェースを受け持つメインタスク(タスクID: MAIN_TASK,
48  *  優先度: MAIN_PRIORITY)と,三つの並列実行されるタスク(タスクID:
49  *  TASK1〜TASK3,初期優先度: MID_PRIORITY)で構成される.また,起動周
50  *  期が2秒の周期ハンドラ(周期ハンドラID: CYCHDR1)を用いる.
51  *
52  *  並列実行されるタスクは,task_loop 回空ループを実行する度に,タスク
53  *  が実行中であることをあらわすメッセージを表示する.
54  *
55  *  周期ハンドラは,三つの優先度(HIGH_PRIORITY,MID_PRIORITY,
56  *  LOW_PRIORITY)のレディキューを回転させる.プログラムの起動直後は,
57  *  周期ハンドラは停止状態になっている.
58  *
59  *  メインタスクは,シリアルI/Oポートからの文字入力を行い(文字入力を
60  *  待っている間は,並列実行されるタスクが実行されている),入力された
61  *  文字に対応した処理を実行する.入力された文字と処理の関係は次の通り.
62  *  Control-C または 'Q' が入力されると,プログラムを終了する.
63  *
64  *  '1' : 以降のコマンドは TASK1 に対して行う.
65  *  '2' : 以降のコマンドは TASK2 に対して行う.
66  *  '3' : 以降のコマンドは TASK3 に対して行う.
67  *  'a' : タスクを act_tsk により起動する.
68  *  'A' : タスクに対する起動要求を can_act によりキャンセルする.
69  *  'e' : タスクに ext_tsk を呼び出させ,終了させる.
70  *  't' : タスクを ter_tsk により強制終了する.
71  *  '>' : タスクの優先度を HIGH_PRIORITY にする.
72  *  '=' : タスクの優先度を MID_PRIORITY にする.
73  *  '<' : タスクの優先度を LOW_PRIORITY にする.
74  *  'G' : タスクの優先度を get_pri で読み出す.
75  *  's' : タスクに slp_tsk を呼び出させ,起床待ちにさせる.
76  *  'S' : タスクに tslp_tsk(10秒) を呼び出させ,起床待ちにさせる.
77  *  'w' : タスクを wup_tsk により起床する.
78  *  'W' : タスクに対する起床要求を can_wup によりキャンセルする.
79  *  'l' : タスクを rel_wai により強制的に待ち解除にする.
80  *  'u' : タスクを sus_tsk により強制待ち状態にする.
81  *  'm' : タスクの強制待ち状態を rsm_tsk により解除する.
82  *  'M' : タスクの強制待ち状態を frsm_tsk により強制解除する.
83  *  'd' : タスクに dly_tsk(10秒) を呼び出させ,時間経過待ちにさせる.
84  *  'x' : タスクにパターン 0x0001 の例外処理を要求する.
85  *  'X' : タスクにパターン 0x0002 の例外処理を要求する.
86  *  'y' : タスクに dis_tex を呼び出させ,タスク例外を禁止する.
87  *  'Y' : タスクに ena_tex を呼び出させ,タスク例外を許可する.
88  *  'r' : 三つの優先度(HIGH_PRIORITY,MID_PRIORITY,LOW_PRIORITY)の
89  *        レディキューを回転させる.
90  *  'c' : 周期ハンドラを動作させる.
91  *  'C' : 周期ハンドラを停止させる.
92  *  'z' : CPU例外を発生させる.
93  *  'Z' : CPUロック状態でCPU例外を発生させる(プログラムを終了する).
94  *  'V' : vxget_tim で性能評価用システム時刻を2回読む.
95  *  'v' : 発行したシステムコールを表示する(デフォルト).
96  *  'q' : 発行したシステムコールを表示しない.
97  */
98
99 #include <t_services.h>
100 #include "kernel_id.h"
101 #include "cxx_sample1.h"
102
103 /*
104  *  並行実行されるタスクへのメッセージ領域
105  */
106 char    message[3];
107
108 /*
109  *  ループ回数
110  */
111 UW  task_loop;      /* タスク内でのループ回数 */
112 UW  tex_loop;       /* 例外処理ルーチン内でのループ回数 */
113
114 /*
115  *  並行実行されるタスク
116  */
117 void task(VP_INT exinf)
118 {
119     _toppers_cxxrt_reset_specific();
120
121     volatile UW i;
122     INT n = 0;
123     INT tskno = (INT) exinf;
124     char    *graph[] = { "|", "  +", "    *" };
125     char    c;
126
127     ena_tex();
128     while (1) {
129         syslog(LOG_NOTICE, "task%d is running (%03d).   %s",
130                     tskno, ++n, graph[tskno-1]);
131         for (i = 0; i < task_loop; i++);
132         c = message[tskno-1];
133         message[tskno-1] = 0;
134         switch (c) {
135         case 'e':
136             syslog(LOG_INFO, "#%d#ext_tsk()", tskno);
137             ext_tsk();
138         case 's':
139             syslog(LOG_INFO, "#%d#slp_tsk()", tskno);
140             syscall(slp_tsk());
141             break;
142         case 'S':
143             syslog(LOG_INFO, "#%d#tslp_tsk(10000)", tskno);
144             syscall(tslp_tsk(10000));
145             break;
146         case 'd':
147             syslog(LOG_INFO, "#%d#dly_tsk(10000)", tskno);
148             syscall(dly_tsk(10000));
149             break;
150         case 'y':
151             syslog(LOG_INFO, "#%d#dis_tex()", tskno);
152             syscall(dis_tex());
153             break;
154         case 'Y':
155             syslog(LOG_INFO, "#%d#ena_tex()", tskno);
156             syscall(ena_tex());
157             break;
158 #ifdef CPUEXC1
159         case 'z':
160             syslog(LOG_NOTICE, "#%d#raise CPU exception", tskno);
161             RAISE_CPU_EXCEPTION;
162             break;
163         case 'Z':
164             loc_cpu();
165             syslog(LOG_NOTICE, "#%d#raise CPU exception", tskno);
166             RAISE_CPU_EXCEPTION;
167             unl_cpu();
168             break;
169 #endif /* CPUEXC1 */
170         default:
171             break;
172         }
173     }
174 }
175
176 /*
177  *  並行して実行されるタスク用のタスク例外処理ルーチン
178  */
179 void tex_routine(TEXPTN texptn, VP_INT exinf)
180 {
181     volatile UW i;
182     INT tskno = (INT) exinf;
183
184     syslog(LOG_NOTICE, "task%d receives exception 0x%04x. ",
185                     tskno, texptn);
186     for (i = 0; i < tex_loop; i++);
187
188     if (texptn & 0x8000) {
189         syslog(LOG_INFO, "#%d#ext_tsk()", tskno);
190         ext_tsk();
191     }
192 }
193
194 /*
195  *  CPU例外ハンドラ
196  */
197 #ifdef CPUEXC1
198
199 void
200 cpuexc_handler(VP p_excinf)
201 {
202     ID  tskid;
203
204     syslog(LOG_NOTICE, "CPU exception handler (p_excinf = %08p).",
205                             p_excinf);
206     if (sns_ctx() != TRUE) {
207         syslog(LOG_WARNING,
208             "sns_ctx() is not TRUE in CPU exception handler.");
209     }
210     if (sns_dpn() != TRUE) {
211         syslog(LOG_WARNING,
212             "sns_dpn() is not TRUE in CPU exception handler.");
213     }
214     syslog(LOG_DEBUG,
215         "sns_loc = %d sns_dsp = %d", sns_loc(), sns_dsp());
216     syslog(LOG_DEBUG,
217         "vxsns_loc = %d vxsns_ctx = %d vxsns_dsp = %d vxsns_dpn = %d",
218         vxsns_loc(p_excinf), vxsns_ctx(p_excinf),
219         vxsns_dsp(p_excinf), vxsns_dpn(p_excinf));
220
221     if (!vxsns_loc(p_excinf) && !vxsns_ctx(p_excinf)) {
222         syscall(iget_tid(&tskid));
223         syscall(iras_tex(tskid, 0x8000));
224     }
225     else {
226         syslog(LOG_NOTICE, "Sample program ends with exception.");
227         kernel_exit();
228     }
229 }
230
231 #endif /* CPUEXC1 */
232
233 /*
234  *  周期ハンドラ
235  *
236  *  HIGH_PRIORITY,MID_PRIORITY,LOW_PRIORITY の各優先度のレディキュー
237  *  を回転させる.
238  */
239 void cyclic_handler(VP_INT exinf)
240 {
241     irot_rdq(HIGH_PRIORITY);
242     irot_rdq(MID_PRIORITY);
243     irot_rdq(LOW_PRIORITY);
244 }
245
246 /*
247  *  メインタスク
248  */
249 void main_task(VP_INT exinf)
250 {
251     char    c;
252     ID  tskid = TASK1;
253     volatile UW i;
254     INT tskno = 1;
255     ER_UINT ercd;   
256     PRI tskpri;
257     SYSTIM  stime1, stime2;
258 #ifndef OMIT_VGET_TIM
259     SYSUTIM utime1, utime2;
260 #endif /* OMIT_VGET_TIM */
261
262     vmsk_log(LOG_UPTO(LOG_INFO), LOG_UPTO(LOG_EMERG));
263     syslog(LOG_NOTICE, "Sample program starts (exinf = %d).", exinf);
264
265     syscall(serial_ctl_por(TASK_PORTID,
266             (IOCTL_CRLF | IOCTL_FCSND | IOCTL_FCRCV)));
267
268     /*
269      *  ループ回数の設定
270      */
271     task_loop = LOOP_REF;
272     get_tim(&stime1);
273     for (i = 0; i < task_loop; i++);
274     get_tim(&stime2);
275     task_loop = LOOP_REF * 400 / (stime2 - stime1);
276     tex_loop = task_loop / 5;
277
278     /*
279      *  タスクの起動
280      */
281     act_tsk(TASK1);
282     act_tsk(TASK2);
283     act_tsk(TASK3);
284
285     /*
286      *  メインループ
287      */
288     do {
289         syscall(serial_rea_dat(TASK_PORTID, &c, 1));
290         switch (c) {
291         case 'e':
292         case 's':
293         case 'S':
294         case 'd':
295         case 'y':
296         case 'Y':
297         case 'z':
298         case 'Z':
299             message[tskno-1] = c;
300             break;
301         case '1':
302             tskno = 1;
303             tskid = TASK1;
304             break;
305         case '2':
306             tskno = 2;
307             tskid = TASK2;
308             break;
309         case '3':
310             tskno = 3;
311             tskid = TASK3;
312             break;
313         case 'a':
314             syslog(LOG_INFO, "#act_tsk(%d)", tskno);
315             syscall(act_tsk(tskid));
316             break;
317         case 'A':
318             syslog(LOG_INFO, "#can_act(%d)", tskno);
319             syscall(ercd = can_act(tskid));
320             if (ercd >= 0) {
321                 syslog(LOG_NOTICE, "can_act(%d) returns %d",
322                         tskno, ercd);
323             }
324             break;
325         case 't':
326             syslog(LOG_INFO, "#ter_tsk(%d)", tskno);
327             syscall(ter_tsk(tskid));
328             break;
329         case '>':
330             syslog(LOG_INFO, "#chg_pri(%d, HIGH_PRIORITY)", tskno);
331             chg_pri(tskid, HIGH_PRIORITY);
332             break;
333         case '=':
334             syslog(LOG_INFO, "#chg_pri(%d, MID_PRIORITY)", tskno);
335             chg_pri(tskid, MID_PRIORITY);
336             break;
337         case '<':
338             syslog(LOG_INFO, "#chg_pri(%d, LOW_PRIORITY)", tskno);
339             chg_pri(tskid, LOW_PRIORITY);
340             break;
341         case 'G':
342             syslog(LOG_INFO, "#get_pri(%d, &tskpri)", tskno);
343             syscall(ercd = get_pri(tskid, &tskpri));
344             if (ercd >= 0) {
345                 syslog(LOG_NOTICE, "priority of task %d is %d",
346                         tskno, tskpri);
347             }
348             break;
349         case 'w':
350             syslog(LOG_INFO, "#wup_tsk(%d)", tskno);
351             syscall(wup_tsk(tskid));
352             break;
353         case 'W':
354             syslog(LOG_INFO, "#can_wup(%d)", tskno);
355             syscall(ercd = can_wup(tskid));
356             if (ercd >= 0) {
357                 syslog(LOG_NOTICE, "can_wup(%d) returns %d",
358                         tskno, ercd);
359             }
360             break;
361         case 'l':
362             syslog(LOG_INFO, "#rel_wai(%d)", tskno);
363             syscall(rel_wai(tskid));
364             break;
365         case 'u':
366             syslog(LOG_INFO, "#sus_tsk(%d)", tskno);
367             syscall(sus_tsk(tskid));
368             break;
369         case 'm':
370             syslog(LOG_INFO, "#rsm_tsk(%d)", tskno);
371             syscall(rsm_tsk(tskid));
372             break;
373         case 'M':
374             syslog(LOG_INFO, "#frsm_tsk(%d)", tskno);
375             syscall(frsm_tsk(tskid));
376             break;
377         case 'x':
378             syslog(LOG_INFO, "#ras_tex(%d, 0x0001)", tskno);
379             syscall(ras_tex(tskid, 0x0001));
380             break;
381         case 'X':
382             syslog(LOG_INFO, "#ras_tex(%d, 0x0002)", tskno);
383             syscall(ras_tex(tskid, 0x0002));
384             break;
385         case 'r':
386             syslog(LOG_INFO, "#rot_rdq(three priorities)");
387             rot_rdq(HIGH_PRIORITY);
388             rot_rdq(MID_PRIORITY);
389             rot_rdq(LOW_PRIORITY);
390             break;
391         case 'c':
392             sta_cyc(CYCHDR1);
393             break;
394         case 'C':
395             stp_cyc(CYCHDR1);
396             break;
397 #ifndef OMIT_VGET_TIM
398         case 'V':
399             syscall(vxget_tim(&utime1));
400             syscall(vxget_tim(&utime2));
401             syslog(LOG_NOTICE, "utime1 = %d, utime2 = %d",
402                         (UINT) utime1, (UINT) utime2);
403             break;
404 #endif /* OMIT_VGET_TIM */
405         case 'v':
406             vmsk_log(LOG_UPTO(LOG_INFO), LOG_UPTO(LOG_EMERG));
407             break;
408         case 'q':
409             vmsk_log(LOG_UPTO(LOG_NOTICE), LOG_UPTO(LOG_EMERG));
410             break;
411         default:
412             break;
413         }
414     } while (c != '\003' && c != 'Q');
415
416     syslog(LOG_NOTICE, "Sample program ends.");
417     kernel_exit();
418 }