source: ssp_qb_r5f100le_cs/trunk/target/qb_r5f100le_cs/ssp_rl78/sample1/src/sample1.c@ 95

Last change on this file since 95 was 95, checked in by nmir-saito, 9 years ago

ファイルの mime-type 変更

  • Property svn:mime-type set to text/plain; charset=shift_jis
File size: 9.4 KB
Line 
1/*
2 * TOPPERS/SSP Kernel
3 * Smallest Set Profile Kernel
4 *
5 *
6 * Copyright (C) 2008 by Embedded and Real-Time Systems Laboratory
7 * Graduate School of Information Science, Nagoya Univ., JAPAN
8 * Copyright (C) 2010-2012 by Meika Sugimoto
9 * Copyright (C) 2014,2015 by Naoki Saito
10 * Nagoya Municipal Industrial Research Institute, JAPAN
11 *
12 * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
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 * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
33 * 免責すること.
34 *
35 * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
36 * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
37 * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
38 * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
39 * の責任を負わない.
40 *
41 */
42
43/*
44 * TOPPERS/SSPのサンプルプログラム
45 *
46 * SSPカーネルの基本的な動作を確認するためのサンプルプログラム.
47 *
48 * プログラムの概要:
49 *
50 * ユーザインタフェースを受け持つメインタスクと,3つの並行実行される
51 * タスクとで構成される.タスクIDおよび優先度設定は以下の通り.
52 * (タスクID) (起動時優先度) (実行時優先度)
53 * MAIN_TASK MAIN_PRIORITY (左に同じ)
54 * TASK1 TASK1_PRIORITY (左に同じ)
55 * TASK2 TASK2_PRIORITY (左に同じ)
56 * TASK3 TASK3_PRIORITY TASK3_EXEPRIORITY
57 *
58 * また,起動周期が2秒の周期ハンドラ(周期ハンドラID: CYC1)および
59 * メインタスク起動用の周期ハンドラ(周期ハンドラID: MAIN_CYC)を用いる.
60 *
61 * 並行実行されるタスクは,task_loop回空ループを実行する度に,タスクが
62 * 実行中であることをあらわすメッセージを表示する.空ループを実行する
63 * のは,空ループなしでメッセージを出力すると,多量のメッセージが出力
64 * され,プログラムの動作が確認しずらくなるためである.また,低速なシ
65 * リアルポートを用いてメッセージを出力する場合に,すべてのメッセージ
66 * が出力できるように,メッセージの量を制限するという理由もある.
67 *
68 * 周期ハンドラ(CYC1)は,起動したことを示すメッセージを表示する.
69 * プログラムの起動直後は,周期ハンドラ(CYC1)は停止状態になっている.
70 *
71 * メインタスクは,周期ハンドラ(MAIN_CYC)から100ミリ秒ごとに起動され,
72 * シリアルI/Oポートからの文字入力を行い,入力された
73 * 文字に対応した処理を実行する.入力された文字と処理の関係は次の通り.
74 * 'Q'が入力されると,プログラムを終了する.
75 *
76 * '1' : 対象タスクをTASK1に切り換える(初期設定).
77 * '2' : 対象タスクをTASK2に切り換える.
78 * '3' : 対象タスクをTASK3に切り換える.
79 * 'a' : 対象タスクをact_tskにより起動する.
80 * 'e' : 対象タスクを関数のリターンにより終了させる.
81 * 'c' : 周期ハンドラを動作開始させる.
82 * 'C' : 周期ハンドラを動作停止させる.
83 * 'b' : アラームハンドラを5秒後に起動するよう動作開始させる.
84 * 'B' : アラームハンドラを動作停止させる.
85 * 'z' : 対象タスクにCPU例外を発生させる(タスクを終了させる).
86 * 's' : イベントフラグ(ID:FLG1)に当該タスクに関連するビットをセットする.
87 * 'l' : すべてのタスク関連するイベントフラグ(ID:FLG1)のビットをクリアする.
88 * 'p' : ポーリングでイベントフラグ(FLG1)を待つ.
89 * 'd' : ポーリングでデータキュー(ID:DTQ1)へデータを送信する.
90 * 'r' : ポーリングでデータキュー(ID:DTQ1)からデータを受信する.
91 */
92
93#include <kernel.h>
94#include <sil.h>
95#include <t_syslog.h>
96#include "kernel_cfg.h"
97#include "syssvc/serial.h"
98#include "syssvc/logtask.h"
99
100#include "sample1.h"
101
102
103/*
104 * システムサービスのエラーハンドリング
105 */
106#define SVC(expression) \
107 if((expression) < 0) \
108 { \
109 syslog(LOG_NOTICE , "Error at %s : %d caused by %s." , \
110 __FILE__ , __LINE__ , #expression); \
111 }
112
113/*
114 * 並列実行されるタスクへのメッセージ領域
115 */
116char message[3];
117
118/*
119 * ループ回数
120 */
121ulong_t task_loop; /* タスク内でのループ回数 */
122
123void init_task(intptr_t exinf)
124{
125#ifndef TASK_LOOP
126 volatile ulong_t i;
127 SYSTIM stime1, stime2;
128#endif /* TASK_LOOP */
129
130 /* シリアルポートのオープン */
131 SVC(serial_opn_por(TASK_PORTID));
132 SVC(serial_ctl_por(TASK_PORTID , IOCTL_CRLF));
133
134 /* ログタスクの初期化 */
135 logtask_initialize(LOGTASK_PORTID);
136
137 /* 起動メッセージの出力 */
138 syslog(LOG_INFO , "Sample program starts.");
139
140 /* 周期ハンドラの起動 */
141 SVC(sta_cyc(MAIN_CYC));
142
143 /*
144 * ループ回数の設定
145 *
146 * TASK_LOOPがマクロ定義されている場合,測定せずに,TASK_LOOPに定
147 * 義された値を,タスク内でのループ回数とする.
148 *
149 * MEASURE_TWICEがマクロ定義されている場合,1回目の測定結果を捨て
150 * て,2回目の測定結果を使う.1回目の測定は長めの時間が出るため.
151 */
152#ifdef TASK_LOOP
153 task_loop = TASK_LOOP;
154#else /* TASK_LOOP */
155
156 task_loop = LOOP_REF;
157 SVC(get_tim(&stime1));
158 for (i = 0; i < task_loop; i++) {
159 /* 時間かせぎのためのループであり,ここでは何もしない */
160 }
161 SVC(get_tim(&stime2));
162 task_loop = LOOP_REF * 400UL / (stime2 - stime1);
163
164#endif /* TASK_LOOP */
165
166}
167
168
169void main_task(intptr_t exinf)
170{
171 static ID tskid = TASK1;
172 static uint_t tskno = 1;
173 char c;
174
175
176 /* シリアルポートからの文字受信 */
177 if(serial_rea_dat(TASK_PORTID , &c , 1) > 0)
178 {
179 switch(c)
180 {
181 case 'e':
182 case 's':
183 case 'l':
184 case 'p':
185 case 'd':
186 case 'r':
187 case 'z':
188 message[tskno-1] = c;
189 break;
190 case '1':
191 tskid = TASK1;
192 tskno = 1;
193 break;
194 case '2':
195 tskid = TASK2;
196 tskno = 2;
197 break;
198 case '3':
199 tskid = TASK3;
200 tskno = 3;
201 break;
202 case 'a':
203 syslog(LOG_INFO, "#act_tsk(%d)", tskno);
204 SVC(act_tsk(tskid));
205 break;
206 case 'b':
207 syslog(LOG_INFO, "#sta_alm(1, 5000)");
208 SVC(sta_alm(ALM1 , 5000));
209 break;
210 case 'B':
211 syslog(LOG_INFO, "#stp_alm(1)");
212 SVC(stp_alm(ALM1));
213 break;
214 case 'c':
215 syslog(LOG_INFO, "sta_cyc(1)");
216 SVC(sta_cyc(CYC1));
217 break;
218 case 'C':
219 syslog(LOG_INFO, "stp_cyc(1)");
220 SVC(stp_cyc(CYC1));
221 break;
222 case 'Q':
223 syslog(LOG_NOTICE, "Sample program ends.");
224 SVC(ext_ker());
225 break;
226 default:
227 /* エラー表示 */
228 syslog(LOG_INFO , "Unknown command.");
229 break;
230 }
231 }
232}
233
234
235void task(intptr_t exinf)
236{
237 /* exinfはタスク番号 */
238 uint_t tskno = (uint_t)exinf;
239 int_t n = 0;
240 char command;
241 volatile ulong_t i;
242 const char *graph[] = { "|", " +", " *" };
243 bool_t cont = true;
244 FLGPTN pattern;
245 const FLGPTN flgptn[] = { 0x00000001U, 0x00000002U, 0x00000004U };
246 const FLGPTN allptn = 0x00000007U;
247 intptr_t dtqdata;
248
249 do
250 {
251 for (i = 0; i < task_loop; i++) {
252 /* 時間かせぎのためのループであり,ここでは何もしない */
253 }
254
255 /* タスク番号の表示 */
256 syslog(LOG_NOTICE, "task%d is running (%03d). %s",
257 tskno, ++n, graph[tskno-1]);
258
259 /* コマンド取得,メッセージ領域をクリア */
260 command = message[tskno - 1];
261 message[tskno - 1] = 0;
262
263 switch(command)
264 {
265 case 'e':
266 cont = false;
267 syslog(LOG_INFO, "#%d#terminate task", tskno);
268 break;
269 case 's':
270 SVC(set_flg(FLG1 , flgptn[tskno - 1]));
271 syslog(LOG_INFO, "#%d#set_flg(flgid=%d , mask=%d)",
272 tskno , FLG1 , flgptn[tskno - 1]);
273 break;
274 case 'l':
275 SVC(clr_flg(FLG1 , ~allptn));
276 syslog(LOG_INFO, "#%d#clr_flg(flgid=%d)", tskno , FLG1);
277 break;
278 case 'p':
279 SVC(pol_flg(FLG1 , allptn , TWF_ORW , &pattern));
280 syslog(LOG_INFO, "#%d#pol_flg(flgid=%d , value=%u)", tskno , FLG1 , pattern);
281 break;
282 case 'd':
283 SVC(psnd_dtq(DTQ1 , (intptr_t)tskno));
284 syslog(LOG_INFO, "#%d#snd_dtq(dtqid=%d , value=%u)", tskno , DTQ1 , tskno);
285 break;
286 case 'r':
287 SVC(prcv_dtq(DTQ1 , (intptr_t *)(&dtqdata)));
288 syslog(LOG_INFO, "#%d#rcv_dtq(dtqid=%d , value=%u)", tskno , DTQ1 , dtqdata);
289 break;
290#ifdef CPUEXC1
291 case 'z':
292 syslog(LOG_NOTICE, "#%d#raise CPU exception", tskno);
293 RAISE_CPU_EXCEPTION;
294 break;
295#endif /* CPUEXC1 */
296 default:
297 break;
298 }
299 }while(cont == true);
300}
301
302
303void alarm_handler(intptr_t exinf)
304{
305 ID tskid = (ID)exinf;
306
307 syslog(LOG_INFO , "Alarm handler is raised.");
308 SVC(iact_tsk(tskid));
309}
310
311void main_task_cychdr(intptr_t exinf)
312{
313 ID tskid = (ID)exinf;
314
315 (void)iact_tsk(tskid);
316}
317
318void cyclic_handler(intptr_t exinf)
319{
320 syslog(LOG_INFO , "Cyclic handler is raised.");
321}
322
323#ifdef CPUEXC1
324void exc_handler(void *p_excinf)
325{
326 syslog(LOG_INFO , "CPU exception handler.");
327 syslog(LOG_INFO , "Kernel exit.");
328
329 (void)ext_ker();
330}
331#endif /* CPUEXC1 */
332
Note: See TracBrowser for help on using the repository browser.