mailbox.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-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.

ホームページ制作