sample1-dual1.c

説明を見る。
00001 /*
00002  *  TOPPERS/JSP Kernel
00003  *      Toyohashi Open Platform for Embedded Real-Time Systems/
00004  *      Just Standard Profile Kernel
00005  * 
00006  *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
00007  *                              Toyohashi Univ. of Technology, JAPAN
00008  *  Copyright (C) 2004-2005 by Embedded and Real-Time Systems Laboratory
00009  *              Graduate School of Information Science, Nagoya Univ., JAPAN
00010  * 
00011  *  上記著作権者は,以下の (1)〜(4) の条件か,Free Software Foundation 
00012  *  によって公表されている GNU General Public License の Version 2 に記
00013  *  述されている条件を満たす場合に限り,本ソフトウェア(本ソフトウェア
00014  *  を改変したものを含む.以下同じ)を使用・複製・改変・再配布(以下,
00015  *  利用と呼ぶ)することを無償で許諾する.
00016  *  (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
00017  *      権表示,この利用条件および下記の無保証規定が,そのままの形でソー
00018  *      スコード中に含まれていること.
00019  *  (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
00020  *      用できる形で再配布する場合には,再配布に伴うドキュメント(利用
00021  *      者マニュアルなど)に,上記の著作権表示,この利用条件および下記
00022  *      の無保証規定を掲載すること.
00023  *  (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
00024  *      用できない形で再配布する場合には,次のいずれかの条件を満たすこ
00025  *      と.
00026  *    (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
00027  *        作権表示,この利用条件および下記の無保証規定を掲載すること.
00028  *    (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
00029  *        報告すること.
00030  *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
00031  *      害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
00032  * 
00033  *  本ソフトウェアは,無保証で提供されているものである.上記著作権者お
00034  *  よびTOPPERSプロジェクトは,本ソフトウェアに関して,その適用可能性も
00035  *  含めて,いかなる保証も行わない.また,本ソフトウェアの利用により直
00036  *  接的または間接的に生じたいかなる損害に関しても,その責任を負わない.
00037  * 
00038  *  @(#) $Id: sample1-dual1.c,v 1.3 2006/03/14 04:39:10 honda Exp $
00039  */
00040 
00041 /* 
00042  *  サンプルプログラム(1)の本体
00043  *
00044  *  JSPカーネルの基本的な動作を確認するためのサンプルプログラム.
00045  *
00046  *  プログラムの概要:
00047  *
00048  *  ユーザインタフェースを受け持つメインタスク(タスクID: MAIN_TASK,
00049  *  優先度: MAIN_PRIORITY)と,三つの並列実行されるタスク(タスクID:
00050  *  TASK1〜TASK3,初期優先度: MID_PRIORITY)で構成される.また,起動周
00051  *  期が2秒の周期ハンドラ(周期ハンドラID: CYCHDR1)を用いる.
00052  *
00053  *  並列実行されるタスクは,task_loop 回空ループを実行する度に,タスク
00054  *  が実行中であることをあらわすメッセージを表示する.
00055  *
00056  *  周期ハンドラは,三つの優先度(HIGH_PRIORITY,MID_PRIORITY,
00057  *  LOW_PRIORITY)のレディキューを回転させる.プログラムの起動直後は,
00058  *  周期ハンドラは停止状態になっている.
00059  *
00060  *  メインタスクは,シリアルI/Oポートからの文字入力を行い(文字入力を
00061  *  待っている間は,並列実行されるタスクが実行されている),入力された
00062  *  文字に対応した処理を実行する.入力された文字と処理の関係は次の通り.
00063  *  Control-C または 'Q' が入力されると,プログラムを終了する.
00064  *
00065  *  '1' : 以降のコマンドは TASK1 に対して行う.
00066  *  '2' : 以降のコマンドは TASK2 に対して行う.
00067  *  '3' : 以降のコマンドは TASK3 に対して行う.
00068  *  '4' : 以降のコマンドは PE1 に対して行う.
00069  *  '5' : 以降のコマンドは PE2 に対して行う.  
00070  *  'a' : タスクを act_tsk により起動する.
00071  *  'A' : タスクに対する起動要求を can_act によりキャンセルする.
00072  *  'e' : タスクに ext_tsk を呼び出させ,終了させる.
00073  *  't' : タスクを ter_tsk により強制終了する.
00074  *  '>' : タスクの優先度を HIGH_PRIORITY にする.
00075  *  '=' : タスクの優先度を MID_PRIORITY にする.
00076  *  '<' : タスクの優先度を LOW_PRIORITY にする.
00077  *  'G' : タスクの優先度を get_pri で読み出す.
00078  *  's' : タスクに slp_tsk を呼び出させ,起床待ちにさせる.
00079  *  'S' : タスクに tslp_tsk(10秒) を呼び出させ,起床待ちにさせる.
00080  *  'w' : タスクを wup_tsk により起床する.
00081  *  'W' : タスクに対する起床要求を can_wup によりキャンセルする.
00082  *  'l' : タスクを rel_wai により強制的に待ち解除にする.
00083  *  'u' : タスクを sus_tsk により強制待ち状態にする.
00084  *  'm' : タスクの強制待ち状態を rsm_tsk により解除する.
00085  *  'M' : タスクの強制待ち状態を frsm_tsk により強制解除する.
00086  *  'd' : タスクに dly_tsk(10秒) を呼び出させ,時間経過待ちにさせる.
00087  *  'x' : タスクにパターン 0x0001 の例外処理を要求する.
00088  *  'X' : タスクにパターン 0x0002 の例外処理を要求する.
00089  *  'y' : タスクに dis_tex を呼び出させ,タスク例外を禁止する.
00090  *  'Y' : タスクに ena_tex を呼び出させ,タスク例外を許可する.
00091  *  'r' : 三つの優先度(HIGH_PRIORITY,MID_PRIORITY,LOW_PRIORITY)の
00092  *        レディキューを回転させる.
00093  *  'c' : 周期ハンドラを動作させる.
00094  *  'C' : 周期ハンドラを停止させる.
00095  *  'j' : LED周期ハンドラを動作させる.
00096  *  'J' : LED周期ハンドラを停止させる.    
00097  *  'z' : CPU例外を発生させる.
00098  *  'Z' : CPUロック状態でCPU例外を発生させる(プログラムを終了する).
00099  *  'V' : vxget_tim で性能評価用システム時刻を2回読む.
00100  *  'v' : 発行したシステムコールを表示する(デフォルト).
00101  *  'q' : 発行したシステムコールを表示しない.
00102  */
00103 
00104 #include <t_services.h>
00105 #include <s_services.h>
00106 #include "kernel_id.h"
00107 #include "sample1-dual1.h"
00108 
00109 #include "class_id.h"
00110 
00111 /*
00112  *  並行実行されるタスクへのメッセージ領域
00113  */
00114 char    message[3];
00115 
00116 /*
00117  *  ループ回数
00118  */
00119 UW  task_loop;      /* タスク内でのループ回数 */
00120 UW  tex_loop;       /* 例外処理ルーチン内でのループ回数 */
00121 
00122 /*
00123  *  並行実行されるタスク
00124  */
00125 void task(VP_INT exinf)
00126 {
00127     volatile UW i;
00128     INT     n = 0;
00129     INT     tskno = (INT) exinf;
00130     const char  *graph[] = { "|", "  +", "    *" };
00131     char        c;
00132 
00133     ena_tex();
00134     while (1) {
00135         syslog(LOG_NOTICE, "task%d is running (%03d).   %s",
00136                     tskno, ++n, graph[tskno-1]);
00137         for (i = 0; i < task_loop; i++);
00138         c = message[tskno-1];
00139         message[tskno-1] = 0;
00140         switch (c) {
00141         case 'e':
00142             syslog(LOG_INFO, "#%d#ext_tsk()", tskno);
00143             ext_tsk();
00144         case 's':
00145             syslog(LOG_INFO, "#%d#slp_tsk()", tskno);
00146             syscall(slp_tsk());
00147             break;
00148         case 'S':
00149             syslog(LOG_INFO, "#%d#tslp_tsk(3000)", tskno);
00150             syscall(tslp_tsk(3000));
00151             break;
00152         case 'd':
00153             syslog(LOG_INFO, "#%d#dly_tsk(10000)", tskno);
00154             syscall(dly_tsk(10000));
00155             break;
00156         case 'y':
00157             syslog(LOG_INFO, "#%d#dis_tex()", tskno);
00158             syscall(dis_tex());
00159             break;
00160         case 'Y':
00161             syslog(LOG_INFO, "#%d#ena_tex()", tskno);
00162             syscall(ena_tex());
00163             break;
00164 #ifdef CPUEXC1
00165         case 'z':
00166             syslog(LOG_NOTICE, "#%d#raise CPU exception", tskno);
00167             RAISE_CPU_EXCEPTION;
00168             break;
00169         case 'Z':
00170             loc_cpu();
00171             syslog(LOG_NOTICE, "#%d#raise CPU exception", tskno);
00172             RAISE_CPU_EXCEPTION;
00173             unl_cpu();
00174             break;
00175 #endif /* CPUEXC1 */
00176         default:
00177             break;
00178         }
00179     }
00180 }
00181 
00182 /*
00183  *  並行して実行されるタスク用のタスク例外処理ルーチン
00184  */
00185 void tex_routine(TEXPTN texptn, VP_INT exinf)
00186 {
00187     volatile UW i;
00188     INT tskno = (INT) exinf;
00189 
00190     syslog(LOG_NOTICE, "task%d receives exception 0x%04x. ",
00191                     tskno, texptn);
00192     for (i = 0; i < tex_loop; i++);
00193 
00194     if (texptn & 0x8000) {
00195         syslog(LOG_INFO, "#%d#ext_tsk()", tskno);
00196         ext_tsk();
00197     }
00198 }
00199 
00200 /*
00201  *  CPU例外ハンドラ
00202  */
00203 #ifdef CPUEXC1
00204 
00205 void
00206 cpuexc_handler(VP p_excinf)
00207 {
00208     ID  tskid;
00209 
00210     syslog(LOG_NOTICE, "CPU exception handler (p_excinf = %08p).",
00211                             p_excinf);
00212     if (sns_ctx() != TRUE) {
00213         syslog(LOG_WARNING,
00214             "sns_ctx() is not TRUE in CPU exception handler.");
00215     }
00216     if (sns_dpn() != TRUE) {
00217         syslog(LOG_WARNING,
00218             "sns_dpn() is not TRUE in CPU exception handler.");
00219     }
00220     syslog(LOG_DEBUG,
00221         "sns_loc = %d sns_dsp = %d", sns_loc(), sns_dsp());
00222     syslog(LOG_DEBUG,
00223         "vxsns_loc = %d vxsns_ctx = %d vxsns_dsp = %d vxsns_dpn = %d",
00224         vxsns_loc(p_excinf), vxsns_ctx(p_excinf),
00225         vxsns_dsp(p_excinf), vxsns_dpn(p_excinf));
00226 
00227     if (!vxsns_loc(p_excinf) && !vxsns_ctx(p_excinf)) {
00228         syscall(iget_tid(&tskid));
00229         syscall(iras_tex(tskid, 0x8000));
00230     }
00231     else {
00232         syslog(LOG_NOTICE, "Sample program ends with exception.");
00233         kernel_exit();
00234     }
00235 }
00236 
00237 #endif /* CPUEXC1 */
00238 
00239 /*
00240  *  周期ハンドラ
00241  *
00242  *  HIGH_PRIORITY,MID_PRIORITY,LOW_PRIORITY の各優先度のレディキュー
00243  *  を回転させる.
00244  */
00245 void cyclic_handler(VP_INT exinf)
00246 {
00247     syslog(LOG_NOTICE, "Cyclic handler start!");
00248     irot_rdq(HIGH_PRIORITY);
00249     irot_rdq(MID_PRIORITY);
00250     irot_rdq(LOW_PRIORITY);
00251 }
00252 
00258 void led_handler(VP_INT exinf)
00259 {
00260     static unsigned char led_data = 0;
00261 
00262     set_led(led_data);
00263 
00264     led_data = ~led_data;
00265 }
00266 
00267 /*
00268  *  メインタスク
00269  */
00270 void main_task(VP_INT exinf)
00271 {
00272     char    c;
00273     ID  tskid = TASK1;
00274     INT clsid = PE1_CLASS_ID;
00275     volatile UW i;
00276     INT tskno = 1;
00277     ER_UINT ercd;   
00278     PRI tskpri;
00279     SYSTIM  stime1, stime2;
00280 #ifndef OMIT_VGET_TIM
00281     SYSUTIM utime1, utime2;
00282 #endif /* OMIT_VGET_TIM */
00283 
00284     vmsk_log(LOG_UPTO(LOG_INFO), LOG_UPTO(LOG_EMERG));
00285     syslog(LOG_NOTICE, "Sample program starts (exinf = %d).", exinf);
00286 
00287     syscall(serial_ctl_por(TASK_PORTID,
00288             (IOCTL_CRLF | IOCTL_FCSND | IOCTL_FCRCV)));
00289 
00290     /*
00291      *  ループ回数の設定
00292      */
00293     task_loop = LOOP_REF;
00294     get_tim(&stime1);
00295     for (i = 0; i < task_loop; i++);
00296     get_tim(&stime2);
00297     task_loop = LOOP_REF * 400 / (stime2 - stime1);
00298     tex_loop = task_loop / 5;
00299 
00300     /*
00301      *  タスクの起動
00302      */
00303 //  syscall(act_tsk(PE2_TASK1));
00304 //  syscall(act_tsk(PE2_TASK2));
00305 //  syscall(act_tsk(PE2_TASK3));
00306 
00307     /*
00308      *  メインループ
00309      */
00310     do {
00311         syscall(serial_rea_dat(TASK_PORTID, &c, 1));
00312         switch (c) {
00313         case 'e':
00314         case 's':
00315         case 'S':
00316         case 'd':
00317         case 'y':
00318         case 'Y':
00319         case 'z':
00320         case 'Z':
00321             message[tskno-1] = c;
00322             break;
00323         case '1':
00324             tskno = 1;
00325             tskid = TASK1 | (clsid << 16);
00326             break;
00327         case '2':
00328             tskno = 2;
00329             tskid = TASK2 | (clsid << 16);
00330             break;
00331         case '3':
00332             tskno = 3;
00333             tskid = TASK3 | (clsid << 16);
00334             break;
00335         case '4':
00336             clsid = PE1_CLASS_ID;
00337             tskid = (tskid & 0xffff) | (clsid << 16);
00338             syslog(LOG_INFO, "Select Processor %d",PE1_CLASS_ID);
00339             break;
00340         case '5':
00341             clsid = PE2_CLASS_ID;
00342             tskid = (tskid & 0xffff) | (clsid << 16);
00343             syslog(LOG_INFO, "Select Processor %d",PE2_CLASS_ID);
00344             break;
00345         case 'a':
00346             syslog(LOG_INFO, "#act_tsk(0x%x)", tskid);
00347             syscall(act_tsk(tskid));
00348             break;
00349         case 'A':
00350             syslog(LOG_INFO, "#can_act(0x%x)", tskid);
00351             syscall(ercd = can_act(tskid));
00352             if (MERCD(ercd) >= 0) {
00353                 syslog(LOG_NOTICE, "can_act(0x%x) returns %d",
00354                         tskid, ercd);
00355             }
00356             break;
00357         case 't':
00358             syslog(LOG_INFO, "#ter_tsk(0x%x)", tskid);
00359             syscall(ter_tsk(tskid));
00360             break;
00361         case '>':
00362             syslog(LOG_INFO, "#chg_pri(0x%x, HIGH_PRIORITY)", tskid);
00363             chg_pri(tskid, HIGH_PRIORITY);
00364             break;
00365         case '=':
00366             syslog(LOG_INFO, "#chg_pri(0x%x, MID_PRIORITY)", tskid);
00367             chg_pri(tskid, MID_PRIORITY);
00368             break;
00369         case '<':
00370             syslog(LOG_INFO, "#chg_pri(0x%x, LOW_PRIORITY)", tskid);
00371             chg_pri(tskid, LOW_PRIORITY);
00372             break;
00373         case 'G':
00374             syslog(LOG_INFO, "#get_pri(0x%x, &tskpri)", tskid);
00375             syscall(ercd = get_pri(tskid, &tskpri));
00376             if (MERCD(ercd) >= 0) {
00377                 syslog(LOG_NOTICE, "priority of task 0x%x is %d",
00378                         tskid, tskpri);
00379             }
00380             break;
00381         case 'w':
00382             syslog(LOG_INFO, "#wup_tsk(0x%x)", tskid);
00383             syscall(wup_tsk(tskid));
00384             break;
00385         case 'W':
00386             syslog(LOG_INFO, "#can_wup(0x%x)", tskid);
00387             syscall(ercd = can_wup(tskid));
00388             if (MERCD(ercd) >= 0) {
00389                 syslog(LOG_NOTICE, "can_wup(0x%x) returns %d",
00390                         tskid, ercd);
00391             }
00392             break;
00393         case 'l':
00394             syslog(LOG_INFO, "#rel_wai(0x%x)", tskid);
00395             syscall(rel_wai(tskid));
00396             break;
00397         case 'u':
00398             syslog(LOG_INFO, "#sus_tsk(0x%x)", tskid);
00399             syscall(sus_tsk(tskid));
00400             break;
00401         case 'm':
00402             syslog(LOG_INFO, "#rsm_tsk(0x%x)", tskid);
00403             syscall(rsm_tsk(tskid));
00404             break;
00405         case 'M':
00406             syslog(LOG_INFO, "#frsm_tsk(0x%x)", tskid);
00407             syscall(frsm_tsk(tskid));
00408             break;
00409         case 'x':
00410             syslog(LOG_INFO, "#ras_tex(0x%x, 0x0001)", tskid);
00411             syscall(ras_tex(tskid, 0x0001));
00412             break;
00413         case 'X':
00414             syslog(LOG_INFO, "#ras_tex(0x%x, 0x0002)", tskid);
00415             syscall(ras_tex(tskid, 0x0002));
00416             break;
00417         case 'r':
00418             syslog(LOG_INFO, "#mrot_rdq(%d, three priorities)", clsid);
00419             syscall(mrot_rdq(clsid, HIGH_PRIORITY));
00420             syscall(mrot_rdq(clsid, MID_PRIORITY));
00421             syscall(mrot_rdq(clsid, LOW_PRIORITY));
00422             break;
00423         case 'c':
00424             syslog(LOG_INFO, "#sta_cyc(PE2_CYCHDR1)");
00425             sta_cyc((clsid << 16) | CYCHDR1);
00426             break;
00427         case 'C':
00428             syslog(LOG_INFO, "#stp_cyc(PE2_CYCHDR1)");
00429             stp_cyc((clsid << 16) | CYCHDR1);
00430             break;
00431         case 'j':
00432             syslog(LOG_INFO, "#sta_cyc(LEDHDR1)");
00433             sta_cyc((clsid << 16) | LEDHDR1);
00434             break;
00435         case 'J':
00436             syslog(LOG_INFO, "#stp_cyc(LEDHDR1)");
00437             stp_cyc((clsid << 16) | LEDHDR1);
00438             break;                      
00439 #ifndef OMIT_VGET_TIM
00440         case 'V':
00441             syscall(vxget_tim(&utime1));
00442             syscall(vxget_tim(&utime2));
00443             syslog(LOG_NOTICE, "utime1 = %d, utime2 = %d",
00444                         (UINT) utime1, (UINT) utime2);
00445             break;
00446 #endif /* OMIT_VGET_TIM */
00447         case 'v':
00448             vmsk_log(LOG_UPTO(LOG_INFO), LOG_UPTO(LOG_EMERG));
00449             break;
00450         case 'q':
00451             vmsk_log(LOG_UPTO(LOG_NOTICE), LOG_UPTO(LOG_EMERG));
00452             break;
00453         default:
00454             break;
00455         }
00456     } while (c != '\003' && c != 'Q');
00457 
00458     syslog(LOG_NOTICE, "Sample program ends.");
00459     kernel_exit();
00460 }

Copyright © 2006 by TAKAGI Nobuhisa.
このページは Mon Apr 3 23:49:12 2006 に Doxygen によって生成されました。