source: asp3_wo_tecs/trunk/extension/drift/kernel/time_event.c@ 306

Last change on this file since 306 was 306, checked in by ertl-honda, 7 years ago

3.1.0を反映

File size: 18.7 KB
Line 
1/*
2 * TOPPERS/ASP Kernel
3 * Toyohashi Open Platform for Embedded Real-Time Systems/
4 * Advanced Standard Profile Kernel
5 *
6 * Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
7 * Toyohashi Univ. of Technology, JAPAN
8 * Copyright (C) 2005-2016 by Embedded and Real-Time Systems Laboratory
9 * Graduate School of Information Science, Nagoya Univ., JAPAN
10 *
11 * 上記著作権者
12は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
13 * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
14 * 変・再é…
15å¸ƒï¼ˆä»¥ä¸‹ï¼Œåˆ©ç”¨ã¨å‘¼ã¶ï¼‰ã™ã‚‹ã“とを無償で許諾する.
16 * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
17 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
18 * スコード中に含まれていること.
19 * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
20 * 用できる形で再é…
21å¸ƒã™ã‚‹å ´åˆã«ã¯ï¼Œå†é…
22å¸ƒã«ä¼´ã†ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆï¼ˆåˆ©ç”¨
23 * 者
24マニュアルなど)に,上記の著作権表示,この利用条件および下記
25 * の無保証規定を掲載すること.
26 * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
27 * 用できない形で再é…
28å¸ƒã™ã‚‹å ´åˆã«ã¯ï¼Œæ¬¡ã®ã„ずれかの条件を満たすこ
29 * と.
30 * (a) 再é…
31å¸ƒã«ä¼´ã†ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆï¼ˆåˆ©ç”¨è€…
32マニュアルなど)に,上記の著
33 * 作権表示,この利用条件および下記の無保証規定を掲載すること.
34 * (b) 再é…
35å¸ƒã®å½¢æ…
36‹ã‚’,別に定める方法によって,TOPPERSプロジェクトに
37 * 報告すること.
38 * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
39 * 害からも,上記著作権者
40およびTOPPERSプロジェクトをå…
41è²¬ã™ã‚‹ã“と.
42 * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
43 * 由に基づく請求からも,上記著作権者
44およびTOPPERSプロジェクトを
45 * å…
46è²¬ã™ã‚‹ã“と.
47 *
48 * 本ソフトウェアは,無保証で提供されているものである.上記著作権者
49お
50 * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
51 * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
52 * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
53 * の責任を負わない.
54 *
55 * $Id: time_event.c 532 2016-01-15 14:48:04Z ertl-hiro $
56 */
57
58/*
59 * タイムイベント管理モジュール
60 */
61
62#include "kernel_impl.h"
63#include "time_event.h"
64
65/*
66 * TSTEP_HRTCNTの範囲チェック
67 */
68#if TSTEP_HRTCNT > 4000U
69#error TSTEP_HRTCNT is too large.
70#endif /* TSTEP_HRTCNT > 4000U */
71
72/*
73 * HRTCNT_BOUNDの範囲チェック
74 */
75#if HRTCNT_BOUND >= 4294000000U
76#error HRTCNT_BOUND is too large.
77#endif /* HRTCNT_BOUND >= 4294000000U */
78
79#ifdef TCYC_HRTCNT
80#if HRTCNT_BOUND >= TCYC_HRTCNT
81#error HRTCNT_BOUND is too large.
82#endif /* HRTCNT_BOUND >= TCYC_HRTCNT */
83#endif /* TCYC_HRTCNT */
84
85/*
86 * タイムイベントヒープ操作マクロ
87 */
88#define PARENT(p_tmevtn) (tmevt_heap + (((p_tmevtn) - tmevt_heap) >> 1))
89 /* 親ノードを求める */
90#define LCHILD(p_tmevtn) (tmevt_heap + (((p_tmevtn) - tmevt_heap) << 1))
91 /* 左の子ノードを求める */
92/*
93 * タイムイベントヒープ中のå…
94ˆé ­ã®ãƒŽãƒ¼ãƒ‰
95 */
96#define p_top_tmevtn (&(tmevt_heap[1]))
97#define top_evttim (tmevt_heap[1].p_tmevtb->evttim)
98 /* å…
99ˆé ­ã®ã‚¿ã‚¤ãƒ ã‚¤ãƒ™ãƒ³ãƒˆã®ç™ºç”Ÿæ™‚刻 */
100/*
101 * タイムイベントヒープ中の最後のノード
102 */
103#define p_last_tmevtn (tmevt_heap[0].p_last)
104
105/*
106 * イベント時刻の前後関係の判定[ASPD1009]
107 *
108 * イベント時刻は,boundary_evttimからの相対値で比較する.すなわち,
109 * boundary_evttimを最も早い時刻,boundary_evttim−1が最も遅
110い時刻とみ
111 * なして比較する.
112 */
113#define EVTTIM_ADVANCE(t) ((t) - boundary_evttim)
114#define EVTTIM_LT(t1, t2) (EVTTIM_ADVANCE(t1) < EVTTIM_ADVANCE(t2))
115#define EVTTIM_LE(t1, t2) (EVTTIM_ADVANCE(t1) <= EVTTIM_ADVANCE(t2))
116
117#ifdef TOPPERS_tmeini
118
119/*
120 * 境界イベント時刻[ASPD1008]
121 */
122EVTTIM boundary_evttim;
123
124/*
125 * 最後に現在時刻を算出した時点でのイベント時刻[ASPD1012]
126 */
127EVTTIM current_evttim; /* 現在のイベント時刻 */
128uint32_t current_evttim_frac; /* 現在のイベント時刻の端数 */
129
130/*
131 * 最後に現在時刻を算出した時点での高分解能タイマのカウント値[ASPD1012]
132 */
133HRTCNT current_hrtcnt;
134
135/*
136 * 最も進んでいた時のイベント時刻[ASPD1041]
137 */
138EVTTIM monotonic_evttim;
139
140/*
141 * ドリフト率
142 */
143uint32_t drift_rate;
144
145/*
146 * イベント時間を遅
147い方に丸めるための補正値
148 */
149EVTTIM evttim_step;
150uint32_t evttim_step_frac;
151
152/*
153 * システム時刻のオフセット[ASPD1043]
154 */
155SYSTIM systim_offset;
156
157/*
158 * 高分解能タイマ割込みの処理中であることを示すフラグ[ASPD1032]
159 */
160bool_t in_signal_time;
161
162/*
163 * タイムイベント管理モジュールの初期化[ASPD1061]
164 */
165void
166initialize_tmevt(void)
167{
168 current_evttim = 0U; /*ï¼»ASPD1047ï¼½*/
169 current_evttim_frac = 0U;
170 boundary_evttim = current_evttim - BOUNDARY_MARGIN;
171 /*ï¼»ASPD1048ï¼½*/
172 monotonic_evttim = 0U; /*ï¼»ASPD1046ï¼½*/
173 drift_rate = 1000000U;
174 evttim_step = (EVTTIM) TSTEP_HRTCNT;
175 evttim_step_frac = 999999U;
176 systim_offset = 0U; /*ï¼»ASPD1044ï¼½*/
177 in_signal_time = false; /*ï¼»ASPD1033ï¼½*/
178 p_last_tmevtn = tmevt_heap;
179}
180
181#endif /* TOPPERS_tmeini */
182
183/*
184 * タイムイベントの挿å…
185¥ä½ç½®ã‚’上向きに探索
186 *
187 * 時刻evttimに発生するタイムイベントを挿å…
188¥ã™ã‚‹ãƒŽãƒ¼ãƒ‰ã‚’空けるために,
189 * ヒープの上に向かって空ノードを移動させる.移動前の空ノードの位置を
190 * p_tmevtnに渡すと,移動後の空ノードの位置(すなわち挿å…
191¥ä½ç½®ï¼‰ã‚’返す.
192 */
193#ifdef TOPPERS_tmeup
194
195TMEVTN *
196tmevt_up(TMEVTN *p_tmevtn, EVTTIM evttim)
197{
198 TMEVTN *p_parent;
199
200 while (p_tmevtn > p_top_tmevtn) {
201 /*
202 * 親ノードのイベント発生時刻の方が早い(または同じ)ならば,
203 * p_tmevtnが挿å…
204¥ä½ç½®ãªã®ã§ãƒ«ãƒ¼ãƒ—を抜ける.
205 */
206 p_parent = PARENT(p_tmevtn);
207 if (EVTTIM_LE(p_parent->p_tmevtb->evttim, evttim)) {
208 break;
209 }
210
211 /*
212 * 親ノードをp_tmevtnの位置に移動させる.
213 */
214 *p_tmevtn = *p_parent;
215 p_tmevtn->p_tmevtb->p_tmevtn = p_tmevtn;
216
217 /*
218 * p_tmevtnを親ノードの位置に更新.
219 */
220 p_tmevtn = p_parent;
221 }
222 return(p_tmevtn);
223}
224
225#endif /* TOPPERS_tmeup */
226
227/*
228 * タイムイベントの挿å…
229¥ä½ç½®ã‚’下向きに探索
230 *
231 * 時刻evttimに発生するタイムイベントを挿å…
232¥ã™ã‚‹ãƒŽãƒ¼ãƒ‰ã‚’空けるために,
233 * ヒープの下に向かって空ノードを移動させる.移動前の空ノードの位置を
234 * p_tmevtnに渡すと,移動後の空ノードの位置(すなわち挿å…
235¥ä½ç½®ï¼‰ã‚’返す.
236 */
237#ifdef TOPPERS_tmedown
238
239TMEVTN *
240tmevt_down(TMEVTN *p_tmevtn, EVTTIM evttim)
241{
242 TMEVTN *p_child;
243
244 while ((p_child = LCHILD(p_tmevtn)) <= p_last_tmevtn) {
245 /*
246 * 左右の子ノードのイベント発生時刻を比較し,早い方の子ノード
247 * の位置をp_childに設定する.以下の子ノードは,ここで選ばれた
248 * 方の子ノードのこと.
249 */
250 if (p_child + 1 <= p_last_tmevtn
251 && EVTTIM_LT((p_child + 1)->p_tmevtb->evttim,
252 p_child->p_tmevtb->evttim)) {
253 p_child = p_child + 1;
254 }
255
256 /*
257 * 子ノードのイベント発生時刻の方が遅
258い(または同じ)ならば,
259 * p_tmevtnが挿å…
260¥ä½ç½®ãªã®ã§ãƒ«ãƒ¼ãƒ—を抜ける.
261 */
262 if (EVTTIM_LE(evttim, p_child->p_tmevtb->evttim)) {
263 break;
264 }
265
266 /*
267 * 子ノードをp_tmevtnの位置に移動させる.
268 */
269 *p_tmevtn = *p_child;
270 p_tmevtn->p_tmevtb->p_tmevtn = p_tmevtn;
271
272 /*
273 * p_tmevtnを子ノードの位置に更新.
274 */
275 p_tmevtn = p_child;
276 }
277 return(p_tmevtn);
278}
279
280#endif /* TOPPERS_tmedown */
281
282/*
283 * タイムイベントヒープへの追加
284 *
285 * p_tmevtbで指定したタイムイベントブロックを,タイムイベントヒープに
286 * 追加する.
287 */
288Inline void
289tmevtb_insert(TMEVTB *p_tmevtb)
290{
291 TMEVTN *p_tmevtn;
292
293 /*
294 * p_last_tmevtnをインクリメントし,そこから上に挿å…
295¥ä½ç½®ã‚’探す.
296 */
297 p_tmevtn = tmevt_up(++p_last_tmevtn, p_tmevtb->evttim);
298
299 /*
300 * タイムイベントをp_tmevtnの位置に挿å…
301¥ã™ã‚‹ï¼Ž
302 */
303 p_tmevtn->p_tmevtb = p_tmevtb;
304 p_tmevtb->p_tmevtn = p_tmevtn;
305}
306
307/*
308 * タイムイベントヒープからの削除
309 */
310Inline void
311tmevtb_delete(TMEVTB *p_tmevtb)
312{
313 TMEVTN *p_tmevtn = p_tmevtb->p_tmevtn;
314 TMEVTN *p_parent;
315 EVTTIM event_evttim;
316
317 /*
318 * 削除によりタイムイベントヒープが空になる場合は何もしない.
319 */
320 if (--p_last_tmevtn < p_top_tmevtn) {
321 return;
322 }
323
324 /*
325 * 削除したノードの位置に最後のノード(p_last_tmevtn + 1 の位置の
326 * ノード)を挿å…
327¥ã—,それを適切な位置へ移動させる.実際には,最後
328 * のノードを実際に挿å…
329¥ã™ã‚‹ã®ã§ã¯ãªãï¼Œå‰Šé™¤ã—たノードの位置が空ノー
330 * ドになるので,最後のノードを挿å…
331¥ã™ã¹ãä½ç½®ã¸å‘けて空ノードを移
332 * 動させる.
333 *
334 * 最後のノードのイベント発生時刻が,削除したノードの親ノードのイ
335 * ベント発生時刻より前の場合には,上に向かって挿å…
336¥ä½ç½®ã‚’探す.そ
337 * うでない場合には,下に向かって探す.
338 */
339 event_evttim = (p_last_tmevtn + 1)->p_tmevtb->evttim;
340 if (p_tmevtn > p_top_tmevtn
341 && EVTTIM_LT(event_evttim,
342 (p_parent = PARENT(p_tmevtn))->p_tmevtb->evttim)) {
343 /*
344 * 親ノードをp_tmevtnの位置に移動させる.
345 */
346 *p_tmevtn = *p_parent;
347 p_tmevtn->p_tmevtb->p_tmevtn = p_tmevtn;
348
349 /*
350 * 削除したノードの親ノードから上に向かって挿å…
351¥ä½ç½®ã‚’探す.
352 */
353 p_tmevtn = tmevt_up(p_parent, event_evttim);
354 }
355 else {
356 /*
357 * 削除したノードから下に向かって挿å…
358¥ä½ç½®ã‚’探す.
359 */
360 p_tmevtn = tmevt_down(p_tmevtn, event_evttim);
361 }
362
363 /*
364 * 最後のノードをp_tmevtnの位置に挿å…
365¥ã™ã‚‹ï¼Ž
366 */
367 *p_tmevtn = *(p_last_tmevtn + 1);
368 p_tmevtn->p_tmevtb->p_tmevtn = p_tmevtn;
369}
370
371/*
372 * タイムイベントヒープのå…
373ˆé ­ã®ãƒŽãƒ¼ãƒ‰ã®å‰Šé™¤
374 */
375Inline TMEVTB *
376tmevtb_delete_top(void)
377{
378 TMEVTN *p_tmevtn;
379 TMEVTB *p_top_tmevtb = p_top_tmevtn->p_tmevtb;
380 EVTTIM event_evttim;
381
382 /*
383 * 削除によりタイムイベントヒープが空になる場合は何もしない.
384 */
385 if (--p_last_tmevtn >= p_top_tmevtn) {
386 /*
387 * ルートノードに最後のノード(p_last_tmevtn + 1 の位置のノー
388 * ド)を挿å…
389¥ã—,それを適切な位置へ移動させる.実際には,最後
390 * のノードを実際に挿å…
391¥ã™ã‚‹ã®ã§ã¯ãªãï¼Œãƒ«ãƒ¼ãƒˆãƒŽãƒ¼ãƒ‰ãŒç©ºãƒŽãƒ¼ãƒ‰
392 * になるので,最後のノードを挿å…
393¥ã™ã¹ãä½ç½®ã¸å‘けて空ノードを
394 * 移動させる.
395 */
396 event_evttim = (p_last_tmevtn + 1)->p_tmevtb->evttim;
397 p_tmevtn = tmevt_down(p_top_tmevtn, event_evttim);
398
399 /*
400 * 最後のノードをp_tmevtnの位置に挿å…
401¥ã™ã‚‹ï¼Ž
402 */
403 *p_tmevtn = *(p_last_tmevtn + 1);
404 p_tmevtn->p_tmevtb->p_tmevtn = p_tmevtn;
405 }
406 return(p_top_tmevtb);
407}
408
409/*
410 * 現在のイベント時刻の更新
411 */
412#ifdef TOPPERS_tmecur
413
414void
415update_current_evttim(void)
416{
417 HRTCNT new_hrtcnt, hrtcnt_advance;
418 EVTTIM previous_evttim, evttim_advance;
419
420 new_hrtcnt = target_hrt_get_current(); /*ï¼»ASPD1013ï¼½*/
421 hrtcnt_advance = new_hrtcnt - current_hrtcnt; /*ï¼»ASPD1014ï¼½*/
422#ifdef TCYC_HRTCNT
423 if (new_hrtcnt < current_hrtcnt) {
424 hrtcnt_advance += TCYC_HRTCNT;
425 }
426#endif /* TCYC_HRTCNT */
427
428#ifdef USE_64BIT_OPS
429 evttim_advance = ((uint64_t) hrtcnt_advance) * drift_rate / 1000000U;
430 current_evttim_frac += ((uint64_t) hrtcnt_advance) * drift_rate % 1000000U;
431 if (current_evttim_frac >= 1000000U) {
432 evttim_advance += 1U;
433 current_evttim_frac -= 1000000U;
434 }
435#else /* USE_64BIT_OPS */
436 {
437 uint32_t s1, c1, s2, c2, s3;
438
439 s1 = hrtcnt_advance / 1000000U * drift_rate;
440 c1 = hrtcnt_advance % 1000000U;
441 s2 = c1 / 1000U * drift_rate;
442 c2 = c1 % 1000U;
443 s3 = c2 * drift_rate;
444 evttim_advance = s1 + s2 / 1000 + s3 / 1000000U;
445 current_evttim_frac += s2 % 1000U * 1000U + s3 % 1000000U;
446 }
447 if (current_evttim_frac >= 2000000U) {
448 evttim_advance += 2U;
449 current_evttim_frac -= 2000000U;
450 }
451 else if (current_evttim_frac >= 1000000U) {
452 evttim_advance += 1U;
453 current_evttim_frac -= 1000000U;
454 }
455#endif /* USE_64BIT_OPS */
456
457 previous_evttim = current_evttim;
458 current_evttim += evttim_advance;
459 current_hrtcnt = new_hrtcnt; /*ï¼»ASPD1016ï¼½*/
460 boundary_evttim = current_evttim - BOUNDARY_MARGIN; /*ï¼»ASPD1011ï¼½*/
461
462 if (monotonic_evttim - previous_evttim < evttim_advance) {
463#ifdef UINT64_MAX
464 if (current_evttim < monotonic_evttim) {
465 systim_offset += 1LLU << 32; /*ï¼»ASPD1045ï¼½*/
466 }
467#endif /* UINT64_MAX */
468 monotonic_evttim = current_evttim; /*ï¼»ASPD1042ï¼½*/
469 }
470}
471
472#endif /* TOPPERS_tmecur */
473
474/*
475 * 現在のイベント時刻を遅
476い方に丸めたイベント時刻の算出[ASPD1027]
477 *
478 * 現在のイベント時刻を更新した後に呼ぶことを想定している.
479 */
480Inline EVTTIM
481calc_current_evttim_ub(void)
482{
483 EVTTIM current_evttim_ub;
484
485 current_evttim_ub = current_evttim + evttim_step;
486 if (current_evttim_frac + evttim_step_frac >= 1000000U) {
487 current_evttim_ub += 1U;
488 }
489 return(current_evttim_ub);
490}
491
492/*
493 * 高分解能タイマ割込みの発生タイミングの設定
494 */
495#ifdef TOPPERS_tmeset
496
497void
498set_hrt_event(void)
499{
500 EVTTIM evttim_advance;
501 HRTCNT hrtcnt;
502
503 if (p_last_tmevtn >= p_top_tmevtn
504 && EVTTIM_LE(top_evttim, current_evttim)) {
505 target_hrt_raise_event();
506 }
507 else {
508 if (p_last_tmevtn >= p_top_tmevtn) {
509 evttim_advance = top_evttim - current_evttim;
510 }
511 else {
512 evttim_advance = TMAX_RELTIM;
513 }
514
515#ifdef USE_64BIT_OPS
516 hrtcnt = (((uint64_t) evttim_advance) * 1000000U
517 - current_evttim_frac + drift_rate - 1U) / drift_rate;
518 if (hrtcnt > HRTCNT_BOUND) {
519 hrtcnt = HRTCNT_BOUND;
520 }
521#else /* USE_64BIT_OPS */
522 {
523 uint32_t c1, s1, c2, s2, c3;
524
525 c1 = evttim_advance / drift_rate;
526 if (c1 > HRTCNT_BOUND / 1000000U) {
527 hrtcnt = HRTCNT_BOUND;
528 }
529 else {
530 s1 = evttim_advance % drift_rate * 1000U;
531 c2 = s1 / drift_rate;
532 s2 = s1 % drift_rate * 1000U + (drift_rate - 1U);
533 if (s2 >= current_evttim_frac) {
534 c3 = (s2 - current_evttim_frac) / drift_rate;
535 hrtcnt = c1 * 1000000U + c2 * 1000U + c3;
536 }
537 else {
538 hrtcnt = c1 * 1000000U + c2 * 1000U - 1U;
539 }
540 if (hrtcnt > HRTCNT_BOUND) {
541 hrtcnt = HRTCNT_BOUND;
542 }
543 }
544 }
545#endif /* USE_64BIT_OPS */
546 target_hrt_set_event(hrtcnt);
547 }
548}
549
550#endif /* TOPPERS_tmeset */
551
552/*
553 * タイムイベントブロックのヒープへの挿å…
554¥
555 */
556#ifdef TOPPERS_tmereg
557
558void
559tmevtb_register(TMEVTB *p_tmevtb)
560{
561 tmevtb_insert(p_tmevtb);
562}
563
564#endif /* TOPPERS_tmereg */
565
566/*
567 * 相対時間指定によるタイムイベントの登録
568 *
569 */
570#ifdef TOPPERS_tmeenq
571
572void
573tmevtb_enqueue(TMEVTB *p_tmevtb, RELTIM time)
574{
575 /*
576 * 現在のイベント時刻とタイムイベントの発生時刻を求める[ASPD1026].
577 */
578 update_current_evttim();
579 p_tmevtb->evttim = calc_current_evttim_ub() + time;
580
581 /*
582 * タイムイベントブロックをヒープに挿å…
583¥ã™ã‚‹ï¼»ASPD1030].
584 */
585 tmevtb_insert(p_tmevtb);
586
587 /*
588 * 高分解能タイマ割込みの発生タイミングを設定する[ASPD1031]
589 * [ASPD1034].
590 */
591 if (!in_signal_time && p_tmevtb->p_tmevtn == p_top_tmevtn) {
592 set_hrt_event();
593 }
594}
595
596#endif /* TOPPERS_tmeenq */
597
598/*
599 * タイムイベントの登録解除
600 */
601#ifdef TOPPERS_tmedeq
602
603void
604tmevtb_dequeue(TMEVTB *p_tmevtb)
605{
606 TMEVTN *p_tmevtn;
607
608 /*
609 * タイムイベントブロックをヒープから削除する[ASPD1039].
610 */
611 p_tmevtn = p_tmevtb->p_tmevtn;
612 tmevtb_delete(p_tmevtb);
613
614 /*
615 * 高分解能タイマ割込みの発生タイミングを設定する[ASPD1040].
616 */
617 if (!in_signal_time && p_tmevtn == p_top_tmevtn) {
618 update_current_evttim();
619 set_hrt_event();
620 }
621}
622
623#endif /* TOPPERS_tmedeq */
624
625/*
626 * システム時刻の調整時のエラーチェック
627 */
628#ifdef TOPPERS_tmechk
629
630bool_t
631check_adjtim(int_t adjtim)
632{
633 if (adjtim > 0) {
634 return(p_last_tmevtn >= p_top_tmevtn /*ï¼»NGKI3588ï¼½*/
635 && EVTTIM_LE(top_evttim, current_evttim - TMAX_ADJTIM));
636 }
637 else if (adjtim < 0) { /*ï¼»NGKI3589ï¼½*/
638 return(monotonic_evttim - current_evttim >= -TMIN_ADJTIM);
639 }
640 return(false);
641}
642
643#endif /* TOPPERS_tmechk */
644
645/*
646 * タイムイベントが発生するまでの時間の計算
647 */
648#ifdef TOPPERS_tmeltim
649
650RELTIM
651tmevt_lefttim(TMEVTB *p_tmevtb)
652{
653 EVTTIM evttim, current_evttim_ub;
654
655 /*
656 * 現在のイベント時刻を遅
657い方に丸めた時刻を求める[ASPD1050].
658 */
659 update_current_evttim();
660 current_evttim_ub = calc_current_evttim_ub();
661
662 /*
663 * タイムイベント発生までの相対時間を求める[ASPD1049].
664 */
665 evttim = p_tmevtb->evttim;
666 if (EVTTIM_LE(evttim, current_evttim_ub)) {
667 /*
668 * タイムイベントの発生時刻を過ぎている場合には0を返す[NGKI0552].
669 */
670 return(0U);
671 }
672 else {
673 return((RELTIM)(evttim - current_evttim_ub));
674 }
675}
676
677#endif /* TOPPERS_tmeltim */
678
679/*
680 * 高分解能タイマ割込みの処理
681 */
682#ifdef TOPPERS_sigtim
683
684void
685signal_time(void)
686{
687 TMEVTB *p_tmevtb;
688 bool_t callflag;
689
690 assert(sense_context());
691 assert(!sense_lock());
692
693 lock_cpu();
694 in_signal_time = true; /*ï¼»ASPD1033ï¼½*/
695
696 do {
697 /*
698 * コールバック関数を呼び出さなければループを抜ける[ASPD1020].
699 */
700 callflag = false;
701
702 /*
703 * 現在のイベント時刻を求める[ASPD1022].
704 */
705 update_current_evttim();
706
707 /*
708 * 発生時刻がcurrent_evttim以前のタイムイベントがあれば,タイ
709 * ムイベントヒープから削除し,コールバック関数を呼び出す
710 * [ASPD1018][ASPD1019].
711 */
712 while (p_last_tmevtn >= p_top_tmevtn
713 && EVTTIM_LE(top_evttim, current_evttim)) {
714 p_tmevtb = tmevtb_delete_top();
715 (*(p_tmevtb->callback))(p_tmevtb->arg);
716 callflag = true;
717 }
718 } while (callflag); /*ï¼»ASPD1020ï¼½*/
719
720 /*
721 * 高分解能タイマ割込みの発生タイミングを設定する[ASPD1025].
722 */
723 set_hrt_event();
724
725 in_signal_time = false; /*ï¼»ASPD1033ï¼½*/
726 unlock_cpu();
727}
728
729#endif /* TOPPERS_sigtim */
Note: See TracBrowser for help on using the repository browser.