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.