Changeset 429 for EcnlProtoTool/trunk/asp3_dcre/sample/sample1.c
- Timestamp:
- Jul 3, 2020, 7:19:17 PM (4 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
EcnlProtoTool/trunk/asp3_dcre/sample/sample1.c
r331 r429 6 6 * Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory 7 7 * Toyohashi Univ. of Technology, JAPAN 8 * Copyright (C) 2004-201 6by Embedded and Real-Time Systems Laboratory8 * Copyright (C) 2004-2019 by Embedded and Real-Time Systems Laboratory 9 9 * Graduate School of Information Science, Nagoya Univ., JAPAN 10 10 * … … 48 48 * プログラムの概要: 49 49 * 50 * ユーザインタフェースを受け持つメインタスク( タスクID: MAIN_TASK,優51 * 先度: MAIN_PRIORITY)と,3つの並行実行されるタスク(タスクID:52 * TASK1~TASK3,初期優先度: MID_PRIORITY)で構成される.また,起動周53 * 期が2秒の周期ハンドラ(周期ハンドラID: CYCHDR1)を用いる.54 * 55 * 並行実行されるタスクは,task_loop回空ループを実行する度に,タスクが56 * 実行中であることをあらわすメッセージを表示する.空ループを実行する57 * のは,空ループなしでメッセージを出力すると,多量のメッセージが出力58 * され,プログラムの動作が確認しずらくなるためである.また,低速なシ50 * ユーザインタフェースを受け持つメインタスク(MAIN_TASK)と,3つの並 51 * 行実行されるタスク(TASK1~TASK3),例外処理タスク(EXC_TASK)の5 52 * つのタスクを用いる.これらの他に,システムログタスクが動作する.ま 53 * た,周期ハンドラ,アラームハンドラ,割込みサービスルーチン,CPU例 54 * 外ハンドラをそれぞれ1つ用いる. 55 * 56 * 並行実行されるタスクは,task_loop回のループを実行する度に,タスク 57 * が実行中であることをあらわすメッセージを表示する.ループを実行する 58 * のは,プログラムの動作を確認しやすくするためである.また,低速なシ 59 59 * リアルポートを用いてメッセージを出力する場合に,すべてのメッセージ 60 60 * が出力できるように,メッセージの量を制限するという理由もある. 61 61 * 62 * 周期ハンドラは,三つの優先度(HIGH_PRIORITY,MID_PRIORITY, 63 * LOW_PRIORITY)のレディキューを回転させる.プログラムの起動直後は, 64 * 周期ハンドラは停止状態になっている. 65 * 66 * メインタスクは,シリアルI/Oポートからの文字入力を行い(文字入力を 67 * 待っている間は,並行実行されるタスクが実行されている),入力された 68 * 文字に対応した処理を実行する.入力された文字と処理の関係は次の通り. 62 * 周期ハンドラ,アラームハンドラ,割込みサービスルーチンは,3つの優 63 * 先度(HIGH_PRIORITY,MID_PRIORITY,LOW_PRIORITY)のレディキューを 64 * 回転させる.周期ハンドラは,プログラムの起動直後は停止状態になって 65 * いる. 66 * 67 * CPU例外ハンドラは,CPU例外からの復帰が可能な場合には,例外処理タス 68 * クを起動する.例外処理タスクは,CPU例外を起こしたタスクに対して, 69 * 終了要求を行う. 70 * 71 * メインタスクは,シリアルポートからの文字入力を行い(文字入力を待っ 72 * ている間は,並行実行されるタスクが実行されている),入力された文字 73 * に対応した処理を実行する.入力された文字と処理の関係は次の通り. 69 74 * Control-Cまたは'Q'が入力されると,プログラムを終了する. 70 75 * … … 97 102 * 'b' : アラームハンドラを5秒後に起動するよう動作開始させる. 98 103 * 'B' : アラームハンドラを動作停止させる. 99 * 'z' : 対象タスクにCPU例外を発生させる(タスクを終了させる). 100 * 'Z' : 対象タスクにCPUロック状態でCPU例外を発生させる(プログラムを 101 * 終了する). 104 * 'z' : 対象タスクにCPU例外を発生させる(ターゲットによっては復帰可能). 105 * 'Z' : 対象タスクにCPUロック状態でCPU例外を発生させる(復帰不可能). 102 106 * '@' : タスク3をacre_tskにより生成する. 103 107 * '!' : 対象タスクをdel_tskにより削除する. 104 108 * '$' : アラームハンドラをacre_almにより生成する. 105 109 * '#' : アラームハンドラをdel_almにより削除する. 106 * 'V' : fch_hrtで高分解能タイマを2回読む.110 * 'V' : 短いループを挟んで,fch_hrtで高分解能タイマを2回読む. 107 111 * 'v' : 発行したシステムコールを表示する(デフォルト). 108 112 * 'q' : 発行したシステムコールを表示しない. … … 116 120 #include "kernel_cfg.h" 117 121 #include "sample1.h" 118 /*#include "sample1n.h"*/119 122 120 123 /* … … 132 135 133 136 /* 137 * プロセッサ時間の消費 138 * 139 * ループによりプロセッサ時間を消費する.最適化ができないように,ルー 140 * プ内でvolatile変数を読み込む. 141 */ 142 static volatile long_t volatile_var; 143 144 static void 145 consume_time(ulong_t ctime) 146 { 147 ulong_t i; 148 149 for (i = 0; i < ctime; i++) { 150 (void) volatile_var; 151 } 152 } 153 154 /* 134 155 * 並行実行されるタスクへのメッセージ領域 135 156 */ … … 144 165 * 並行実行されるタスク 145 166 */ 146 void task(intptr_t exinf)147 { 148 volatile ulong_t i; 167 void 168 task(intptr_t exinf) 169 { 149 170 int_t n = 0; 150 171 int_t tskno = (int_t) exinf; … … 155 176 syslog(LOG_NOTICE, "task%d is running (%03d). %s", 156 177 tskno, ++n, graph[tskno-1]); 157 for (i = 0; i < task_loop; i++);178 consume_time(task_loop); 158 179 c = message[tskno-1]; 159 180 message[tskno-1] = 0; … … 202 223 203 224 /* 204 * 割込みハンドラ 225 * 割込みサービスルーチン 226 * 227 * HIGH_PRIORITY,MID_PRIORITY,LOW_PRIORITY の各優先度のレディキュー 228 * を回転させる. 205 229 */ 206 230 #ifdef INTNO1 207 231 208 void intno1_isr(intptr_t exinf) 232 void 233 intno1_isr(intptr_t exinf) 209 234 { 210 235 intno1_clear(); … … 235 260 "sns_dpn() is not true in CPU exception handler."); 236 261 } 237 syslog(LOG_INFO, "sns_loc = %d sns_dsp = %dxsns_dpn = %d",262 syslog(LOG_INFO, "sns_loc = %d, sns_dsp = %d, xsns_dpn = %d", 238 263 sns_loc(), sns_dsp(), xsns_dpn(p_excinf)); 239 264 … … 244 269 } 245 270 246 #ifdef PREPARE_RETURN_CPUEXC247 PREPARE_RETURN_CPUEXC;248 271 SVC_PERROR(get_tid(&cpuexc_tskid)); 249 272 SVC_PERROR(act_tsk(EXC_TASK)); 250 #else /* PREPARE_RETURN_CPUEXC */251 syslog(LOG_NOTICE, "Sample program ends with exception.");252 SVC_PERROR(ext_ker());253 assert(0);254 #endif /* PREPARE_RETURN_CPUEXC */255 273 } 256 274 … … 263 281 * を回転させる. 264 282 */ 265 void cyclic_handler(intptr_t exinf) 283 void 284 cyclic_handler(intptr_t exinf) 266 285 { 267 286 SVC_PERROR(rot_rdq(HIGH_PRIORITY)); … … 276 295 * を回転させる. 277 296 */ 278 void alarm_handler(intptr_t exinf) 297 void 298 alarm_handler(intptr_t exinf) 279 299 { 280 300 SVC_PERROR(rot_rdq(HIGH_PRIORITY)); … … 286 306 * 例外処理タスク 287 307 */ 288 void exc_task(intptr_t exinf) 308 void 309 exc_task(intptr_t exinf) 289 310 { 290 311 SVC_PERROR(ras_ter(cpuexc_tskid)); … … 294 315 * メインタスク 295 316 */ 296 void main_task(intptr_t exinf) 317 void 318 main_task(intptr_t exinf) 297 319 { 298 320 char c; … … 302 324 PRI tskpri; 303 325 #ifndef TASK_LOOP 304 volatile ulong_t i;305 326 SYSTIM stime1, stime2; 306 327 #endif /* TASK_LOOP */ … … 332 353 * ループ回数の設定 333 354 * 334 * 並行実行されるタスク内での 空ループの回数(task_loop)は,空ルー335 * プの実行時間が約0.4秒になるように設定する.この設定のために,336 * LOOP_REF回の 空ループの実行時間を,その前後でget_timを呼ぶことで337 * 測定し,その測定結果から空ループの実行時間が0.4秒になるループ 回338 * 数を求め,task_loopに設定する.355 * 並行実行されるタスク内でのループの回数(task_loop)は,ループ 356 * の実行時間が約0.4秒になるように設定する.この設定のために, 357 * LOOP_REF回のループの実行時間を,その前後でget_timを呼ぶことで 358 * 測定し,その測定結果から空ループの実行時間が0.4秒になるループ 359 * 回数を求め,task_loopに設定する. 339 360 * 340 * LOOP_REFは,デフォルトでは1,000,000に設定しているが,想定したよ 341 * り遅いプロセッサでは,サンプルプログラムの実行開始に時間がかか 342 * りすぎるという問題を生じる.逆に想定したより速いプロセッサでは, 343 * LOOP_REF回の空ループの実行時間が短くなり,task_loopに設定する値 344 * の誤差が大きくなるという問題がある. 345 * 346 * そこで,そのようなターゲットでは,target_test.hで,LOOP_REFを適 347 * 切な値に定義するのが望ましい. 361 * LOOP_REFは,デフォルトでは1,000,000に設定しているが,想定した 362 * より遅いプロセッサでは,サンプルプログラムの実行開始に時間がか 363 * かりすぎるという問題を生じる.逆に想定したより速いプロセッサで 364 * は,LOOP_REF回のループの実行時間が短くなり,task_loopに設定す 365 * る値の誤差が大きくなるという問題がある.そこで,そのようなター 366 * ゲットでは,target_test.hで,LOOP_REFを適切な値に定義すること 367 * とする. 348 368 * 349 369 * また,task_loopの値を固定したい場合には,その値をTASK_LOOPにマ 350 * クロ定義する.TASK_LOOPがマクロ定義されている場合,上記の測定 を351 * 行わずに,TASK_LOOPに定義された値を空ループの回数とする.370 * クロ定義する.TASK_LOOPがマクロ定義されている場合,上記の測定 371 * を行わずに,TASK_LOOPに定義された値をループの回数とする. 352 372 * 353 * ターゲットによっては,空ループの実行時間の1回目の測定で,本来よ354 * りも長めになるものがある.このようなターゲットでは,MEASURE_TWICE355 * をマクロ定義することで,1回目の測定結果を捨てて,2回目の測定結果356 * を使う.373 * ターゲットによっては,ループの実行時間の1回目の測定で,本来より 374 * も長めになるものがある.このようなターゲットでは,MEASURE_TWICE 375 * をマクロ定義することで,1回目の測定結果を捨てて,2回目の測定結 376 * 果を使う. 357 377 */ 358 378 #ifdef TASK_LOOP … … 361 381 362 382 #ifdef MEASURE_TWICE 363 task_loop = LOOP_REF;364 383 SVC_PERROR(get_tim(&stime1)); 365 for (i = 0; i < task_loop; i++);384 consume_time(LOOP_REF); 366 385 SVC_PERROR(get_tim(&stime2)); 367 386 #endif /* MEASURE_TWICE */ 368 387 369 task_loop = LOOP_REF;370 388 SVC_PERROR(get_tim(&stime1)); 371 for (i = 0; i < task_loop; i++);389 consume_time(LOOP_REF); 372 390 SVC_PERROR(get_tim(&stime2)); 373 391 task_loop = LOOP_REF * 400LU / (ulong_t)(stime2 - stime1) * 1000LU; … … 477 495 break; 478 496 case 'c': 479 syslog(LOG_INFO, "#sta_cyc( 1)");497 syslog(LOG_INFO, "#sta_cyc(CYCHDR1)"); 480 498 SVC_PERROR(sta_cyc(CYCHDR1)); 481 499 break; 482 500 case 'C': 483 syslog(LOG_INFO, "#stp_cyc( 1)");501 syslog(LOG_INFO, "#stp_cyc(CYCHDR1)"); 484 502 SVC_PERROR(stp_cyc(CYCHDR1)); 485 503 break; 486 504 case 'b': 487 syslog(LOG_INFO, "#sta_alm( 1, 5000000)");505 syslog(LOG_INFO, "#sta_alm(ALMHDR1, 5000000)"); 488 506 SVC_PERROR(sta_alm(ALMHDR1, 5000000)); 489 507 break; 490 508 case 'B': 491 syslog(LOG_INFO, "#stp_alm( 1)");509 syslog(LOG_INFO, "#stp_alm(ALMHDR1)"); 492 510 SVC_PERROR(stp_alm(ALMHDR1)); 493 511 break; … … 499 517 ctsk.stksz = STACK_SIZE; 500 518 ctsk.stk = NULL; 501 SVC_PERROR(TASK3 = acre_tsk(&ctsk)); 502 syslog(LOG_NOTICE, "task3 is created with tskid = %d.", 519 SVC_PERROR(ercd = acre_tsk(&ctsk)); 520 if (ercd >= 0) { 521 TASK3 = ercd; 522 syslog(LOG_NOTICE, "task3 is created with tskid = %d.", 503 523 (int_t) TASK3); 524 } 504 525 break; 505 526 case '!': … … 512 533 calm.nfyinfo.nfy.handler.exinf = (intptr_t) 0; 513 534 calm.nfyinfo.nfy.handler.tmehdr = (TMEHDR) alarm_handler; 514 SVC_PERROR(ALMHDR1 = acre_alm(&calm)); 515 syslog(LOG_NOTICE, "alarm handler is created with almid = %d.", 535 SVC_PERROR(ercd = acre_alm(&calm)); 536 if (ercd >= 0) { 537 ALMHDR1 = ercd; 538 syslog(LOG_NOTICE, "alarm handler is created with almid = %d.", 516 539 (int_t) ALMHDR1); 540 } 517 541 break; 518 542 case '#': 519 syslog(LOG_INFO, "#del_alm( 1)");543 syslog(LOG_INFO, "#del_alm(ALMHDR1)"); 520 544 SVC_PERROR(del_alm(ALMHDR1)); 521 545 break; … … 523 547 case 'V': 524 548 hrtcnt1 = fch_hrt(); 549 consume_time(1000LU); 525 550 hrtcnt2 = fch_hrt(); 526 551 syslog(LOG_NOTICE, "hrtcnt1 = %tu, hrtcnt2 = %tu", 527 hrtcnt1,hrtcnt2);552 (uint32_t) hrtcnt1, (uint32_t) hrtcnt2); 528 553 break; 529 554 … … 552 577 #endif /* BIT_KERNEL */ 553 578 579 case '\003': 580 case 'Q': 581 break; 582 554 583 default: 584 syslog(LOG_INFO, "Unknown command: '%c'.", c); 555 585 break; 556 586 }
Note:
See TracChangeset
for help on using the changeset viewer.