alarm.c

説明を見る。
00001 /*
00002  *  TOPPERS/ASP Kernel
00003  *      Toyohashi Open Platform for Embedded Real-Time Systems/
00004  *      Advanced Standard Profile Kernel
00005  * 
00006  *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
00007  *                              Toyohashi Univ. of Technology, JAPAN
00008  *  Copyright (C) 2005-2007 by Embedded and Real-Time Systems Laboratory
00009  *              Graduate School of Information Science, Nagoya Univ., JAPAN
00010  * 
00011  *  上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
00012  *  ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
00013  *  変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
00014  *  (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
00015  *      権表示,この利用条件および下記の無保証規定が,そのままの形でソー
00016  *      スコード中に含まれていること.
00017  *  (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
00018  *      用できる形で再配布する場合には,再配布に伴うドキュメント(利用
00019  *      者マニュアルなど)に,上記の著作権表示,この利用条件および下記
00020  *      の無保証規定を掲載すること.
00021  *  (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
00022  *      用できない形で再配布する場合には,次のいずれかの条件を満たすこ
00023  *      と.
00024  *    (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
00025  *        作権表示,この利用条件および下記の無保証規定を掲載すること.
00026  *    (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
00027  *        報告すること.
00028  *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
00029  *      害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
00030  *      また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
00031  *      由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
00032  *      免責すること.
00033  * 
00034  *  本ソフトウェアは,無保証で提供されているものである.上記著作権者お
00035  *  よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
00036  *  に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
00037  *  アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
00038  *  の責任を負わない.
00039  * 
00040  *  @(#) $Id: alarm.c 748 2008-03-07 17:18:06Z hiro $
00041  */
00042 
00043 /*
00044  *      アラームハンドラ機能
00045  */
00046 
00047 #include "kernel_impl.h"
00048 #include "check.h"
00049 #include "alarm.h"
00050 
00051 /*
00052  *  トレースログマクロのデフォルト定義
00053  */
00054 #ifndef LOG_ALM_ENTER
00055 #define LOG_ALM_ENTER(p_almcb)
00056 #endif /* LOG_ALM_ENTER */
00057 
00058 #ifndef LOG_ALM_LEAVE
00059 #define LOG_ALM_LEAVE(p_almcb)
00060 #endif /* LOG_ALM_LEAVE */
00061 
00062 #ifndef LOG_STA_ALM_ENTER
00063 #define LOG_STA_ALM_ENTER(almid, almtim)
00064 #endif /* LOG_STA_ALM_ENTER */
00065 
00066 #ifndef LOG_STA_ALM_LEAVE
00067 #define LOG_STA_ALM_LEAVE(ercd)
00068 #endif /* LOG_STA_ALM_LEAVE */
00069 
00070 #ifndef LOG_ISTA_ALM_ENTER
00071 #define LOG_ISTA_ALM_ENTER(almid, almtim)
00072 #endif /* LOG_ISTA_ALM_ENTER */
00073 
00074 #ifndef LOG_ISTA_ALM_LEAVE
00075 #define LOG_ISTA_ALM_LEAVE(ercd)
00076 #endif /* LOG_ISTA_ALM_LEAVE */
00077 
00078 #ifndef LOG_STP_ALM_ENTER
00079 #define LOG_STP_ALM_ENTER(almid)
00080 #endif /* LOG_STP_ALM_ENTER */
00081 
00082 #ifndef LOG_STP_ALM_LEAVE
00083 #define LOG_STP_ALM_LEAVE(ercd)
00084 #endif /* LOG_STP_ALM_LEAVE */
00085 
00086 #ifndef LOG_ISTP_ALM_ENTER
00087 #define LOG_ISTP_ALM_ENTER(almid)
00088 #endif /* LOG_ISTP_ALM_ENTER */
00089 
00090 #ifndef LOG_ISTP_ALM_LEAVE
00091 #define LOG_ISTP_ALM_LEAVE(ercd)
00092 #endif /* LOG_ISTP_ALM_LEAVE */
00093 
00094 #ifndef LOG_REF_ALM_ENTER
00095 #define LOG_REF_ALM_ENTER(almid, pk_ralm)
00096 #endif /* LOG_REF_ALM_ENTER */
00097 
00098 #ifndef LOG_REF_ALM_LEAVE
00099 #define LOG_REF_ALM_LEAVE(ercd, pk_ralm)
00100 #endif /* LOG_REF_ALM_LEAVE */
00101 
00102 /*
00103  *  アラームハンドラの数
00104  */
00105 #define tnum_alm    ((uint_t)(tmax_almid - TMIN_ALMID + 1))
00106 
00107 /*
00108  *  アラームハンドラIDからアラームハンドラ管理ブロックを取り出すためのマクロ
00109  */
00110 #define INDEX_ALM(almid)    ((uint_t)((almid) - TMIN_ALMID))
00111 #define get_almcb(almid)    (&(almcb_table[INDEX_ALM(almid)]))
00112 
00113 /*
00114  *  アラームハンドラ機能の初期化
00115  */
00116 #ifdef TOPPERS_almini
00117 
00118 void
00119 initialize_alarm(void)
00120 {
00121     uint_t  i;
00122     ALMCB   *p_almcb;
00123 
00124     for (p_almcb = almcb_table, i = 0; i < tnum_alm; p_almcb++, i++) {
00125         p_almcb->p_alminib = &(alminib_table[i]);
00126         p_almcb->almsta = false;
00127     }
00128 }
00129 
00130 #endif /* TOPPERS_almini */
00131 
00132 /*
00133  *  アラームハンドラの動作開始
00134  */
00135 #ifdef TOPPERS_sta_alm
00136 
00137 ER
00138 sta_alm(ID almid, RELTIM almtim)
00139 {
00140     ALMCB   *p_almcb;
00141     ER      ercd;
00142 
00143     LOG_STA_ALM_ENTER(almid, almtim);
00144     CHECK_TSKCTX_UNL();
00145     CHECK_ALMID(almid);
00146     CHECK_PAR(almtim <= TMAX_RELTIM);
00147     p_almcb = get_almcb(almid);
00148 
00149     t_lock_cpu();
00150     if (p_almcb->almsta) {
00151         tmevtb_dequeue(&(p_almcb->tmevtb));
00152     }
00153     else {
00154         p_almcb->almsta = true;
00155     }
00156     tmevtb_enqueue(&(p_almcb->tmevtb), almtim,
00157                                 (CBACK) call_almhdr, (void *) p_almcb);
00158     ercd = E_OK;
00159     t_unlock_cpu();
00160 
00161   error_exit:
00162     LOG_STA_ALM_LEAVE(ercd);
00163     return(ercd);
00164 }
00165 
00166 #endif /* TOPPERS_sta_alm */
00167 
00168 /*
00169  *  アラームハンドラの動作開始(非タスクコンテキスト用)
00170  */
00171 #ifdef TOPPERS_ista_alm
00172 
00173 ER
00174 ista_alm(ID almid, RELTIM almtim)
00175 {
00176     ALMCB   *p_almcb;
00177     ER      ercd;
00178 
00179     LOG_ISTA_ALM_ENTER(almid, almtim);
00180     CHECK_INTCTX_UNL();
00181     CHECK_ALMID(almid);
00182     CHECK_PAR(almtim <= TMAX_RELTIM);
00183     p_almcb = get_almcb(almid);
00184 
00185     i_lock_cpu();
00186     if (p_almcb->almsta) {
00187         tmevtb_dequeue(&(p_almcb->tmevtb));
00188     }
00189     else {
00190         p_almcb->almsta = true;
00191     }
00192     tmevtb_enqueue(&(p_almcb->tmevtb), almtim,
00193                                 (CBACK) call_almhdr, (void *) p_almcb);
00194     ercd = E_OK;
00195     i_unlock_cpu();
00196 
00197   error_exit:
00198     LOG_ISTA_ALM_LEAVE(ercd);
00199     return(ercd);
00200 }
00201 
00202 #endif /* TOPPERS_ista_alm */
00203 
00204 /*
00205  *  アラームハンドラの動作停止
00206  */
00207 #ifdef TOPPERS_stp_alm
00208 
00209 ER
00210 stp_alm(ID almid)
00211 {
00212     ALMCB   *p_almcb;
00213     ER      ercd;
00214 
00215     LOG_STP_ALM_ENTER(almid);
00216     CHECK_TSKCTX_UNL();
00217     CHECK_ALMID(almid);
00218     p_almcb = get_almcb(almid);
00219 
00220     t_lock_cpu();
00221     if (p_almcb->almsta) {
00222         p_almcb->almsta = false;
00223         tmevtb_dequeue(&(p_almcb->tmevtb));
00224     }
00225     ercd = E_OK;
00226     t_unlock_cpu();
00227 
00228   error_exit:
00229     LOG_STP_ALM_LEAVE(ercd);
00230     return(ercd);
00231 }
00232 
00233 #endif /* TOPPERS_stp_alm */
00234 
00235 /*
00236  *  アラームハンドラの動作停止(非タスクコンテキスト用)
00237  */
00238 #ifdef TOPPERS_istp_alm
00239 
00240 ER
00241 istp_alm(ID almid)
00242 {
00243     ALMCB   *p_almcb;
00244     ER      ercd;
00245 
00246     LOG_ISTP_ALM_ENTER(almid);
00247     CHECK_INTCTX_UNL();
00248     CHECK_ALMID(almid);
00249     p_almcb = get_almcb(almid);
00250 
00251     i_lock_cpu();
00252     if (p_almcb->almsta) {
00253         p_almcb->almsta = false;
00254         tmevtb_dequeue(&(p_almcb->tmevtb));
00255     }
00256     ercd = E_OK;
00257     i_unlock_cpu();
00258 
00259   error_exit:
00260     LOG_ISTP_ALM_LEAVE(ercd);
00261     return(ercd);
00262 }
00263 
00264 #endif /* TOPPERS_istp_alm */
00265 
00266 /*
00267  *  アラームハンドラの状態参照
00268  */
00269 #ifdef TOPPERS_ref_alm
00270 
00271 ER
00272 ref_alm(ID almid, T_RALM *pk_ralm)
00273 {
00274     ALMCB   *p_almcb;
00275     ER      ercd;
00276     
00277     LOG_REF_ALM_ENTER(almid, pk_ralm);
00278     CHECK_TSKCTX_UNL();
00279     CHECK_ALMID(almid);
00280     p_almcb = get_almcb(almid);
00281 
00282     t_lock_cpu();
00283     if (p_almcb->almsta) {
00284         pk_ralm->almstat = TALM_STA;
00285         pk_ralm->lefttim = tmevt_lefttim(&(p_almcb->tmevtb));
00286     }
00287     else {
00288         pk_ralm->almstat = TALM_STP;
00289     }
00290     ercd = E_OK;
00291     t_unlock_cpu();
00292 
00293   error_exit:
00294     LOG_REF_ALM_LEAVE(ercd, pk_ralm);
00295     return(ercd);
00296 }
00297 
00298 #endif /* TOPPERS_ref_alm */
00299 
00300 /*
00301  *  アラームハンドラ起動ルーチン
00302  */
00303 #ifdef TOPPERS_almcal
00304 
00305 void
00306 call_almhdr(ALMCB *p_almcb)
00307 {
00308     PRI     saved_ipm;
00309 
00310     /*
00311      *  アラームハンドラを停止状態にする.
00312      */
00313     p_almcb->almsta = false;
00314 
00315     /*
00316      *  アラームハンドラを,CPUロック解除状態で呼び出す.
00317      */
00318     saved_ipm = i_get_ipm();
00319     i_unlock_cpu();
00320 
00321     LOG_ALM_ENTER(p_almcb);
00322     (*((ALMHDR)(p_almcb->p_alminib->almhdr)))(p_almcb->p_alminib->exinf);
00323     LOG_ALM_LEAVE(p_almcb);
00324 
00325     if (!i_sense_lock()) {
00326         i_lock_cpu();
00327     }
00328     i_set_ipm(saved_ipm);
00329 }
00330 
00331 #endif /* TOPPERS_almcal */

Copyright © 2008 by Kijineko Inc.

ホームページ制作