source: UsbWattMeter/trunk/asp_dcre/kernel/alarm.c

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

MIMEにSJISを設定

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