source: rubycfg_asp/trunk/asp_dcre/kernel/alarm.c@ 313

Last change on this file since 313 was 313, checked in by coas-nagasima, 7 years ago

ソースを追加

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
  • Property svn:mime-type set to text/x-csrc
File size: 10.9 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-2014 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: alarm.c 313 2017-07-23 04:50:32Z coas-nagasima $
56 */
57
58/*
59 * アラームハンドラ機能
60 */
61
62#include "kernel_impl.h"
63#include "check.h"
64#include "alarm.h"
65
66/*
67 * トレースログマクロのデフォルト定義
68 */
69#ifndef LOG_ALM_ENTER
70#define LOG_ALM_ENTER(p_almcb)
71#endif /* LOG_ALM_ENTER */
72
73#ifndef LOG_ALM_LEAVE
74#define LOG_ALM_LEAVE(p_almcb)
75#endif /* LOG_ALM_LEAVE */
76
77#ifndef LOG_ACRE_ALM_ENTER
78#define LOG_ACRE_ALM_ENTER(pk_calm)
79#endif /* LOG_ACRE_ALM_ENTER */
80
81#ifndef LOG_ACRE_ALM_LEAVE
82#define LOG_ACRE_ALM_LEAVE(ercd)
83#endif /* LOG_ACRE_ALM_LEAVE */
84
85#ifndef LOG_DEL_ALM_ENTER
86#define LOG_DEL_ALM_ENTER(almid)
87#endif /* LOG_DEL_ALM_ENTER */
88
89#ifndef LOG_DEL_ALM_LEAVE
90#define LOG_DEL_ALM_LEAVE(ercd)
91#endif /* LOG_DEL_ALM_LEAVE */
92
93#ifndef LOG_STA_ALM_ENTER
94#define LOG_STA_ALM_ENTER(almid, almtim)
95#endif /* LOG_STA_ALM_ENTER */
96
97#ifndef LOG_STA_ALM_LEAVE
98#define LOG_STA_ALM_LEAVE(ercd)
99#endif /* LOG_STA_ALM_LEAVE */
100
101#ifndef LOG_ISTA_ALM_ENTER
102#define LOG_ISTA_ALM_ENTER(almid, almtim)
103#endif /* LOG_ISTA_ALM_ENTER */
104
105#ifndef LOG_ISTA_ALM_LEAVE
106#define LOG_ISTA_ALM_LEAVE(ercd)
107#endif /* LOG_ISTA_ALM_LEAVE */
108
109#ifndef LOG_STP_ALM_ENTER
110#define LOG_STP_ALM_ENTER(almid)
111#endif /* LOG_STP_ALM_ENTER */
112
113#ifndef LOG_STP_ALM_LEAVE
114#define LOG_STP_ALM_LEAVE(ercd)
115#endif /* LOG_STP_ALM_LEAVE */
116
117#ifndef LOG_ISTP_ALM_ENTER
118#define LOG_ISTP_ALM_ENTER(almid)
119#endif /* LOG_ISTP_ALM_ENTER */
120
121#ifndef LOG_ISTP_ALM_LEAVE
122#define LOG_ISTP_ALM_LEAVE(ercd)
123#endif /* LOG_ISTP_ALM_LEAVE */
124
125#ifndef LOG_REF_ALM_ENTER
126#define LOG_REF_ALM_ENTER(almid, pk_ralm)
127#endif /* LOG_REF_ALM_ENTER */
128
129#ifndef LOG_REF_ALM_LEAVE
130#define LOG_REF_ALM_LEAVE(ercd, pk_ralm)
131#endif /* LOG_REF_ALM_LEAVE */
132
133/*
134 * アラームハンドラの数
135 */
136#define tnum_alm ((uint_t)(tmax_almid - TMIN_ALMID + 1))
137#define tnum_salm ((uint_t)(tmax_salmid - TMIN_ALMID + 1))
138
139/*
140 * アラームハンドラIDからアラームハンドラ管理ブロックを取り出すためのマクロ
141 */
142#define INDEX_ALM(almid) ((uint_t)((almid) - TMIN_ALMID))
143#define get_almcb(almid) (&(almcb_table[INDEX_ALM(almid)]))
144
145#ifdef TOPPERS_almini
146
147/*
148 * 使用していないアラームハンドラ管理ブロックのリスト
149 *
150 * アラームハンドラ管理ブロックのå…
151ˆé ­ã«ã¯ã‚­ãƒ¥ãƒ¼ã«ã¤ãªããŸã‚ã®é ˜åŸŸãŒãª
152 * いため,タイムイベントブロック(tmevtb)の領域を用いる.
153 */
154QUEUE free_almcb;
155
156/*
157 * アラームハンドラ機能の初期化
158 */
159void
160initialize_alarm(void)
161{
162 uint_t i, j;
163 ALMCB *p_almcb;
164 ALMINIB *p_alminib;
165
166 for (i = 0; i < tnum_salm; i++) {
167 p_almcb = &(almcb_table[i]);
168 p_almcb->p_alminib = &(alminib_table[i]);
169 p_almcb->almsta = false;
170 }
171 queue_initialize(&free_almcb);
172 for (j = 0; i < tnum_alm; i++, j++) {
173 p_almcb = &(almcb_table[i]);
174 p_alminib = &(aalminib_table[j]);
175 p_alminib->almatr = TA_NOEXS;
176 p_almcb->p_alminib = ((const ALMINIB *) p_alminib);
177 queue_insert_prev(&free_almcb, ((QUEUE *) &(p_almcb->tmevtb)));
178 }
179}
180
181#endif /* TOPPERS_almini */
182
183/*
184 * アラームハンドラの生成
185 */
186#ifdef TOPPERS_acre_alm
187
188ER_UINT
189acre_alm(const T_CALM *pk_calm)
190{
191 ALMCB *p_almcb;
192 ALMINIB *p_alminib;
193 ER ercd;
194
195 LOG_ACRE_ALM_ENTER(pk_calm);
196 CHECK_TSKCTX_UNL();
197 CHECK_RSATR(pk_calm->almatr, TA_NULL);
198 CHECK_ALIGN_FUNC(pk_calm->almhdr);
199 CHECK_NONNULL_FUNC(pk_calm->almhdr);
200
201 t_lock_cpu();
202 if (tnum_alm == 0 || queue_empty(&free_almcb)) {
203 ercd = E_NOID;
204 }
205 else {
206 p_almcb = ((ALMCB *)(((char *) queue_delete_next(&free_almcb))
207 - offsetof(ALMCB, tmevtb)));
208 p_alminib = (ALMINIB *)(p_almcb->p_alminib);
209 p_alminib->almatr = pk_calm->almatr;
210 p_alminib->exinf = pk_calm->exinf;
211 p_alminib->almhdr = pk_calm->almhdr;
212
213 p_almcb->almsta = false;
214 ercd = ALMID(p_almcb);
215 }
216 t_unlock_cpu();
217
218 error_exit:
219 LOG_ACRE_ALM_LEAVE(ercd);
220 return(ercd);
221}
222
223#endif /* TOPPERS_acre_alm */
224
225/*
226 * アラームハンドラの削除
227 */
228#ifdef TOPPERS_del_alm
229
230ER
231del_alm(ID almid)
232{
233 ALMCB *p_almcb;
234 ALMINIB *p_alminib;
235 ER ercd;
236
237 LOG_DEL_ALM_ENTER(almid);
238 CHECK_TSKCTX_UNL();
239 CHECK_ALMID(almid);
240 p_almcb = get_almcb(almid);
241
242 t_lock_cpu();
243 if (p_almcb->p_alminib->almatr == TA_NOEXS) {
244 ercd = E_NOEXS;
245 }
246 else if (ALMID(p_almcb) > tmax_salmid) {
247 if (p_almcb->almsta) {
248 p_almcb->almsta = false;
249 tmevtb_dequeue(&(p_almcb->tmevtb));
250 }
251
252 p_alminib = (ALMINIB *)(p_almcb->p_alminib);
253 p_alminib->almatr = TA_NOEXS;
254 queue_insert_prev(&free_almcb, ((QUEUE *) &(p_almcb->tmevtb)));
255 ercd = E_OK;
256 }
257 else {
258 ercd = E_OBJ;
259 }
260 t_unlock_cpu();
261
262 error_exit:
263 LOG_DEL_ALM_LEAVE(ercd);
264 return(ercd);
265}
266
267#endif /* TOPPERS_del_alm */
268
269/*
270 * アラームハンドラの動作開始
271 */
272#ifdef TOPPERS_sta_alm
273
274ER
275sta_alm(ID almid, RELTIM almtim)
276{
277 ALMCB *p_almcb;
278 ER ercd;
279
280 LOG_STA_ALM_ENTER(almid, almtim);
281 CHECK_TSKCTX_UNL();
282 CHECK_ALMID(almid);
283 CHECK_PAR(almtim <= TMAX_RELTIM);
284 p_almcb = get_almcb(almid);
285
286 t_lock_cpu();
287 if (p_almcb->p_alminib->almatr == TA_NOEXS) {
288 ercd = E_NOEXS;
289 }
290 else {
291 if (p_almcb->almsta) {
292 tmevtb_dequeue(&(p_almcb->tmevtb));
293 }
294 else {
295 p_almcb->almsta = true;
296 }
297 tmevtb_enqueue(&(p_almcb->tmevtb), almtim,
298 (CBACK) call_almhdr, (void *) p_almcb);
299 ercd = E_OK;
300 }
301 t_unlock_cpu();
302
303 error_exit:
304 LOG_STA_ALM_LEAVE(ercd);
305 return(ercd);
306}
307
308#endif /* TOPPERS_sta_alm */
309
310/*
311 * アラームハンドラの動作開始(非タスクコンテキスト用)
312 */
313#ifdef TOPPERS_ista_alm
314
315ER
316ista_alm(ID almid, RELTIM almtim)
317{
318 ALMCB *p_almcb;
319 ER ercd;
320
321 LOG_ISTA_ALM_ENTER(almid, almtim);
322 CHECK_INTCTX_UNL();
323 CHECK_ALMID(almid);
324 CHECK_PAR(almtim <= TMAX_RELTIM);
325 p_almcb = get_almcb(almid);
326
327 i_lock_cpu();
328 if (p_almcb->p_alminib->almatr == TA_NOEXS) {
329 ercd = E_NOEXS;
330 }
331 else {
332 if (p_almcb->almsta) {
333 tmevtb_dequeue(&(p_almcb->tmevtb));
334 }
335 else {
336 p_almcb->almsta = true;
337 }
338 tmevtb_enqueue(&(p_almcb->tmevtb), almtim,
339 (CBACK) call_almhdr, (void *) p_almcb);
340 ercd = E_OK;
341 }
342 i_unlock_cpu();
343
344 error_exit:
345 LOG_ISTA_ALM_LEAVE(ercd);
346 return(ercd);
347}
348
349#endif /* TOPPERS_ista_alm */
350
351/*
352 * アラームハンドラの動作停止
353 */
354#ifdef TOPPERS_stp_alm
355
356ER
357stp_alm(ID almid)
358{
359 ALMCB *p_almcb;
360 ER ercd;
361
362 LOG_STP_ALM_ENTER(almid);
363 CHECK_TSKCTX_UNL();
364 CHECK_ALMID(almid);
365 p_almcb = get_almcb(almid);
366
367 t_lock_cpu();
368 if (p_almcb->p_alminib->almatr == TA_NOEXS) {
369 ercd = E_NOEXS;
370 }
371 else {
372 if (p_almcb->almsta) {
373 p_almcb->almsta = false;
374 tmevtb_dequeue(&(p_almcb->tmevtb));
375 }
376 ercd = E_OK;
377 }
378 t_unlock_cpu();
379
380 error_exit:
381 LOG_STP_ALM_LEAVE(ercd);
382 return(ercd);
383}
384
385#endif /* TOPPERS_stp_alm */
386
387/*
388 * アラームハンドラの動作停止(非タスクコンテキスト用)
389 */
390#ifdef TOPPERS_istp_alm
391
392ER
393istp_alm(ID almid)
394{
395 ALMCB *p_almcb;
396 ER ercd;
397
398 LOG_ISTP_ALM_ENTER(almid);
399 CHECK_INTCTX_UNL();
400 CHECK_ALMID(almid);
401 p_almcb = get_almcb(almid);
402
403 i_lock_cpu();
404 if (p_almcb->p_alminib->almatr == TA_NOEXS) {
405 ercd = E_NOEXS;
406 }
407 else {
408 if (p_almcb->almsta) {
409 p_almcb->almsta = false;
410 tmevtb_dequeue(&(p_almcb->tmevtb));
411 }
412 ercd = E_OK;
413 }
414 i_unlock_cpu();
415
416 error_exit:
417 LOG_ISTP_ALM_LEAVE(ercd);
418 return(ercd);
419}
420
421#endif /* TOPPERS_istp_alm */
422
423/*
424 * アラームハンドラの状æ…
425‹å‚ç…
426§
427 */
428#ifdef TOPPERS_ref_alm
429
430ER
431ref_alm(ID almid, T_RALM *pk_ralm)
432{
433 ALMCB *p_almcb;
434 ER ercd;
435
436 LOG_REF_ALM_ENTER(almid, pk_ralm);
437 CHECK_TSKCTX_UNL();
438 CHECK_ALMID(almid);
439 p_almcb = get_almcb(almid);
440
441 t_lock_cpu();
442 if (p_almcb->p_alminib->almatr == TA_NOEXS) {
443 ercd = E_NOEXS;
444 }
445 else {
446 if (p_almcb->almsta) {
447 pk_ralm->almstat = TALM_STA;
448 pk_ralm->lefttim = tmevt_lefttim(&(p_almcb->tmevtb));
449 }
450 else {
451 pk_ralm->almstat = TALM_STP;
452 }
453 ercd = E_OK;
454 }
455 t_unlock_cpu();
456
457 error_exit:
458 LOG_REF_ALM_LEAVE(ercd, pk_ralm);
459 return(ercd);
460}
461
462#endif /* TOPPERS_ref_alm */
463
464/*
465 * アラームハンドラ起動ルーチン
466 */
467#ifdef TOPPERS_almcal
468
469void
470call_almhdr(ALMCB *p_almcb)
471{
472 PRI saved_ipm;
473
474 /*
475 * アラームハンドラを停止状æ…
476‹ã«ã™ã‚‹ï¼Ž
477 */
478 p_almcb->almsta = false;
479
480 /*
481 * アラームハンドラを,CPUロック解除状æ…
482‹ã§å‘¼ã³å‡ºã™ï¼Ž
483 */
484 saved_ipm = i_get_ipm();
485 i_unlock_cpu();
486
487 LOG_ALM_ENTER(p_almcb);
488 (*((ALMHDR)(p_almcb->p_alminib->almhdr)))(p_almcb->p_alminib->exinf);
489 LOG_ALM_LEAVE(p_almcb);
490
491 if (!i_sense_lock()) {
492 i_lock_cpu();
493 }
494 i_set_ipm(saved_ipm);
495}
496
497#endif /* TOPPERS_almcal */
Note: See TracBrowser for help on using the repository browser.