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: mailbox.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 "task.h" 00050 #include "wait.h" 00051 #include "mailbox.h" 00052 00053 /* 00054 * トレースログマクロのデフォルト定義 00055 */ 00056 #ifndef LOG_SND_MBX_ENTER 00057 #define LOG_SND_MBX_ENTER(mbxid, pk_msg) 00058 #endif /* LOG_SND_MBX_ENTER */ 00059 00060 #ifndef LOG_SND_MBX_LEAVE 00061 #define LOG_SND_MBX_LEAVE(ercd) 00062 #endif /* LOG_SND_MBX_LEAVE */ 00063 00064 #ifndef LOG_RCV_MBX_ENTER 00065 #define LOG_RCV_MBX_ENTER(mbxid, ppk_msg) 00066 #endif /* LOG_RCV_MBX_ENTER */ 00067 00068 #ifndef LOG_RCV_MBX_LEAVE 00069 #define LOG_RCV_MBX_LEAVE(ercd, pk_msg) 00070 #endif /* LOG_RCV_MBX_LEAVE */ 00071 00072 #ifndef LOG_PRCV_MBX_ENTER 00073 #define LOG_PRCV_MBX_ENTER(mbxid, ppk_msg) 00074 #endif /* LOG_PRCV_MBX_ENTER */ 00075 00076 #ifndef LOG_PRCV_MBX_LEAVE 00077 #define LOG_PRCV_MBX_LEAVE(ercd, pk_msg) 00078 #endif /* LOG_PRCV_MBX_LEAVE */ 00079 00080 #ifndef LOG_TRCV_MBX_ENTER 00081 #define LOG_TRCV_MBX_ENTER(mbxid, ppk_msg, tmout) 00082 #endif /* LOG_TRCV_MBX_ENTER */ 00083 00084 #ifndef LOG_TRCV_MBX_LEAVE 00085 #define LOG_TRCV_MBX_LEAVE(ercd, pk_msg) 00086 #endif /* LOG_TRCV_MBX_LEAVE */ 00087 00088 #ifndef LOG_INI_MBX_ENTER 00089 #define LOG_INI_MBX_ENTER(mbxid) 00090 #endif /* LOG_INI_MBX_ENTER */ 00091 00092 #ifndef LOG_INI_MBX_LEAVE 00093 #define LOG_INI_MBX_LEAVE(ercd) 00094 #endif /* LOG_INI_MBX_LEAVE */ 00095 00096 #ifndef LOG_REF_MBX_ENTER 00097 #define LOG_REF_MBX_ENTER(mbxid, pk_rmbx) 00098 #endif /* LOG_REF_MBX_ENTER */ 00099 00100 #ifndef LOG_REF_MBX_LEAVE 00101 #define LOG_REF_MBX_LEAVE(ercd, pk_rmbx) 00102 #endif /* LOG_REF_MBX_LEAVE */ 00103 00104 /* 00105 * メールボックスの数 00106 */ 00107 #define tnum_mbx ((uint_t)(tmax_mbxid - TMIN_MBXID + 1)) 00108 00109 /* 00110 * メールボックスIDからメールボックス管理ブロックを取り出すためのマクロ 00111 */ 00112 #define INDEX_MBX(mbxid) ((uint_t)((mbxid) - TMIN_MBXID)) 00113 #define get_mbxcb(mbxid) (&(mbxcb_table[INDEX_MBX(mbxid)])) 00114 00115 /* 00116 * メールボックス機能の初期化 00117 */ 00118 #ifdef TOPPERS_mbxini 00119 00120 void 00121 initialize_mailbox(void) 00122 { 00123 uint_t i; 00124 MBXCB *p_mbxcb; 00125 00126 for (p_mbxcb = mbxcb_table, i = 0; i < tnum_mbx; p_mbxcb++, i++) { 00127 queue_initialize(&(p_mbxcb->wait_queue)); 00128 p_mbxcb->p_mbxinib = &(mbxinib_table[i]); 00129 p_mbxcb->pk_head = NULL; 00130 } 00131 } 00132 00133 #endif /* TOPPERS_mbxini */ 00134 00135 /* 00136 * メッセージ優先度の取出し 00137 */ 00138 #define MSGPRI(pk_msg) (((T_MSG_PRI *) pk_msg)->msgpri) 00139 00140 /* 00141 * 優先度順メッセージキューへの挿入 00142 */ 00143 Inline void 00144 enqueue_msg_pri(T_MSG **ppk_prevmsg_next, T_MSG *pk_msg) 00145 { 00146 T_MSG *pk_nextmsg; 00147 00148 while ((pk_nextmsg = *ppk_prevmsg_next) != NULL) { 00149 if (MSGPRI(pk_nextmsg) > MSGPRI(pk_msg)) { 00150 break; 00151 } 00152 ppk_prevmsg_next = &(pk_nextmsg->pk_next); 00153 } 00154 pk_msg->pk_next = pk_nextmsg; 00155 *ppk_prevmsg_next = pk_msg; 00156 } 00157 00158 /* 00159 * メールボックスへの送信 00160 */ 00161 #ifdef TOPPERS_snd_mbx 00162 00163 ER 00164 snd_mbx(ID mbxid, T_MSG *pk_msg) 00165 { 00166 MBXCB *p_mbxcb; 00167 TCB *p_tcb; 00168 ER ercd; 00169 00170 LOG_SND_MBX_ENTER(mbxid, pk_msg); 00171 CHECK_TSKCTX_UNL(); 00172 CHECK_MBXID(mbxid); 00173 p_mbxcb = get_mbxcb(mbxid); 00174 CHECK_PAR((p_mbxcb->p_mbxinib->mbxatr & TA_MPRI) == 0U 00175 || (TMIN_MPRI <= MSGPRI(pk_msg) 00176 && MSGPRI(pk_msg) <= p_mbxcb->p_mbxinib->maxmpri)); 00177 00178 t_lock_cpu(); 00179 if (!queue_empty(&(p_mbxcb->wait_queue))) { 00180 p_tcb = (TCB *) queue_delete_next(&(p_mbxcb->wait_queue)); 00181 ((WINFO_MBX *)(p_tcb->p_winfo))->pk_msg = pk_msg; 00182 if (wait_complete(p_tcb)) { 00183 dispatch(); 00184 } 00185 ercd = E_OK; 00186 } 00187 else if ((p_mbxcb->p_mbxinib->mbxatr & TA_MPRI) != 0U) { 00188 enqueue_msg_pri(&(p_mbxcb->pk_head), pk_msg); 00189 ercd = E_OK; 00190 } 00191 else { 00192 pk_msg->pk_next = NULL; 00193 if (p_mbxcb->pk_head != NULL) { 00194 p_mbxcb->pk_last->pk_next = pk_msg; 00195 } 00196 else { 00197 p_mbxcb->pk_head = pk_msg; 00198 } 00199 p_mbxcb->pk_last = pk_msg; 00200 ercd = E_OK; 00201 } 00202 t_unlock_cpu(); 00203 00204 error_exit: 00205 LOG_SND_MBX_LEAVE(ercd); 00206 return(ercd); 00207 } 00208 00209 #endif /* TOPPERS_snd_mbx */ 00210 00211 /* 00212 * メールボックスからの受信 00213 */ 00214 #ifdef TOPPERS_rcv_mbx 00215 00216 ER 00217 rcv_mbx(ID mbxid, T_MSG **ppk_msg) 00218 { 00219 MBXCB *p_mbxcb; 00220 WINFO_MBX winfo_mbx; 00221 ER ercd; 00222 00223 LOG_RCV_MBX_ENTER(mbxid, ppk_msg); 00224 CHECK_DISPATCH(); 00225 CHECK_MBXID(mbxid); 00226 p_mbxcb = get_mbxcb(mbxid); 00227 00228 t_lock_cpu(); 00229 if (p_mbxcb->pk_head != NULL) { 00230 *ppk_msg = p_mbxcb->pk_head; 00231 p_mbxcb->pk_head = (*ppk_msg)->pk_next; 00232 ercd = E_OK; 00233 } 00234 else { 00235 p_runtsk->tstat = (TS_WAITING | TS_WAIT_MBX); 00236 wobj_make_wait((WOBJCB *) p_mbxcb, (WINFO_WOBJ *) &winfo_mbx); 00237 dispatch(); 00238 ercd = winfo_mbx.winfo.wercd; 00239 if (ercd == E_OK) { 00240 *ppk_msg = winfo_mbx.pk_msg; 00241 } 00242 } 00243 t_unlock_cpu(); 00244 00245 error_exit: 00246 LOG_RCV_MBX_LEAVE(ercd, *ppk_msg); 00247 return(ercd); 00248 } 00249 00250 #endif /* TOPPERS_rcv_mbx */ 00251 00252 /* 00253 * メールボックスからの受信(ポーリング) 00254 */ 00255 #ifdef TOPPERS_prcv_mbx 00256 00257 ER 00258 prcv_mbx(ID mbxid, T_MSG **ppk_msg) 00259 { 00260 MBXCB *p_mbxcb; 00261 ER ercd; 00262 00263 LOG_PRCV_MBX_ENTER(mbxid, ppk_msg); 00264 CHECK_TSKCTX_UNL(); 00265 CHECK_MBXID(mbxid); 00266 p_mbxcb = get_mbxcb(mbxid); 00267 00268 t_lock_cpu(); 00269 if (p_mbxcb->pk_head != NULL) { 00270 *ppk_msg = p_mbxcb->pk_head; 00271 p_mbxcb->pk_head = (*ppk_msg)->pk_next; 00272 ercd = E_OK; 00273 } 00274 else { 00275 ercd = E_TMOUT; 00276 } 00277 t_unlock_cpu(); 00278 00279 error_exit: 00280 LOG_PRCV_MBX_LEAVE(ercd, *ppk_msg); 00281 return(ercd); 00282 } 00283 00284 #endif /* TOPPERS_prcv_mbx */ 00285 00286 /* 00287 * メールボックスからの受信(タイムアウトあり) 00288 */ 00289 #ifdef TOPPERS_trcv_mbx 00290 00291 ER 00292 trcv_mbx(ID mbxid, T_MSG **ppk_msg, TMO tmout) 00293 { 00294 MBXCB *p_mbxcb; 00295 WINFO_MBX winfo_mbx; 00296 TMEVTB tmevtb; 00297 ER ercd; 00298 00299 LOG_TRCV_MBX_ENTER(mbxid, ppk_msg, tmout); 00300 CHECK_DISPATCH(); 00301 CHECK_MBXID(mbxid); 00302 CHECK_TMOUT(tmout); 00303 p_mbxcb = get_mbxcb(mbxid); 00304 00305 t_lock_cpu(); 00306 if (p_mbxcb->pk_head != NULL) { 00307 *ppk_msg = p_mbxcb->pk_head; 00308 p_mbxcb->pk_head = (*ppk_msg)->pk_next; 00309 ercd = E_OK; 00310 } 00311 else if (tmout == TMO_POL) { 00312 ercd = E_TMOUT; 00313 } 00314 else { 00315 p_runtsk->tstat = (TS_WAITING | TS_WAIT_MBX); 00316 wobj_make_wait_tmout((WOBJCB *) p_mbxcb, (WINFO_WOBJ *) &winfo_mbx, 00317 &tmevtb, tmout); 00318 dispatch(); 00319 ercd = winfo_mbx.winfo.wercd; 00320 if (ercd == E_OK) { 00321 *ppk_msg = winfo_mbx.pk_msg; 00322 } 00323 } 00324 t_unlock_cpu(); 00325 00326 error_exit: 00327 LOG_TRCV_MBX_LEAVE(ercd, *ppk_msg); 00328 return(ercd); 00329 } 00330 00331 #endif /* TOPPERS_trcv_mbx */ 00332 00333 /* 00334 * メールボックスの再初期化 00335 */ 00336 #ifdef TOPPERS_ini_mbx 00337 00338 ER 00339 ini_mbx(ID mbxid) 00340 { 00341 MBXCB *p_mbxcb; 00342 bool_t dspreq; 00343 ER ercd; 00344 00345 LOG_INI_MBX_ENTER(mbxid); 00346 CHECK_TSKCTX_UNL(); 00347 CHECK_MBXID(mbxid); 00348 p_mbxcb = get_mbxcb(mbxid); 00349 00350 t_lock_cpu(); 00351 dspreq = init_wait_queue(&(p_mbxcb->wait_queue)); 00352 p_mbxcb->pk_head = NULL; 00353 if (dspreq) { 00354 dispatch(); 00355 } 00356 ercd = E_OK; 00357 t_unlock_cpu(); 00358 00359 error_exit: 00360 LOG_INI_MBX_LEAVE(ercd); 00361 return(ercd); 00362 } 00363 00364 #endif /* TOPPERS_ini_mbx */ 00365 00366 /* 00367 * メールボックスの状態参照 00368 */ 00369 #ifdef TOPPERS_ref_mbx 00370 00371 ER 00372 ref_mbx(ID mbxid, T_RMBX *pk_rmbx) 00373 { 00374 MBXCB *p_mbxcb; 00375 ER ercd; 00376 00377 LOG_REF_MBX_ENTER(mbxid, pk_rmbx); 00378 CHECK_TSKCTX_UNL(); 00379 CHECK_MBXID(mbxid); 00380 p_mbxcb = get_mbxcb(mbxid); 00381 00382 t_lock_cpu(); 00383 pk_rmbx->wtskid = wait_tskid(&(p_mbxcb->wait_queue)); 00384 pk_rmbx->pk_msg = p_mbxcb->pk_head; 00385 ercd = E_OK; 00386 t_unlock_cpu(); 00387 00388 error_exit: 00389 LOG_REF_MBX_LEAVE(ercd, pk_rmbx); 00390 return(ercd); 00391 } 00392 00393 #endif /* TOPPERS_ref_mbx */
Copyright © 2008 by Kijineko Inc.