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

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

TECSレスのASP3の開発のため以下のtrunkからコピー
http://dev.toppers.jp/svn/asp3/branches/WO_TECS-3.C.0

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