OSDN Git Service

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