/* * TOPPERS/JSP Kernel * Toyohashi Open Platform for Embedded Real-Time Systems/ * Just Standard Profile Kernel * * Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory * Toyohashi Univ. of Technology, JAPAN * * 惧淡螟侯涪荚は·笆布の (1)×(4) の掘凤か·Free Software Foundation * によって给山されている GNU General Public License の Version 2 に淡 * 揭されている掘凤を塔たす眷圭に嘎り·塑ソフトウェア∈塑ソフトウェア * を猖恃したものを崔むˉ笆布票じ∷を蝗脱ˇ剩澜ˇ猖恃ˇ浩芹邵∈笆布· * 网脱と钙ぶ∷することを痰浸で钓满するˉ * (1) 塑ソフトウェアをソ〖スコ〖ドの妨で网脱する眷圭には·惧淡の螟侯 * 涪山绩·この网脱掘凤および布淡の痰瘦沮惮年が·そのままの妨でソ〖 * スコ〖ド面に崔まれていることˉ * (2) 塑ソフトウェアを·ライブラリ妨及など·戮のソフトウェア倡券に蝗 * 脱できる妨で浩芹邵する眷圭には·浩芹邵に燃うドキュメント∈网脱 * 荚マニュアルなど∷に·惧淡の螟侯涪山绩·この网脱掘凤および布淡 * の痰瘦沮惮年を非很することˉ * (3) 塑ソフトウェアを·怠达に寥み哈むなど·戮のソフトウェア倡券に蝗 * 脱できない妨で浩芹邵する眷圭には·肌のいずれかの掘凤を塔たすこ * とˉ * (a) 浩芹邵に燃うドキュメント∈网脱荚マニュアルなど∷に·惧淡の螟 * 侯涪山绩·この网脱掘凤および布淡の痰瘦沮惮年を非很することˉ * (b) 浩芹邵の妨轮を·侍に年める数恕によって·TOPPERSプロジェクトに * 鼠桂することˉ * (4) 塑ソフトウェアの网脱により木儡弄または粗儡弄に栏じるいかなる禄 * 巢からも·惧淡螟侯涪荚およびTOPPERSプロジェクトを倘勒することˉ * * 塑ソフトウェアは·痰瘦沮で捏丁されているものであるˉ惧淡螟侯涪荚お * よびTOPPERSプロジェクトは·塑ソフトウェアに簇して·その努脱材墙拉も * 崔めて·いかなる瘦沮も乖わないˉまた·塑ソフトウェアの网脱により木 * 儡弄または粗儡弄に栏じたいかなる禄巢に簇しても·その勒扦を砷わないˉ * * @(#) $Id: sample1.c,v 1.2 2003/12/24 08:39:40 honda Exp $ */ /* * サンプルプログラム(1)の塑挛 * * JSPカ〖ネルの答塑弄な瓢侯を澄千するためのサンプルプログラムˉ * * プログラムの车妥: * * ユ〖ザインタフェ〖スを减け积つメインタスク∈タスクID: MAIN_TASK· * 庭黎刨: MAIN_PRIORITY∷と·话つの事误悸乖されるタスク∈タスクID: * TASK1×TASK3·介袋庭黎刨: MID_PRIORITY∷で菇喇されるˉまた·弹瓢件 * 袋が2擅の件袋ハンドラ∈件袋ハンドラID: CYCHDR1∷を脱いるˉ * * 事误悸乖されるタスクは·task_loop 搀鄂ル〖プを悸乖する刨に·タスク * が悸乖面であることをあらわすメッセ〖ジを山绩するˉ * * 件袋ハンドラは·话つの庭黎刨∈HIGH_PRIORITY·MID_PRIORITY· * LOW_PRIORITY∷のレディキュ〖を搀啪させるˉプログラムの弹瓢木稿は· * 件袋ハンドラは匿贿觉轮になっているˉ * * メインタスクは·シリアルI/Oポ〖トからの矢机掐蜗を乖い∈矢机掐蜗を * 略っている粗は·事误悸乖されるタスクが悸乖されている∷·掐蜗された * 矢机に滦炳した借妄を悸乖するˉ掐蜗された矢机と借妄の簇犯は肌の奶りˉ * Control-C または 'Q' が掐蜗されると·プログラムを姜位するˉ * * '1' : 笆惯のコマンドは TASK1 に滦して乖うˉ * '2' : 笆惯のコマンドは TASK2 に滦して乖うˉ * '3' : 笆惯のコマンドは TASK3 に滦して乖うˉ * 'a' : タスクを act_tsk により弹瓢するˉ * 'A' : タスクに滦する弹瓢妥滇を can_act によりキャンセルするˉ * 'e' : タスクに ext_tsk を钙び叫させ·姜位させるˉ * 't' : タスクを ter_tsk により动扩姜位するˉ * '>' : タスクの庭黎刨を HIGH_PRIORITY にするˉ * '=' : タスクの庭黎刨を MID_PRIORITY にするˉ * ' * 'G' : タスクの庭黎刨を get_pri で粕み叫すˉ * 's' : タスクに slp_tsk を钙び叫させ·弹静略ちにさせるˉ * 'S' : タスクに tslp_tsk(10擅) を钙び叫させ·弹静略ちにさせるˉ * 'w' : タスクを wup_tsk により弹静するˉ * 'W' : タスクに滦する弹静妥滇を can_wup によりキャンセルするˉ * 'l' : タスクを rel_wai により动扩弄に略ち豺近にするˉ * 'u' : タスクを sus_tsk により动扩略ち觉轮にするˉ * 'm' : タスクの动扩略ち觉轮を rsm_tsk により豺近するˉ * 'M' : タスクの动扩略ち觉轮を frsm_tsk により动扩豺近するˉ * 'd' : タスクに dly_tsk(10擅) を钙び叫させ·箕粗沸册略ちにさせるˉ * 'x' : タスクにパタ〖ン 0x0001 の毋嘲借妄を妥滇するˉ * 'X' : タスクにパタ〖ン 0x0002 の毋嘲借妄を妥滇するˉ * 'y' : タスクに dis_tex を钙び叫させ·タスク毋嘲を敦贿するˉ * 'Y' : タスクに ena_tex を钙び叫させ·タスク毋嘲を钓材するˉ * 'r' : 话つの庭黎刨∈HIGH_PRIORITY·MID_PRIORITY·LOW_PRIORITY∷の * レディキュ〖を搀啪させるˉ * 'c' : 件袋ハンドラを瓢侯させるˉ * 'C' : 件袋ハンドラを匿贿させるˉ * 'z' : CPU毋嘲を券栏させるˉ * 'Z' : CPUロック觉轮でCPU毋嘲を券栏させる∈プログラムを姜位する∷ˉ * 'V' : vxget_tim で拉墙删擦脱システム箕癸を2搀粕むˉ * 'v' : 券乖したシステムコ〖ルを山绩する∈デフォルト∷ˉ * 'q' : 券乖したシステムコ〖ルを山绩しないˉ */ #include #include "kernel_id.h" #include "sample1.h" /* * 事乖悸乖されるタスクへのメッセ〖ジ挝拌 */ char message[3]; /* * ル〖プ搀眶 */ UW task_loop; /* タスク柒でのル〖プ搀眶 */ UW tex_loop; /* 毋嘲借妄ル〖チン柒でのル〖プ搀眶 */ /* * 事乖悸乖されるタスク */ void task(VP_INT exinf) { volatile UW i; INT n = 0; INT tskno = (INT) exinf; char *graph[] = { "|", " +", " *" }; char c; ena_tex(); while (1) { syslog(LOG_NOTICE, "task%d is running (%03d). %s", tskno, ++n, graph[tskno-1]); for (i = 0; i < task_loop; i++); c = message[tskno-1]; message[tskno-1] = 0; switch (c) { case 'e': syslog(LOG_INFO, "#%d#ext_tsk()", tskno); ext_tsk(); case 's': syslog(LOG_INFO, "#%d#slp_tsk()", tskno); syscall(slp_tsk()); break; case 'S': syslog(LOG_INFO, "#%d#tslp_tsk(10000)", tskno); syscall(tslp_tsk(10000)); break; case 'd': syslog(LOG_INFO, "#%d#dly_tsk(10000)", tskno); syscall(dly_tsk(10000)); break; case 'y': syslog(LOG_INFO, "#%d#dis_tex()", tskno); syscall(dis_tex()); break; case 'Y': syslog(LOG_INFO, "#%d#ena_tex()", tskno); syscall(ena_tex()); break; #ifdef CPUEXC1 case 'z': syslog(LOG_NOTICE, "#%d#raise CPU exception", tskno); RAISE_CPU_EXCEPTION; break; case 'Z': loc_cpu(); syslog(LOG_NOTICE, "#%d#raise CPU exception", tskno); RAISE_CPU_EXCEPTION; unl_cpu(); break; #endif /* CPUEXC1 */ default: break; } } } /* * 事乖して悸乖されるタスク脱のタスク毋嘲借妄ル〖チン */ void tex_routine(TEXPTN texptn, VP_INT exinf) { volatile UW i; INT tskno = (INT) exinf; syslog(LOG_NOTICE, "task%d receives exception 0x%04x. ", tskno, texptn); for (i = 0; i < tex_loop; i++); if (texptn & 0x8000) { syslog(LOG_INFO, "#%d#ext_tsk()", tskno); ext_tsk(); } } /* * CPU毋嘲ハンドラ */ #ifdef CPUEXC1 void cpuexc_handler(VP p_excinf) { ID tskid; syslog(LOG_NOTICE, "CPU exception handler (p_excinf = %08p).", p_excinf); if (sns_ctx() != TRUE) { syslog(LOG_WARNING, "sns_ctx() is not TRUE in CPU exception handler."); } if (sns_dpn() != TRUE) { syslog(LOG_WARNING, "sns_dpn() is not TRUE in CPU exception handler."); } syslog(LOG_DEBUG, "sns_loc = %d sns_dsp = %d", sns_loc(), sns_dsp()); syslog(LOG_DEBUG, "vxsns_loc = %d vxsns_ctx = %d vxsns_dsp = %d vxsns_dpn = %d", vxsns_loc(p_excinf), vxsns_ctx(p_excinf), vxsns_dsp(p_excinf), vxsns_dpn(p_excinf)); if (!vxsns_loc(p_excinf) && !vxsns_ctx(p_excinf)) { syscall(iget_tid(&tskid)); syscall(iras_tex(tskid, 0x8000)); } else { syslog(LOG_NOTICE, "Sample program ends with exception."); kernel_exit(); } } #endif /* CPUEXC1 */ /* * 件袋ハンドラ * * HIGH_PRIORITY·MID_PRIORITY·LOW_PRIORITY の称庭黎刨のレディキュ〖 * を搀啪させるˉ */ void cyclic_handler(VP_INT exinf) { irot_rdq(HIGH_PRIORITY); irot_rdq(MID_PRIORITY); irot_rdq(LOW_PRIORITY); } /* * メインタスク */ void main_task(VP_INT exinf) { char c; ID tskid = TASK1; volatile UW i; INT tskno = 1; ER_UINT ercd; PRI tskpri; SYSTIM stime1, stime2; #ifndef OMIT_VGET_TIM SYSUTIM utime1, utime2; #endif /* OMIT_VGET_TIM */ vmsk_log(LOG_UPTO(LOG_INFO), LOG_UPTO(LOG_EMERG)); syslog(LOG_NOTICE, "Sample program starts (exinf = %d).", exinf); syscall(serial_ctl_por(TASK_PORTID, (IOCTL_CRLF | IOCTL_FCSND | IOCTL_FCRCV))); /* * ル〖プ搀眶の肋年 */ task_loop = LOOP_REF; get_tim(&stime1); for (i = 0; i < task_loop; i++); get_tim(&stime2); task_loop = LOOP_REF * 400 / (stime2 - stime1); tex_loop = task_loop / 5; /* * タスクの弹瓢 */ act_tsk(TASK1); act_tsk(TASK2); act_tsk(TASK3); /* * メインル〖プ */ do { syscall(serial_rea_dat(TASK_PORTID, &c, 1)); switch (c) { case 'e': case 's': case 'S': case 'd': case 'y': case 'Y': case 'z': case 'Z': message[tskno-1] = c; break; case '1': tskno = 1; tskid = TASK1; break; case '2': tskno = 2; tskid = TASK2; break; case '3': tskno = 3; tskid = TASK3; break; case 'a': syslog(LOG_INFO, "#act_tsk(%d)", tskno); syscall(act_tsk(tskid)); break; case 'A': syslog(LOG_INFO, "#can_act(%d)", tskno); syscall(ercd = can_act(tskid)); if (MERCD(ercd) >= 0) { syslog(LOG_NOTICE, "can_act(%d) returns %d", tskid, ercd); } break; case 't': syslog(LOG_INFO, "#ter_tsk(%d)", tskno); syscall(ter_tsk(tskid)); break; case '>': syslog(LOG_INFO, "#chg_pri(%d, HIGH_PRIORITY)", tskno); chg_pri(tskid, HIGH_PRIORITY); break; case '=': syslog(LOG_INFO, "#chg_pri(%d, MID_PRIORITY)", tskno); chg_pri(tskid, MID_PRIORITY); break; case ' syslog(LOG_INFO, "#chg_pri(%d, LOW_PRIORITY)", tskno); chg_pri(tskid, LOW_PRIORITY); break; case 'G': syslog(LOG_INFO, "#get_pri(%d, &tskpri)", tskno); syscall(ercd = get_pri(tskid, &tskpri)); if (MERCD(ercd) >= 0) { syslog(LOG_NOTICE, "priority of task %d is %d", tskid, tskpri); } break; case 'w': syslog(LOG_INFO, "#wup_tsk(%d)", tskno); syscall(wup_tsk(tskid)); break; case 'W': syslog(LOG_INFO, "#can_wup(%d)", tskno); syscall(ercd = can_wup(tskid)); if (MERCD(ercd) >= 0) { syslog(LOG_NOTICE, "can_wup(%d) returns %d", tskid, ercd); } break; case 'l': syslog(LOG_INFO, "#rel_wai(%d)", tskno); syscall(rel_wai(tskid)); break; case 'u': syslog(LOG_INFO, "#sus_tsk(%d)", tskno); syscall(sus_tsk(tskid)); break; case 'm': syslog(LOG_INFO, "#rsm_tsk(%d)", tskno); syscall(rsm_tsk(tskid)); break; case 'M': syslog(LOG_INFO, "#frsm_tsk(%d)", tskno); syscall(frsm_tsk(tskid)); break; case 'x': syslog(LOG_INFO, "#ras_tsk(%d, 0x0001)", tskno); syscall(ras_tex(tskid, 0x0001)); break; case 'X': syslog(LOG_INFO, "#ras_tsk(%d, 0x0002)", tskno); syscall(ras_tex(tskid, 0x0002)); break; case 'r': syslog(LOG_INFO, "#rot_rdq(three priorities)"); rot_rdq(HIGH_PRIORITY); rot_rdq(MID_PRIORITY); rot_rdq(LOW_PRIORITY); break; case 'c': sta_cyc(CYCHDR1); break; case 'C': stp_cyc(CYCHDR1); break; #ifndef OMIT_VGET_TIM case 'V': syscall(vxget_tim(&utime1)); syscall(vxget_tim(&utime2)); syslog(LOG_NOTICE, "utime1 = %d, utime2 = %d", (UINT) utime1, (UINT) utime2); break; #endif /* OMIT_VGET_TIM */ case 'v': vmsk_log(LOG_UPTO(LOG_INFO), LOG_UPTO(LOG_EMERG)); break; case 'q': vmsk_log(LOG_UPTO(LOG_NOTICE), LOG_UPTO(LOG_EMERG)); break; default: break; } } while (c != '\003' && c != 'Q'); syslog(LOG_NOTICE, "Sample program ends."); kernel_exit(); }