source: EcnlProtoTool/trunk/asp3_dcre/kernel/alarm.c@ 429

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

ASP3, TINET, mbed を更新

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc;charset=UTF-8
File size: 9.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-2018 by Embedded and Real-Time Systems Laboratory
9 * Graduate School of Information Science, Nagoya Univ., JAPAN
10 *
11 * 上記著作権者は,以下の(1)~(4)の条件を満たす場合に限り,本ソフトウェ
12 * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
13 * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
14 * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
15 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
16 * スコード中に含まれていること.
17 * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
18 * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
19 * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
20 * の無保証規定を掲載すること.
21 * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
22 * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
23 * と.
24 * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
25 * 作権表示,この利用条件および下記の無保証規定を掲載すること.
26 * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
27 * 報告すること.
28 * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
29 * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
30 * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
31 * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
32 * 免責すること.
33 *
34 * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
35 * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
36 * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
37 * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
38 * の責任を負わない.
39 *
40 * $Id$
41 */
42
43/*
44 * アラーム通知機能
45 */
46
47#include "kernel_impl.h"
48#include "check.h"
49#include "alarm.h"
50
51/*
52 * トレースログマクロのデフォルト定義
53 */
54#ifndef LOG_ALM_ENTER
55#define LOG_ALM_ENTER(p_almcb)
56#endif /* LOG_ALM_ENTER */
57
58#ifndef LOG_ALM_LEAVE
59#define LOG_ALM_LEAVE(p_almcb)
60#endif /* LOG_ALM_LEAVE */
61
62#ifndef LOG_ACRE_ALM_ENTER
63#define LOG_ACRE_ALM_ENTER(pk_calm)
64#endif /* LOG_ACRE_ALM_ENTER */
65
66#ifndef LOG_ACRE_ALM_LEAVE
67#define LOG_ACRE_ALM_LEAVE(ercd)
68#endif /* LOG_ACRE_ALM_LEAVE */
69
70#ifndef LOG_DEL_ALM_ENTER
71#define LOG_DEL_ALM_ENTER(almid)
72#endif /* LOG_DEL_ALM_ENTER */
73
74#ifndef LOG_DEL_ALM_LEAVE
75#define LOG_DEL_ALM_LEAVE(ercd)
76#endif /* LOG_DEL_ALM_LEAVE */
77
78#ifndef LOG_STA_ALM_ENTER
79#define LOG_STA_ALM_ENTER(almid, almtim)
80#endif /* LOG_STA_ALM_ENTER */
81
82#ifndef LOG_STA_ALM_LEAVE
83#define LOG_STA_ALM_LEAVE(ercd)
84#endif /* LOG_STA_ALM_LEAVE */
85
86#ifndef LOG_STP_ALM_ENTER
87#define LOG_STP_ALM_ENTER(almid)
88#endif /* LOG_STP_ALM_ENTER */
89
90#ifndef LOG_STP_ALM_LEAVE
91#define LOG_STP_ALM_LEAVE(ercd)
92#endif /* LOG_STP_ALM_LEAVE */
93
94#ifndef LOG_REF_ALM_ENTER
95#define LOG_REF_ALM_ENTER(almid, pk_ralm)
96#endif /* LOG_REF_ALM_ENTER */
97
98#ifndef LOG_REF_ALM_LEAVE
99#define LOG_REF_ALM_LEAVE(ercd, pk_ralm)
100#endif /* LOG_REF_ALM_LEAVE */
101
102/*
103 * アラーム通知の数
104 */
105#define tnum_alm ((uint_t)(tmax_almid - TMIN_ALMID + 1))
106#define tnum_salm ((uint_t)(tmax_salmid - TMIN_ALMID + 1))
107
108/*
109 * アラーム通知IDからアラーム通知管理ブロックを取り出すためのマクロ
110 */
111#define INDEX_ALM(almid) ((uint_t)((almid) - TMIN_ALMID))
112#define get_almcb(almid) (&(almcb_table[INDEX_ALM(almid)]))
113
114#ifdef TOPPERS_almini
115
116/*
117 * 使用していないアラーム通知管理ブロックのリスト
118 *
119 * アラーム通知管理ブロックの先頭にはキューにつなぐための領域がないた
120 * め,タイムイベントブロック(tmevtb)の領域を用いる.
121 */
122QUEUE free_almcb;
123
124/*
125 * アラーム通知機能の初期化
126 */
127void
128initialize_alarm(void)
129{
130 uint_t i, j;
131 ALMCB *p_almcb;
132 ALMINIB *p_alminib;
133
134 for (i = 0; i < tnum_salm; i++) {
135 p_almcb = &(almcb_table[i]);
136 p_almcb->p_alminib = &(alminib_table[i]);
137 p_almcb->almsta = false;
138 p_almcb->tmevtb.callback = (CBACK) call_alarm;
139 p_almcb->tmevtb.arg = (void *) p_almcb;
140 }
141 queue_initialize(&free_almcb);
142 for (j = 0; i < tnum_alm; i++, j++) {
143 p_almcb = &(almcb_table[i]);
144 p_alminib = &(aalminib_table[j]);
145 p_alminib->almatr = TA_NOEXS;
146 p_almcb->p_alminib = ((const ALMINIB *) p_alminib);
147 p_almcb->tmevtb.callback = (CBACK) call_alarm;
148 p_almcb->tmevtb.arg = (void *) p_almcb;
149 queue_insert_prev(&free_almcb, ((QUEUE *) &(p_almcb->tmevtb)));
150 }
151}
152
153#endif /* TOPPERS_almini */
154
155/*
156 * アラーム通知の生成
157 */
158#ifdef TOPPERS_acre_alm
159
160ER_UINT
161acre_alm(const T_CALM *pk_calm)
162{
163 ALMCB *p_almcb;
164 ALMINIB *p_alminib;
165 ATR almatr;
166 T_NFYINFO *p_nfyinfo;
167 ER ercd;
168
169 LOG_ACRE_ALM_ENTER(pk_calm);
170 CHECK_TSKCTX_UNL();
171
172 almatr = pk_calm->almatr;
173
174 CHECK_VALIDATR(almatr, TA_NULL);
175 ercd = check_nfyinfo(&(pk_calm->nfyinfo));
176 if (ercd != E_OK) {
177 goto error_exit;
178 }
179
180 lock_cpu();
181 if (tnum_alm == 0 || queue_empty(&free_almcb)) {
182 ercd = E_NOID;
183 }
184 else {
185 p_almcb = ((ALMCB *)(((char *) queue_delete_next(&free_almcb))
186 - offsetof(ALMCB, tmevtb)));
187 p_alminib = (ALMINIB *)(p_almcb->p_alminib);
188 p_alminib->almatr = almatr;
189 if (pk_calm->nfyinfo.nfymode == TNFY_HANDLER) {
190 p_alminib->exinf = pk_calm->nfyinfo.nfy.handler.exinf;
191 p_alminib->nfyhdr = (NFYHDR)(pk_calm->nfyinfo.nfy.handler.tmehdr);
192 }
193 else {
194 p_nfyinfo = &aalm_nfyinfo_table[p_alminib - aalminib_table];
195 *p_nfyinfo = pk_calm->nfyinfo;
196 p_alminib->exinf = (intptr_t) p_nfyinfo;
197 p_alminib->nfyhdr = notify_handler;
198 }
199 p_almcb->almsta = false;
200 ercd = ALMID(p_almcb);
201 }
202 unlock_cpu();
203
204 error_exit:
205 LOG_ACRE_ALM_LEAVE(ercd);
206 return(ercd);
207}
208
209#endif /* TOPPERS_acre_alm */
210
211/*
212 * アラーム通知の削除
213 */
214#ifdef TOPPERS_del_alm
215
216ER
217del_alm(ID almid)
218{
219 ALMCB *p_almcb;
220 ALMINIB *p_alminib;
221 ER ercd;
222
223 LOG_DEL_ALM_ENTER(almid);
224 CHECK_TSKCTX_UNL();
225 CHECK_ID(VALID_ALMID(almid));
226 p_almcb = get_almcb(almid);
227
228 lock_cpu();
229 if (p_almcb->p_alminib->almatr == TA_NOEXS) {
230 ercd = E_NOEXS;
231 }
232 else if (almid <= tmax_salmid) {
233 ercd = E_OBJ;
234 }
235 else {
236 if (p_almcb->almsta) {
237 p_almcb->almsta = false;
238 tmevtb_dequeue(&(p_almcb->tmevtb));
239 }
240
241 p_alminib = (ALMINIB *)(p_almcb->p_alminib);
242 p_alminib->almatr = TA_NOEXS;
243 queue_insert_prev(&free_almcb, ((QUEUE *) &(p_almcb->tmevtb)));
244 ercd = E_OK;
245 }
246 unlock_cpu();
247
248 error_exit:
249 LOG_DEL_ALM_LEAVE(ercd);
250 return(ercd);
251}
252
253#endif /* TOPPERS_del_alm */
254
255/*
256 * アラーム通知の動作開始
257 */
258#ifdef TOPPERS_sta_alm
259
260ER
261sta_alm(ID almid, RELTIM almtim)
262{
263 ALMCB *p_almcb;
264 ER ercd;
265
266 LOG_STA_ALM_ENTER(almid, almtim);
267 CHECK_UNL();
268 CHECK_ID(VALID_ALMID(almid));
269 CHECK_PAR(VALID_RELTIM(almtim));
270 p_almcb = get_almcb(almid);
271
272 lock_cpu();
273 if (p_almcb->p_alminib->almatr == TA_NOEXS) {
274 ercd = E_NOEXS;
275 }
276 else {
277 if (p_almcb->almsta) {
278 tmevtb_dequeue(&(p_almcb->tmevtb));
279 }
280 else {
281 p_almcb->almsta = true;
282 }
283 tmevtb_enqueue_reltim(&(p_almcb->tmevtb), almtim);
284 ercd = E_OK;
285 }
286 unlock_cpu();
287
288 error_exit:
289 LOG_STA_ALM_LEAVE(ercd);
290 return(ercd);
291}
292
293#endif /* TOPPERS_sta_alm */
294
295/*
296 * アラーム通知の動作停止
297 */
298#ifdef TOPPERS_stp_alm
299
300ER
301stp_alm(ID almid)
302{
303 ALMCB *p_almcb;
304 ER ercd;
305
306 LOG_STP_ALM_ENTER(almid);
307 CHECK_UNL();
308 CHECK_ID(VALID_ALMID(almid));
309 p_almcb = get_almcb(almid);
310
311 lock_cpu();
312 if (p_almcb->p_alminib->almatr == TA_NOEXS) {
313 ercd = E_NOEXS;
314 }
315 else {
316 if (p_almcb->almsta) {
317 p_almcb->almsta = false;
318 tmevtb_dequeue(&(p_almcb->tmevtb));
319 }
320 ercd = E_OK;
321 }
322 unlock_cpu();
323
324 error_exit:
325 LOG_STP_ALM_LEAVE(ercd);
326 return(ercd);
327}
328
329#endif /* TOPPERS_stp_alm */
330
331/*
332 * アラーム通知の状態参照
333 */
334#ifdef TOPPERS_ref_alm
335
336ER
337ref_alm(ID almid, T_RALM *pk_ralm)
338{
339 ALMCB *p_almcb;
340 ER ercd;
341
342 LOG_REF_ALM_ENTER(almid, pk_ralm);
343 CHECK_TSKCTX_UNL();
344 CHECK_ID(VALID_ALMID(almid));
345 p_almcb = get_almcb(almid);
346
347 lock_cpu();
348 if (p_almcb->p_alminib->almatr == TA_NOEXS) {
349 ercd = E_NOEXS;
350 }
351 else {
352 if (p_almcb->almsta) {
353 pk_ralm->almstat = TALM_STA;
354 pk_ralm->lefttim = tmevt_lefttim(&(p_almcb->tmevtb));
355 }
356 else {
357 pk_ralm->almstat = TALM_STP;
358 }
359 ercd = E_OK;
360 }
361 unlock_cpu();
362
363 error_exit:
364 LOG_REF_ALM_LEAVE(ercd, pk_ralm);
365 return(ercd);
366}
367
368#endif /* TOPPERS_ref_alm */
369
370/*
371 * アラーム通知起動ルーチン
372 */
373#ifdef TOPPERS_almcal
374
375void
376call_alarm(ALMCB *p_almcb)
377{
378 /*
379 * アラーム通知を停止状態にする.
380 */
381 p_almcb->almsta = false;
382
383 /*
384 * 通知ハンドラを,CPUロック解除状態で呼び出す.
385 *
386 * アラーム通知の生成/削除はタスクからしか行えないため,アラーム
387 * 通知初期化ブロックをCPUロック解除状態で参照しても問題ない.
388 */
389 unlock_cpu();
390
391 LOG_ALM_ENTER(p_almcb);
392 (*(p_almcb->p_alminib->nfyhdr))(p_almcb->p_alminib->exinf);
393 LOG_ALM_LEAVE(p_almcb);
394
395 if (!sense_lock()) {
396 lock_cpu();
397 }
398}
399
400#endif /* TOPPERS_almcal */
Note: See TracBrowser for help on using the repository browser.