source: asp3_tinet_ecnl_arm/trunk/asp3_dcre/kernel/alarm.c@ 352

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

arm向けASP3版ECNLを追加

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc;charset=UTF-8
File size: 9.6 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 * 上記著作権者は,以下の(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 nfyinfo, *p_nfyinfo;
167 ER ercd, rercd;
168
169 LOG_ACRE_ALM_ENTER(pk_calm);
170 CHECK_TSKCTX_UNL();
171
172 almatr = pk_calm->almatr;
173 nfyinfo = pk_calm->nfyinfo;
174
175 CHECK_RSATR(almatr, TA_NULL);
176 rercd = check_nfyinfo(&nfyinfo);
177 if (rercd != E_OK) {
178 ercd = rercd;
179 goto error_exit;
180 }
181
182 lock_cpu();
183 if (tnum_alm == 0 || queue_empty(&free_almcb)) {
184 ercd = E_NOID;
185 }
186 else {
187 p_almcb = ((ALMCB *)(((char *) queue_delete_next(&free_almcb))
188 - offsetof(ALMCB, tmevtb)));
189 p_alminib = (ALMINIB *)(p_almcb->p_alminib);
190 p_alminib->almatr = almatr;
191 if (nfyinfo.nfymode == TNFY_HANDLER) {
192 p_alminib->exinf = nfyinfo.nfy.handler.exinf;
193 p_alminib->nfyhdr = (NFYHDR)(nfyinfo.nfy.handler.tmehdr);
194 }
195 else {
196 p_nfyinfo = &aalm_nfyinfo_table[p_alminib - aalminib_table];
197 *p_nfyinfo = nfyinfo;
198 p_alminib->exinf = (intptr_t) p_nfyinfo;
199 p_alminib->nfyhdr = notify_handler;
200 }
201 p_almcb->almsta = false;
202 ercd = ALMID(p_almcb);
203 }
204 unlock_cpu();
205
206 error_exit:
207 LOG_ACRE_ALM_LEAVE(ercd);
208 return(ercd);
209}
210
211#endif /* TOPPERS_acre_alm */
212
213/*
214 * アラーム通知の削除
215 */
216#ifdef TOPPERS_del_alm
217
218ER
219del_alm(ID almid)
220{
221 ALMCB *p_almcb;
222 ALMINIB *p_alminib;
223 ER ercd;
224
225 LOG_DEL_ALM_ENTER(almid);
226 CHECK_TSKCTX_UNL();
227 CHECK_ID(VALID_ALMID(almid));
228 p_almcb = get_almcb(almid);
229
230 lock_cpu();
231 if (p_almcb->p_alminib->almatr == TA_NOEXS) {
232 ercd = E_NOEXS;
233 }
234 else if (almid <= tmax_salmid) {
235 ercd = E_OBJ;
236 }
237 else {
238 if (p_almcb->almsta) {
239 p_almcb->almsta = false;
240 tmevtb_dequeue(&(p_almcb->tmevtb));
241 }
242
243 p_alminib = (ALMINIB *)(p_almcb->p_alminib);
244 p_alminib->almatr = TA_NOEXS;
245 queue_insert_prev(&free_almcb, ((QUEUE *) &(p_almcb->tmevtb)));
246 ercd = E_OK;
247 }
248 unlock_cpu();
249
250 error_exit:
251 LOG_DEL_ALM_LEAVE(ercd);
252 return(ercd);
253}
254
255#endif /* TOPPERS_del_alm */
256
257/*
258 * アラーム通知の動作開始
259 */
260#ifdef TOPPERS_sta_alm
261
262ER
263sta_alm(ID almid, RELTIM almtim)
264{
265 ALMCB *p_almcb;
266 ER ercd;
267
268 LOG_STA_ALM_ENTER(almid, almtim);
269 CHECK_UNL();
270 CHECK_ID(VALID_ALMID(almid));
271 CHECK_PAR(VALID_RELTIM(almtim));
272 p_almcb = get_almcb(almid);
273
274 lock_cpu();
275 if (p_almcb->p_alminib->almatr == TA_NOEXS) {
276 ercd = E_NOEXS;
277 }
278 else {
279 if (p_almcb->almsta) {
280 tmevtb_dequeue(&(p_almcb->tmevtb));
281 }
282 else {
283 p_almcb->almsta = true;
284 }
285 tmevtb_enqueue(&(p_almcb->tmevtb), almtim);
286 ercd = E_OK;
287 }
288 unlock_cpu();
289
290 error_exit:
291 LOG_STA_ALM_LEAVE(ercd);
292 return(ercd);
293}
294
295#endif /* TOPPERS_sta_alm */
296
297/*
298 * アラーム通知の動作停止
299 */
300#ifdef TOPPERS_stp_alm
301
302ER
303stp_alm(ID almid)
304{
305 ALMCB *p_almcb;
306 ER ercd;
307
308 LOG_STP_ALM_ENTER(almid);
309 CHECK_UNL();
310 CHECK_ID(VALID_ALMID(almid));
311 p_almcb = get_almcb(almid);
312
313 lock_cpu();
314 if (p_almcb->p_alminib->almatr == TA_NOEXS) {
315 ercd = E_NOEXS;
316 }
317 else {
318 if (p_almcb->almsta) {
319 p_almcb->almsta = false;
320 tmevtb_dequeue(&(p_almcb->tmevtb));
321 }
322 ercd = E_OK;
323 }
324 unlock_cpu();
325
326 error_exit:
327 LOG_STP_ALM_LEAVE(ercd);
328 return(ercd);
329}
330
331#endif /* TOPPERS_stp_alm */
332
333/*
334 * アラーム通知の状態参照
335 */
336#ifdef TOPPERS_ref_alm
337
338ER
339ref_alm(ID almid, T_RALM *pk_ralm)
340{
341 ALMCB *p_almcb;
342 ER ercd;
343
344 LOG_REF_ALM_ENTER(almid, pk_ralm);
345 CHECK_TSKCTX_UNL();
346 CHECK_ID(VALID_ALMID(almid));
347 p_almcb = get_almcb(almid);
348
349 lock_cpu();
350 if (p_almcb->p_alminib->almatr == TA_NOEXS) {
351 ercd = E_NOEXS;
352 }
353 else {
354 if (p_almcb->almsta) {
355 pk_ralm->almstat = TALM_STA;
356 pk_ralm->lefttim = tmevt_lefttim(&(p_almcb->tmevtb));
357 }
358 else {
359 pk_ralm->almstat = TALM_STP;
360 }
361 ercd = E_OK;
362 }
363 unlock_cpu();
364
365 error_exit:
366 LOG_REF_ALM_LEAVE(ercd, pk_ralm);
367 return(ercd);
368}
369
370#endif /* TOPPERS_ref_alm */
371
372/*
373 * アラーム通知起動ルーチン
374 */
375#ifdef TOPPERS_almcal
376
377void
378call_alarm(ALMCB *p_almcb)
379{
380 /*
381 * アラーム通知を停止状態にする.
382 */
383 p_almcb->almsta = false;
384
385 /*
386 * 通知ハンドラを,CPUロック解除状態で呼び出す.
387 */
388 unlock_cpu();
389
390 LOG_ALM_ENTER(p_almcb);
391 (*(p_almcb->p_alminib->nfyhdr))(p_almcb->p_alminib->exinf);
392 LOG_ALM_LEAVE(p_almcb);
393
394 if (!sense_lock()) {
395 lock_cpu();
396 }
397}
398
399#endif /* TOPPERS_almcal */
Note: See TracBrowser for help on using the repository browser.