source: mypx/kernel/mailbox.c

このファイルの最終更新内容7 で kominami が 2015/09/12 9:22:12 に更新しました

TOPPERS/ASP 1.9.1

ファイルサイズ: 8.6 KB
Rev 
[7]1/*
2 *  TOPPERS/ASP Kernel
3 *      Toyohashi Open Platform for Embedded Real-Time Systems/
4 *      Advanced Standard Profile Kernel
5 *
6 *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
7 *                              Toyohashi Univ. of Technology, JAPAN
8 *  Copyright (C) 2005-2011 by Embedded and Real-Time Systems Laboratory
9 *              Graduate School of Information Science, Nagoya Univ., JAPAN
10 *
11 *  Ÿåµ­Ãøºîž¢ŒÔ€Ï¡€°Ê²Œ€Î(1)¡Á(4)€ÎŸò·ï€òËþ€¿€¹Ÿì¹ç€ËžÂ€ê¡€ËÜ¥œ¥Õ¥È¥Š¥§
12 *  ¥¢¡ÊËÜ¥œ¥Õ¥È¥Š¥§¥¢€ò²þÊÑ€·€¿€â€Î€òŽÞ€à¡¥°Ê²ŒÆ±€ž¡Ë€ò»ÈÍÑ¡ŠÊ£Àœ¡Š²þ
13 *  ÊÑ¡ŠºÆÇÛÉۡʰʲŒ¡€ÍøÍрȞƀ֡ˀ¹€ë€³€È€ò̵œþ€ÇµöÂú€¹€ë¡¥
14 *  (1) ËÜ¥œ¥Õ¥È¥Š¥§¥¢€ò¥œ¡Œ¥¹¥³¡Œ¥É€Î·Á€ÇÍøÍÑ€¹€ëŸì¹ç€Ë€Ï¡€Ÿåµ­€ÎÃøºî
15 *      ž¢ÉœŒš¡€€³€ÎÍøÍÑŸò·ï€ª€è€Ó²Œµ­€Î̵ÊÝŸÚµ¬Äꀬ¡€€œ€Î€Þ€Þ€Î·Á€Ç¥œ¡Œ
16 *      ¥¹¥³¡Œ¥ÉÃæ€ËŽÞ€Þ€ì€Æ€€€ë€³€È¡¥
17 *  (2) ËÜ¥œ¥Õ¥È¥Š¥§¥¢€ò¡€¥é¥€¥Ö¥é¥ê·ÁŒ°€Ê€É¡€ÂŸ€Î¥œ¥Õ¥È¥Š¥§¥¢³«È¯€Ë»È
18 *      Íрǀ­€ë·Á€ÇºÆÇÛÉÛ€¹€ëŸì¹ç€Ë€Ï¡€ºÆÇÛÉÛ€ËÈŒ€Š¥É¥­¥å¥á¥ó¥È¡ÊÍøÍÑ
19 *      ŒÔ¥Þ¥Ë¥å¥¢¥ë€Ê€É¡Ë€Ë¡€Ÿåµ­€ÎÃøºîž¢ÉœŒš¡€€³€ÎÍøÍÑŸò·ï€ª€è€Ó²Œµ­
20 *      €Î̵ÊÝŸÚµ¬Äê€ò·ÇºÜ€¹€ë€³€È¡¥
21 *  (3) ËÜ¥œ¥Õ¥È¥Š¥§¥¢€ò¡€µ¡Žï€ËÁȀ߹þ€à€Ê€É¡€ÂŸ€Î¥œ¥Õ¥È¥Š¥§¥¢³«È¯€Ë»È
22 *      Íрǀ­€Ê€€·Á€ÇºÆÇÛÉÛ€¹€ëŸì¹ç€Ë€Ï¡€Œ¡€Î€€€º€ì€«€ÎŸò·ï€òËþ€¿€¹€³
23 *      €È¡¥
24 *    (a) ºÆÇÛÉÛ€ËÈŒ€Š¥É¥­¥å¥á¥ó¥È¡ÊÍøÍьԥޥ˥奢¥ë€Ê€É¡Ë€Ë¡€Ÿåµ­€ÎÃø
25 *        ºîž¢ÉœŒš¡€€³€ÎÍøÍÑŸò·ï€ª€è€Ó²Œµ­€Î̵ÊÝŸÚµ¬Äê€ò·ÇºÜ€¹€ë€³€È¡¥
26 *    (b) ºÆÇÛÉۀηÁÂÖ€ò¡€ÊÌ€ËÄê€á€ëÊýË¡€Ë€è€Ã€Æ¡€TOPPERS¥×¥í¥ž¥§¥¯¥È€Ë
27 *        Êó¹ð€¹€ë€³€È¡¥
28 *  (4) ËÜ¥œ¥Õ¥È¥Š¥§¥¢€ÎÍøÍрˀè€êÄŸÀÜŪ€Þ€¿€ÏŽÖÀÜŪ€ËÀž€ž€ë€€€«€Ê€ë»
29 *      ³²€«€é€â¡€Ÿåµ­Ãøºîž¢ŒÔ€ª€è€ÓTOPPERS¥×¥í¥ž¥§¥¯¥È€òÌÈÀÕ€¹€ë€³€È¡¥
30 *      €Þ€¿¡€ËÜ¥œ¥Õ¥È¥Š¥§¥¢€Î¥æ¡Œ¥¶€Þ€¿€Ï¥š¥ó¥É¥æ¡Œ¥¶€«€é€Î€€€«€Ê€ëÍý
31 *      ͳ€ËŽð€Å€¯ÀÁµá€«€é€â¡€Ÿåµ­Ãøºîž¢ŒÔ€ª€è€ÓTOPPERS¥×¥í¥ž¥§¥¯¥È€ò
32 *      ÌÈÀÕ€¹€ë€³€È¡¥
33 *
34 *  ËÜ¥œ¥Õ¥È¥Š¥§¥¢€Ï¡€ÌµÊÝŸÚ€ÇÄó¶¡€µ€ì€Æ€€€ë€â€Î€Ç€¢€ë¡¥Ÿåµ­Ãøºîž¢ŒÔ€ª
35 *  €è€ÓTOPPERS¥×¥í¥ž¥§¥¯¥È€Ï¡€ËÜ¥œ¥Õ¥È¥Š¥§¥¢€ËŽØ€·€Æ¡€ÆÃÄê€Î»ÈÍÑÌÜŪ
36 *  €ËÂЀ¹€ëŬ¹çÀ­€âŽÞ€á€Æ¡€€€€«€Ê€ëÊÝŸÚ€â¹Ô€ï€Ê€€¡¥€Þ€¿¡€ËÜ¥œ¥Õ¥È¥Š¥§
37 *  ¥¢€ÎÍøÍрˀè€êÄŸÀÜŪ€Þ€¿€ÏŽÖÀÜŪ€ËÀž€ž€¿€€€«€Ê€ë»³²€ËŽØ€·€Æ€â¡€€œ
38 *  €ÎÀÕÇ€€òÉé€ï€Ê€€¡¥
39 *
40 *  @(#) $Id$
41 */
42
43/*
44 *              ¥á¡Œ¥ë¥Ü¥Ã¥¯¥¹µ¡Çœ
45 */
46
47#include "kernel_impl.h"
48#include "check.h"
49#include "task.h"
50#include "wait.h"
51#include "mailbox.h"
52
53/*
54 *  ¥È¥ì¡Œ¥¹¥í¥°¥Þ¥¯¥í€Î¥Ç¥Õ¥©¥ë¥ÈÄêµÁ
55 */
56#ifndef LOG_SND_MBX_ENTER
57#define LOG_SND_MBX_ENTER(mbxid, pk_msg)
58#endif /* LOG_SND_MBX_ENTER */
59
60#ifndef LOG_SND_MBX_LEAVE
61#define LOG_SND_MBX_LEAVE(ercd)
62#endif /* LOG_SND_MBX_LEAVE */
63
64#ifndef LOG_RCV_MBX_ENTER
65#define LOG_RCV_MBX_ENTER(mbxid, ppk_msg)
66#endif /* LOG_RCV_MBX_ENTER */
67
68#ifndef LOG_RCV_MBX_LEAVE
69#define LOG_RCV_MBX_LEAVE(ercd, pk_msg)
70#endif /* LOG_RCV_MBX_LEAVE */
71
72#ifndef LOG_PRCV_MBX_ENTER
73#define LOG_PRCV_MBX_ENTER(mbxid, ppk_msg)
74#endif /* LOG_PRCV_MBX_ENTER */
75
76#ifndef LOG_PRCV_MBX_LEAVE
77#define LOG_PRCV_MBX_LEAVE(ercd, pk_msg)
78#endif /* LOG_PRCV_MBX_LEAVE */
79
80#ifndef LOG_TRCV_MBX_ENTER
81#define LOG_TRCV_MBX_ENTER(mbxid, ppk_msg, tmout)
82#endif /* LOG_TRCV_MBX_ENTER */
83
84#ifndef LOG_TRCV_MBX_LEAVE
85#define LOG_TRCV_MBX_LEAVE(ercd, pk_msg)
86#endif /* LOG_TRCV_MBX_LEAVE */
87
88#ifndef LOG_INI_MBX_ENTER
89#define LOG_INI_MBX_ENTER(mbxid)
90#endif /* LOG_INI_MBX_ENTER */
91
92#ifndef LOG_INI_MBX_LEAVE
93#define LOG_INI_MBX_LEAVE(ercd)
94#endif /* LOG_INI_MBX_LEAVE */
95
96#ifndef LOG_REF_MBX_ENTER
97#define LOG_REF_MBX_ENTER(mbxid, pk_rmbx)
98#endif /* LOG_REF_MBX_ENTER */
99
100#ifndef LOG_REF_MBX_LEAVE
101#define LOG_REF_MBX_LEAVE(ercd, pk_rmbx)
102#endif /* LOG_REF_MBX_LEAVE */
103
104/*
105 *  ¥á¡Œ¥ë¥Ü¥Ã¥¯¥¹€Î¿ô
106 */
107#define tnum_mbx        ((uint_t)(tmax_mbxid - TMIN_MBXID + 1))
108
109/*
110 *  ¥á¡Œ¥ë¥Ü¥Ã¥¯¥¹ID€«€é¥á¡Œ¥ë¥Ü¥Ã¥¯¥¹ŽÉÍý¥Ö¥í¥Ã¥¯€òŒè€êœÐ€¹€¿€á€Î¥Þ¥¯¥í
111 */
112#define INDEX_MBX(mbxid)        ((uint_t)((mbxid) - TMIN_MBXID))
113#define get_mbxcb(mbxid)        (&(mbxcb_table[INDEX_MBX(mbxid)]))
114
115/*
116 *  ¥á¡Œ¥ë¥Ü¥Ã¥¯¥¹µ¡Çœ€ÎœéŽü²œ
117 */
118#ifdef TOPPERS_mbxini
119
120void
121initialize_mailbox(void)
122{
123        uint_t  i;
124        MBXCB   *p_mbxcb;
125
126        for (i = 0; i < tnum_mbx; i++) {
127                p_mbxcb = &(mbxcb_table[i]);
128                queue_initialize(&(p_mbxcb->wait_queue));
129                p_mbxcb->p_mbxinib = &(mbxinib_table[i]);
130                p_mbxcb->pk_head = NULL;
131        }
132}
133
134#endif /* TOPPERS_mbxini */
135
136/*
137 *  ¥á¥Ã¥»¡Œ¥žÍ¥ÀèÅـΌèœÐ€·
138 */
139#define MSGPRI(pk_msg)  (((T_MSG_PRI *)(pk_msg))->msgpri)
140
141/*
142 *  Í¥ÀèÅÙœç¥á¥Ã¥»¡Œ¥ž¥­¥å¡Œ€Ø€ÎÁÞÆþ
143 */
144Inline void
145enqueue_msg_pri(T_MSG **ppk_prevmsg_next, T_MSG *pk_msg)
146{
147        T_MSG   *pk_nextmsg;
148
149        while ((pk_nextmsg = *ppk_prevmsg_next) != NULL) {
150                if (MSGPRI(pk_nextmsg) > MSGPRI(pk_msg)) {
151                        break;
152                }
153                ppk_prevmsg_next = &(pk_nextmsg->pk_next);
154        }
155        pk_msg->pk_next = pk_nextmsg;
156        *ppk_prevmsg_next = pk_msg;
157}
158
159/*
160 *  ¥á¡Œ¥ë¥Ü¥Ã¥¯¥¹€Ø€ÎÁ÷¿®
161 */
162#ifdef TOPPERS_snd_mbx
163
164ER
165snd_mbx(ID mbxid, T_MSG *pk_msg)
166{
167        MBXCB   *p_mbxcb;
168        TCB             *p_tcb;
169        ER              ercd;
170   
171        LOG_SND_MBX_ENTER(mbxid, pk_msg);
172        CHECK_TSKCTX_UNL();
173        CHECK_MBXID(mbxid);
174        p_mbxcb = get_mbxcb(mbxid);
175        CHECK_PAR((p_mbxcb->p_mbxinib->mbxatr & TA_MPRI) == 0U
176                                || (TMIN_MPRI <= MSGPRI(pk_msg)
177                                        && MSGPRI(pk_msg) <= p_mbxcb->p_mbxinib->maxmpri));
178
179        t_lock_cpu();
180        if (!queue_empty(&(p_mbxcb->wait_queue))) {
181                p_tcb = (TCB *) queue_delete_next(&(p_mbxcb->wait_queue));
182                ((WINFO_MBX *)(p_tcb->p_winfo))->pk_msg = pk_msg;
183                if (wait_complete(p_tcb)) {
184                        dispatch();
185                }
186                ercd = E_OK;
187        }
188        else if ((p_mbxcb->p_mbxinib->mbxatr & TA_MPRI) != 0U) {
189                enqueue_msg_pri(&(p_mbxcb->pk_head), pk_msg);
190                ercd = E_OK;
191        }
192        else {
193                pk_msg->pk_next = NULL;
194                if (p_mbxcb->pk_head != NULL) {
195                        p_mbxcb->pk_last->pk_next = pk_msg;
196                }
197                else {
198                        p_mbxcb->pk_head = pk_msg;
199                }
200                p_mbxcb->pk_last = pk_msg;
201                ercd = E_OK;
202        }
203        t_unlock_cpu();
204
205  error_exit:
206        LOG_SND_MBX_LEAVE(ercd);
207        return(ercd);
208}
209
210#endif /* TOPPERS_snd_mbx */
211
212/*
213 *  ¥á¡Œ¥ë¥Ü¥Ã¥¯¥¹€«€é€ÎŒõ¿®
214 */
215#ifdef TOPPERS_rcv_mbx
216
217ER
218rcv_mbx(ID mbxid, T_MSG **ppk_msg)
219{
220        MBXCB   *p_mbxcb;
221        WINFO_MBX winfo_mbx;
222        ER              ercd;
223   
224        LOG_RCV_MBX_ENTER(mbxid, ppk_msg);
225        CHECK_DISPATCH();
226        CHECK_MBXID(mbxid);
227        p_mbxcb = get_mbxcb(mbxid);
228   
229        t_lock_cpu();
230        if (p_mbxcb->pk_head != NULL) {
231                *ppk_msg = p_mbxcb->pk_head;
232                p_mbxcb->pk_head = (*ppk_msg)->pk_next;
233                ercd = E_OK;
234        }
235        else {
236                p_runtsk->tstat = (TS_WAITING | TS_WAIT_MBX);
237                wobj_make_wait((WOBJCB *) p_mbxcb, (WINFO_WOBJ *) &winfo_mbx);
238                dispatch();
239                ercd = winfo_mbx.winfo.wercd;
240                if (ercd == E_OK) {
241                        *ppk_msg = winfo_mbx.pk_msg;
242                }
243        }
244        t_unlock_cpu();
245
246  error_exit:
247        LOG_RCV_MBX_LEAVE(ercd, *ppk_msg);
248        return(ercd);
249}
250
251#endif /* TOPPERS_rcv_mbx */
252
253/*
254 *  ¥á¡Œ¥ë¥Ü¥Ã¥¯¥¹€«€é€ÎŒõ¿®¡Ê¥Ý¡Œ¥ê¥ó¥°¡Ë
255 */
256#ifdef TOPPERS_prcv_mbx
257
258ER
259prcv_mbx(ID mbxid, T_MSG **ppk_msg)
260{
261        MBXCB   *p_mbxcb;
262        ER              ercd;
263   
264        LOG_PRCV_MBX_ENTER(mbxid, ppk_msg);
265        CHECK_TSKCTX_UNL();
266        CHECK_MBXID(mbxid);
267        p_mbxcb = get_mbxcb(mbxid);
268   
269        t_lock_cpu();
270        if (p_mbxcb->pk_head != NULL) {
271                *ppk_msg = p_mbxcb->pk_head;
272                p_mbxcb->pk_head = (*ppk_msg)->pk_next;
273                ercd = E_OK;
274        }
275        else {
276                ercd = E_TMOUT;
277        }
278        t_unlock_cpu();
279
280  error_exit:
281        LOG_PRCV_MBX_LEAVE(ercd, *ppk_msg);
282        return(ercd);
283}
284
285#endif /* TOPPERS_prcv_mbx */
286
287/*
288 *  ¥á¡Œ¥ë¥Ü¥Ã¥¯¥¹€«€é€ÎŒõ¿®¡Ê¥¿¥€¥à¥¢¥Š¥È€¢€ê¡Ë
289 */
290#ifdef TOPPERS_trcv_mbx
291
292ER
293trcv_mbx(ID mbxid, T_MSG **ppk_msg, TMO tmout)
294{
295        MBXCB   *p_mbxcb;
296        WINFO_MBX winfo_mbx;
297        TMEVTB  tmevtb;
298        ER              ercd;
299   
300        LOG_TRCV_MBX_ENTER(mbxid, ppk_msg, tmout);
301        CHECK_DISPATCH();
302        CHECK_MBXID(mbxid);
303        CHECK_TMOUT(tmout);
304        p_mbxcb = get_mbxcb(mbxid);
305   
306        t_lock_cpu();
307        if (p_mbxcb->pk_head != NULL) {
308                *ppk_msg = p_mbxcb->pk_head;
309                p_mbxcb->pk_head = (*ppk_msg)->pk_next;
310                ercd = E_OK;
311        }
312        else if (tmout == TMO_POL) {
313                ercd = E_TMOUT;
314        }
315        else {
316                p_runtsk->tstat = (TS_WAITING | TS_WAIT_MBX);
317                wobj_make_wait_tmout((WOBJCB *) p_mbxcb, (WINFO_WOBJ *) &winfo_mbx,
318                                                                                                                &tmevtb, tmout);
319                dispatch();
320                ercd = winfo_mbx.winfo.wercd;
321                if (ercd == E_OK) {
322                        *ppk_msg = winfo_mbx.pk_msg;
323                }
324        }
325        t_unlock_cpu();
326
327  error_exit:
328        LOG_TRCV_MBX_LEAVE(ercd, *ppk_msg);
329        return(ercd);
330}
331
332#endif /* TOPPERS_trcv_mbx */
333
334/*
335 *  ¥á¡Œ¥ë¥Ü¥Ã¥¯¥¹€ÎºÆœéŽü²œ
336 */
337#ifdef TOPPERS_ini_mbx
338
339ER
340ini_mbx(ID mbxid)
341{
342        MBXCB   *p_mbxcb;
343        bool_t  dspreq;
344        ER              ercd;
345   
346        LOG_INI_MBX_ENTER(mbxid);
347        CHECK_TSKCTX_UNL();
348        CHECK_MBXID(mbxid);
349        p_mbxcb = get_mbxcb(mbxid);
350
351        t_lock_cpu();
352        dspreq = init_wait_queue(&(p_mbxcb->wait_queue));
353        p_mbxcb->pk_head = NULL;
354        if (dspreq) {
355                dispatch();
356        }
357        ercd = E_OK;
358        t_unlock_cpu();
359
360  error_exit:
361        LOG_INI_MBX_LEAVE(ercd);
362        return(ercd);
363}
364
365#endif /* TOPPERS_ini_mbx */
366
367/*
368 *  ¥á¡Œ¥ë¥Ü¥Ã¥¯¥¹€ÎŸõÂÖ»²ŸÈ
369 */
370#ifdef TOPPERS_ref_mbx
371
372ER
373ref_mbx(ID mbxid, T_RMBX *pk_rmbx)
374{
375        MBXCB   *p_mbxcb;
376        ER              ercd;
377   
378        LOG_REF_MBX_ENTER(mbxid, pk_rmbx);
379        CHECK_TSKCTX_UNL();
380        CHECK_MBXID(mbxid);
381        p_mbxcb = get_mbxcb(mbxid);
382
383        t_lock_cpu();
384        pk_rmbx->wtskid = wait_tskid(&(p_mbxcb->wait_queue));
385        pk_rmbx->pk_msg = p_mbxcb->pk_head;
386        ercd = E_OK;
387        t_unlock_cpu();
388
389  error_exit:
390        LOG_REF_MBX_LEAVE(ercd, pk_rmbx);
391        return(ercd);
392}
393
394#endif /* TOPPERS_ref_mbx */
詳しい使い方は TracBrowser を参照してください。