📄 time_event.c
字号:
/* * TOPPERS/JSP Kernel * Toyohashi Open Platform for Embedded Real-Time Systems/ * Just Standard Profile Kernel * * Copyright (C) 2000,2001 by Embedded and Real-Time Systems Laboratory * Toyohashi Univ. of Technology, JAPAN * * 惧淡螟侯涪荚は·Free Software Foundation によって给山されている * GNU General Public License の Version 2 に淡揭されている掘凤か·笆 * 布の(1)×(4)の掘凤を塔たす眷圭に嘎り·塑ソフトウェア∈塑ソフトウェ * アを猖恃したものを崔むˉ笆布票じ∷を蝗脱ˇ剩澜ˇ猖恃ˇ浩芹邵∈笆布· * 网脱と钙ぶ∷することを痰浸で钓满するˉ * (1) 塑ソフトウェアをソ〖スコ〖ドの妨で网脱する眷圭には·惧淡の螟侯 * 涪山绩·この网脱掘凤および布淡の痰瘦沮惮年が·そのままの妨でソ〖 * スコ〖ド面に崔まれていることˉ * (2) 塑ソフトウェアを浩网脱材墙なバイナリコ〖ド∈リロケ〖タブルオブ * ジェクトファイルやライブラリなど∷の妨で网脱する眷圭には·网脱 * に燃うドキュメント∈网脱荚マニュアルなど∷に·惧淡の螟侯涪山绩· * この网脱掘凤および布淡の痰瘦沮惮年を非很することˉ * (3) 塑ソフトウェアを浩网脱稍材墙なバイナリコ〖ドの妨または怠达に寥 * み哈んだ妨で网脱する眷圭には·肌のいずれかの掘凤を塔たすことˉ * (a) 网脱に燃うドキュメント∈网脱荚マニュアルなど∷に·惧淡の螟侯 * 涪山绩·この网脱掘凤および布淡の痰瘦沮惮年を非很することˉ * (b) 网脱の妨轮を·侍に年める数恕によって·惧淡螟侯涪荚に鼠桂する * ことˉ * (4) 塑ソフトウェアの网脱により木儡弄または粗儡弄に栏じるいかなる禄 * 巢からも·惧淡螟侯涪荚を倘勒することˉ * * 塑ソフトウェアは·痰瘦沮で捏丁されているものであるˉ惧淡螟侯涪荚は· * 塑ソフトウェアに簇して·その努脱材墙拉も崔めて·いかなる瘦沮も乖わ * ないˉまた·塑ソフトウェアの网脱により木儡弄または粗儡弄に栏じたい * かなる禄巢に簇しても·その勒扦を砷わないˉ * * @(#) $Id: time_event.c,v 1.4 2002/03/26 08:19:38 hiro Exp $ *//* * タイムイベント瓷妄モジュ〖ル */#include "jsp_kernel.h"#include "check.h"#include "time_event.h"/* * システム箕癸のオフセット */SYSTIM systim_offset;/* * 附哼のシステム箕癸∈帽疤: ミリ擅∷ * * 阜泰には·涟のタイムティックのシステム箕癸ˉ */SYSTIM current_time;/* * 肌のタイムティックのシステム箕癸∈帽疤: 1ミリ擅∷ */SYSTIM next_time;/* * システム箕癸姥换脱恃眶∈帽疤: 1/TIM_DENOミリ擅∷ */#if TIC_DENO != 1UINT next_subtime;#endif /* TIC_DENO != 1 *//* * 陵滦箕粗のベ〖ス箕癸∈帽疤: 1ミリ擅∷ */#if TIC_DENO != 1EVTTIM base_time;#endif /* TIC_DENO != 1 *//* * タイムイベントヒ〖プの呵稿の蝗脱挝拌のインデックス * * タイムイベントヒ〖プに判峡されているタイムイベントの眶に办米するˉ */static UINT last_index;/* * タイムイベントヒ〖プ拎侯マクロ */#define PARENT(index) ((index) >> 1) /* 科ノ〖ドを滇める */#define LCHILD(index) ((index) << 1) /* 宝の灰ノ〖ドを滇める */#define TMEVT_NODE(index) (tmevt_heap[(index) - 1])/* * イベント券栏箕癸孺秤マクロ * * イベント券栏箕癸は·current_time からの陵滦猛で孺秤するˉすなわち· * current_time を呵井猛∈呵も夺い箕癸∷·current_time - 1 が呵络猛 * ∈呵も斌い箕癸∷とみなして孺秤するˉ */#define EVTTIM_LT(t1, t2) (((t1) - current_time) < ((t2) - current_time))#define EVTTIM_LE(t1, t2) (((t1) - current_time) <= ((t2) - current_time))/* * タイマモジュ〖ルの介袋步 */voidtmevt_initialize(){ systim_offset = 0; current_time = 0;#if TIC_DENO == 1 next_time = current_time + TIC_NUME;#else /* TIC_DENO == 1 */ next_subtime += TIC_NUME; next_time = current_time + next_subtime / TIC_DENO; next_subtime %= TIC_DENO; base_time = (EVTTIM)(next_time + (next_subtime > 0 ? 1 : 0));#endif /* TIC_DENO == 1 */ last_index = 0;}/* * タイムイベントの赁掐疤弥を惧羹きに玫瑚 * * 箕癸 time に券栏するタイムイベントを赁掐するノ〖ドを鄂けるために· * ヒ〖プの惧に羹かって鄂ノ〖ドを败瓢させるˉ败瓢涟の鄂ノ〖ドの疤弥を * index に畔すと·败瓢稿の鄂ノ〖ドの疤弥∈すなわち赁掐疤弥∷を手すˉ */static UINTtmevt_up(UINT index, EVTTIM time){ UINT parent; while (index > 1) { /* * 科ノ〖ドのイベント券栏箕癸の数が玲い∈または票じ∷ * ならば·index が赁掐疤弥なのでル〖プを却けるˉ */ parent = PARENT(index); if (EVTTIM_LE(TMEVT_NODE(parent).time, time)) { break; } /* * 科ノ〖ドを index の疤弥に败瓢させるˉ */ TMEVT_NODE(index) = TMEVT_NODE(parent); TMEVT_NODE(index).tmevtb->index = index; /* * index を科ノ〖ドの疤弥に构糠ˉ */ index = parent; } return(index);}/* * タイムイベントの赁掐疤弥を布羹きに玫瑚 * * 箕癸 time に券栏するタイムイベントを赁掐するノ〖ドを鄂けるために· * ヒ〖プの布に羹かって鄂ノ〖ドを败瓢させるˉ败瓢涟の鄂ノ〖ドの疤弥を * index に畔すと·败瓢稿の鄂ノ〖ドの疤弥∈すなわち赁掐疤弥∷を手すˉ */static UINTtmevt_down(UINT index, EVTTIM time){ UINT child; while ((child = LCHILD(index)) <= last_index) { /* * 焊宝の灰ノ〖ドのイベント券栏箕癸を孺秤し·玲い数の * 灰ノ〖ドの疤弥を child に肋年するˉ笆布の灰ノ〖ド * は·ここで联ばれた数の灰ノ〖ドのことˉ */ if (child + 1 <= last_index && EVTTIM_LT(TMEVT_NODE(child + 1).time, TMEVT_NODE(child).time)) { child = child + 1; } /* * 灰ノ〖ドのイベント券栏箕癸の数が觅い∈または票じ∷ * ならば·index が赁掐疤弥なのでル〖プを却けるˉ */ if (EVTTIM_LE(time, TMEVT_NODE(child).time)) { break; } /* * 灰ノ〖ドを index の疤弥に败瓢させるˉ */ TMEVT_NODE(index) = TMEVT_NODE(child); TMEVT_NODE(index).tmevtb->index = index; /* * index を灰ノ〖ドの疤弥に构糠ˉ */ index = child; } return(index);}/* * タイムイベントヒ〖プへの判峡 * * タイムイベントブロック tmevtb を·time で回年した箕粗が沸册稿にイ * ベントが券栏するように·タイムイベントヒ〖プに判峡するˉ */voidtmevtb_insert(TMEVTB *tmevtb, EVTTIM time){ UINT index; /* * last_index をインクリメントし·そこから惧に赁掐疤弥を玫すˉ */ index = tmevt_up(++last_index, time); /* * タイムイベントを index の疤弥に赁掐するˉ */ TMEVT_NODE(index).time = time; TMEVT_NODE(index).tmevtb = tmevtb; tmevtb->index = index;}/* * タイムイベントヒ〖プからの猴近 */voidtmevtb_delete(TMEVTB *tmevtb){ UINT index = tmevtb->index; UINT parent; EVTTIM event_time = TMEVT_NODE(last_index).time; /* * 猴近によりタイムイベントヒ〖プが鄂になる眷圭は部もしないˉ */ if (--last_index == 0) { return; } /* * 猴近したノ〖ドの疤弥に呵稿のノ〖ド∈last_index + 1 の疤弥 * のノ〖ド∷を赁掐し·それを努磊な疤弥へ败瓢させるˉ悸狠には· * 呵稿のノ〖ドを悸狠に赁掐するのではなく·猴近したノ〖ドの疤 * 弥が鄂ノ〖ドになるので·呵稿のノ〖ドを赁掐すべき疤弥へ羹け * て鄂ノ〖ドを败瓢させるˉ * 呵稿のノ〖ドのイベント券栏箕癸が·猴近したノ〖ドの科ノ〖ド * のイベント券栏箕癸より涟の眷圭には·惧に羹かって赁掐疤弥を * 玫すˉそうでない眷圭には·布に羹かって玫すˉ */ if (index > 1 && EVTTIM_LT(event_time, TMEVT_NODE(parent = PARENT(index)).time)) { /* * 科ノ〖ドを index の疤弥に败瓢させるˉ */ TMEVT_NODE(index) = TMEVT_NODE(parent); TMEVT_NODE(index).tmevtb->index = index; /* * 猴近したノ〖ドの科ノ〖ドから惧に羹かって赁掐疤弥を * 玫すˉ */ index = tmevt_up(parent, event_time); } else { /* * 猴近したノ〖ドから布に羹かって赁掐疤弥を玫すˉ */ index = tmevt_down(index, event_time); } /* * 呵稿のノ〖ドを index の疤弥に赁掐するˉ */ TMEVT_NODE(index) = TMEVT_NODE(last_index + 1); TMEVT_NODE(index).tmevtb->index = index;}/* * タイムイベントヒ〖プの黎片のノ〖ドの猴近 */Inline voidtmevtb_delete_top(){ UINT index; EVTTIM event_time = TMEVT_NODE(last_index).time; /* * 猴近によりタイムイベントヒ〖プが鄂になる眷圭は部もしないˉ */ if (--last_index == 0) { return; } /* * ル〖トノ〖ドに呵稿のノ〖ド∈last_index + 1 の疤弥のノ〖ド∷ * を赁掐し·それを努磊な疤弥へ败瓢させるˉ悸狠には·呵稿のノ〖 * ドを悸狠に赁掐するのではなく·ル〖トノ〖ドが鄂ノ〖ドになる * ので·呵稿のノ〖ドを赁掐すべき疤弥へ羹けて鄂ノ〖ドを败瓢さ * せるˉ */ index = tmevt_down(1, event_time); /* * 呵稿のノ〖ドを index の疤弥に赁掐するˉ */ TMEVT_NODE(index) = TMEVT_NODE(last_index + 1); TMEVT_NODE(index).tmevtb->index = index;}/* * タイムティックの丁惦 * * TIC_NUME < TIC_DENO の箕は·近换を蝗わずに箕癸の构糠ができるが·ソ〖 * スコ〖ドを粕みやすくにするために #if の驴脱を闰けているˉ */SYSCALL ERisig_tim(){ TMEVTB *tmevtb; CHECK_INTCTX_UNL(); i_lock_cpu(); /* * next_time よりイベント券栏箕癸の玲い∈または票じ∷タイムイ * ベントを·タイムイベントヒ〖プから猴近し·コ〖ルバック簇眶 * を钙び叫すˉ */ while (last_index > 0 && EVTTIM_LE(TMEVT_NODE(1).time, next_time)) { tmevtb = TMEVT_NODE(1).tmevtb; tmevtb_delete_top(); (*(tmevtb->callback))(tmevtb->arg); /* * ここで庭黎刨の光い充哈みを减け烧けるˉ */ i_unlock_cpu(); i_lock_cpu(); } /* * current_time を构糠するˉ */ current_time = next_time; /* * next_time·next_subtime·base_time を构糠するˉ */#if TIC_DENO == 1 next_time = current_time + TIC_NUME;#else /* TIC_DENO == 1 */ next_subtime += TIC_NUME; next_time = current_time + next_subtime / TIC_DENO; next_subtime %= TIC_DENO; base_time = (EVTTIM)(next_time + (next_subtime > 0 ? 1 : 0));#endif /* TIC_DENO == 1 */ i_unlock_cpu(); return(E_OK);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -