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-2008 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: cyclic.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 "cyclic.h" 00050 00051 /* 00052 * トレースログマクロのデフォルト定義 00053 */ 00054 #ifndef LOG_CYC_ENTER 00055 #define LOG_CYC_ENTER(p_cyccb) 00056 #endif /* LOG_CYC_ENTER */ 00057 00058 #ifndef LOG_CYC_LEAVE 00059 #define LOG_CYC_LEAVE(p_cyccb) 00060 #endif /* LOG_CYC_LEAVE */ 00061 00062 #ifndef LOG_STA_CYC_ENTER 00063 #define LOG_STA_CYC_ENTER(cycid) 00064 #endif /* LOG_STA_CYC_ENTER */ 00065 00066 #ifndef LOG_STA_CYC_LEAVE 00067 #define LOG_STA_CYC_LEAVE(ercd) 00068 #endif /* LOG_STA_CYC_LEAVE */ 00069 00070 #ifndef LOG_STP_CYC_ENTER 00071 #define LOG_STP_CYC_ENTER(cycid) 00072 #endif /* LOG_STP_CYC_ENTER */ 00073 00074 #ifndef LOG_STP_CYC_LEAVE 00075 #define LOG_STP_CYC_LEAVE(ercd) 00076 #endif /* LOG_STP_CYC_LEAVE */ 00077 00078 #ifndef LOG_REF_CYC_ENTER 00079 #define LOG_REF_CYC_ENTER(cycid, pk_rcyc) 00080 #endif /* LOG_REF_CYC_ENTER */ 00081 00082 #ifndef LOG_REF_CYC_LEAVE 00083 #define LOG_REF_CYC_LEAVE(ercd, pk_rcyc) 00084 #endif /* LOG_REF_CYC_LEAVE */ 00085 00086 /* 00087 * 周期ハンドラの数 00088 */ 00089 #define tnum_cyc ((uint_t)(tmax_cycid - TMIN_CYCID + 1)) 00090 00091 /* 00092 * 周期ハンドラIDから周期ハンドラ管理ブロックを取り出すためのマクロ 00093 */ 00094 #define INDEX_CYC(cycid) ((uint_t)((cycid) - TMIN_CYCID)) 00095 #define get_cyccb(cycid) (&(cyccb_table[INDEX_CYC(cycid)])) 00096 00097 /* 00098 * 周期ハンドラ起動のためのタイムイベントブロックの登録 00099 */ 00100 Inline void 00101 tmevtb_enqueue_cyc(CYCCB *p_cyccb, EVTTIM evttim) 00102 { 00103 tmevtb_enqueue_evttim(&(p_cyccb->tmevtb), evttim, 00104 (CBACK) call_cychdr, (void *) p_cyccb); 00105 p_cyccb->evttim = evttim; 00106 } 00107 00108 /* 00109 * 周期ハンドラ機能の初期化 00110 */ 00111 #ifdef TOPPERS_cycini 00112 00113 void 00114 initialize_cyclic(void) 00115 { 00116 uint_t i; 00117 CYCCB *p_cyccb; 00118 00119 for (p_cyccb = cyccb_table, i = 0; i < tnum_cyc; p_cyccb++, i++) { 00120 p_cyccb->p_cycinib = &(cycinib_table[i]); 00121 if ((p_cyccb->p_cycinib->cycatr & TA_STA) != 0U) { 00122 p_cyccb->cycsta = true; 00123 tmevtb_enqueue_cyc(p_cyccb, (EVTTIM)(p_cyccb->p_cycinib->cycphs)); 00124 } 00125 else { 00126 p_cyccb->cycsta = false; 00127 } 00128 } 00129 } 00130 00131 #endif /* TOPPERS_cycini */ 00132 00133 /* 00134 * 周期ハンドラの動作開始 00135 */ 00136 #ifdef TOPPERS_sta_cyc 00137 00138 ER 00139 sta_cyc(ID cycid) 00140 { 00141 CYCCB *p_cyccb; 00142 ER ercd; 00143 00144 LOG_STA_CYC_ENTER(cycid); 00145 CHECK_TSKCTX_UNL(); 00146 CHECK_CYCID(cycid); 00147 p_cyccb = get_cyccb(cycid); 00148 00149 t_lock_cpu(); 00150 if (p_cyccb->cycsta) { 00151 tmevtb_dequeue(&(p_cyccb->tmevtb)); 00152 } 00153 else { 00154 p_cyccb->cycsta = true; 00155 } 00156 tmevtb_enqueue_cyc(p_cyccb, base_time + p_cyccb->p_cycinib->cyctim); 00157 ercd = E_OK; 00158 t_unlock_cpu(); 00159 00160 error_exit: 00161 LOG_STA_CYC_LEAVE(ercd); 00162 return(ercd); 00163 } 00164 00165 #endif /* TOPPERS_sta_cyc */ 00166 00167 /* 00168 * 周期ハンドラの動作停止 00169 */ 00170 #ifdef TOPPERS_stp_cyc 00171 00172 ER 00173 stp_cyc(ID cycid) 00174 { 00175 CYCCB *p_cyccb; 00176 ER ercd; 00177 00178 LOG_STP_CYC_ENTER(cycid); 00179 CHECK_TSKCTX_UNL(); 00180 CHECK_CYCID(cycid); 00181 p_cyccb = get_cyccb(cycid); 00182 00183 t_lock_cpu(); 00184 if (p_cyccb->cycsta) { 00185 p_cyccb->cycsta = false; 00186 tmevtb_dequeue(&(p_cyccb->tmevtb)); 00187 } 00188 ercd = E_OK; 00189 t_unlock_cpu(); 00190 00191 error_exit: 00192 LOG_STP_CYC_LEAVE(ercd); 00193 return(ercd); 00194 } 00195 00196 #endif /* TOPPERS_stp_cyc */ 00197 00198 /* 00199 * 周期ハンドラの状態参照 00200 */ 00201 #ifdef TOPPERS_ref_cyc 00202 00203 ER 00204 ref_cyc(ID cycid, T_RCYC *pk_rcyc) 00205 { 00206 CYCCB *p_cyccb; 00207 ER ercd; 00208 00209 LOG_REF_CYC_ENTER(cycid, pk_rcyc); 00210 CHECK_TSKCTX_UNL(); 00211 CHECK_CYCID(cycid); 00212 p_cyccb = get_cyccb(cycid); 00213 00214 t_lock_cpu(); 00215 if (p_cyccb->cycsta) { 00216 pk_rcyc->cycstat = TCYC_STA; 00217 pk_rcyc->lefttim = tmevt_lefttim(&(p_cyccb->tmevtb)); 00218 } 00219 else { 00220 pk_rcyc->cycstat = TCYC_STP; 00221 } 00222 ercd = E_OK; 00223 t_unlock_cpu(); 00224 00225 error_exit: 00226 LOG_REF_CYC_LEAVE(ercd, pk_rcyc); 00227 return(ercd); 00228 } 00229 00230 #endif /* TOPPERS_ref_cyc */ 00231 00232 /* 00233 * 周期ハンドラ起動ルーチン 00234 */ 00235 #ifdef TOPPERS_cyccal 00236 00237 void 00238 call_cychdr(CYCCB *p_cyccb) 00239 { 00240 PRI saved_ipm; 00241 00242 /* 00243 * 次回の起動のためのタイムイベントブロックを登録する. 00244 * 00245 * 同じタイムティックで周期ハンドラを再度起動すべき場合には,この 00246 * 関数からsignal_timeに戻った後に,再度この関数が呼ばれることにな 00247 * る. 00248 */ 00249 tmevtb_enqueue_cyc(p_cyccb, p_cyccb->evttim + p_cyccb->p_cycinib->cyctim); 00250 00251 /* 00252 * 周期ハンドラを,CPUロック解除状態で呼び出す. 00253 */ 00254 saved_ipm = i_get_ipm(); 00255 i_unlock_cpu(); 00256 00257 LOG_CYC_ENTER(p_cyccb); 00258 (*((CYCHDR)(p_cyccb->p_cycinib->cychdr)))(p_cyccb->p_cycinib->exinf); 00259 LOG_CYC_LEAVE(p_cyccb); 00260 00261 if (!i_sense_lock()) { 00262 i_lock_cpu(); 00263 } 00264 i_set_ipm(saved_ipm); 00265 } 00266 00267 #endif /* TOPPERS_cyccal */
Copyright © 2008 by Kijineko Inc.