source: asp_wo_cfg/trunk/kernel/mailbox.c@ 49

Last change on this file since 49 was 49, checked in by ertl-hiro, 12 years ago

asp_wo_kernelをコミット。

  • Property svn:keywords set to Id
File size: 9.8 KB
Line 
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-2012 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: mailbox.c 49 2012-09-06 04:41:53Z ertl-hiro $
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_CRE_MBX_ENTER
57#define LOG_CRE_MBX_ENTER(mbxid, pk_cmbx)
58#endif /* LOG_CRE_MBX_ENTER */
59
60#ifndef LOG_CRE_MBX_LEAVE
61#define LOG_CRE_MBX_LEAVE(ercd)
62#endif /* LOG_CRE_MBX_LEAVE */
63
64#ifndef LOG_SND_MBX_ENTER
65#define LOG_SND_MBX_ENTER(mbxid, pk_msg)
66#endif /* LOG_SND_MBX_ENTER */
67
68#ifndef LOG_SND_MBX_LEAVE
69#define LOG_SND_MBX_LEAVE(ercd)
70#endif /* LOG_SND_MBX_LEAVE */
71
72#ifndef LOG_RCV_MBX_ENTER
73#define LOG_RCV_MBX_ENTER(mbxid, ppk_msg)
74#endif /* LOG_RCV_MBX_ENTER */
75
76#ifndef LOG_RCV_MBX_LEAVE
77#define LOG_RCV_MBX_LEAVE(ercd, pk_msg)
78#endif /* LOG_RCV_MBX_LEAVE */
79
80#ifndef LOG_PRCV_MBX_ENTER
81#define LOG_PRCV_MBX_ENTER(mbxid, ppk_msg)
82#endif /* LOG_PRCV_MBX_ENTER */
83
84#ifndef LOG_PRCV_MBX_LEAVE
85#define LOG_PRCV_MBX_LEAVE(ercd, pk_msg)
86#endif /* LOG_PRCV_MBX_LEAVE */
87
88#ifndef LOG_TRCV_MBX_ENTER
89#define LOG_TRCV_MBX_ENTER(mbxid, ppk_msg, tmout)
90#endif /* LOG_TRCV_MBX_ENTER */
91
92#ifndef LOG_TRCV_MBX_LEAVE
93#define LOG_TRCV_MBX_LEAVE(ercd, pk_msg)
94#endif /* LOG_TRCV_MBX_LEAVE */
95
96#ifndef LOG_INI_MBX_ENTER
97#define LOG_INI_MBX_ENTER(mbxid)
98#endif /* LOG_INI_MBX_ENTER */
99
100#ifndef LOG_INI_MBX_LEAVE
101#define LOG_INI_MBX_LEAVE(ercd)
102#endif /* LOG_INI_MBX_LEAVE */
103
104#ifndef LOG_REF_MBX_ENTER
105#define LOG_REF_MBX_ENTER(mbxid, pk_rmbx)
106#endif /* LOG_REF_MBX_ENTER */
107
108#ifndef LOG_REF_MBX_LEAVE
109#define LOG_REF_MBX_LEAVE(ercd, pk_rmbx)
110#endif /* LOG_REF_MBX_LEAVE */
111
112/*
113 * メールボックスの数
114 */
115#define tnum_mbx ((uint_t)(tmax_mbxid - TMIN_MBXID + 1))
116
117/*
118 * メールボックスIDからメールボックス管理ブロックを取り出すためのマクロ
119 */
120#define INDEX_MBX(mbxid) ((uint_t)((mbxid) - TMIN_MBXID))
121#define get_mbxcb(mbxid) (&(mbxcb_table[INDEX_MBX(mbxid)]))
122
123/*
124 * メールボックス機能の初期化
125 */
126#ifdef TOPPERS_mbxini
127
128void
129initialize_mailbox(void)
130{
131 uint_t i;
132 MBXCB *p_mbxcb;
133 MBXINIB *p_mbxinib;
134
135 for (i = 0; i < tnum_mbx; i++) {
136 p_mbxcb = &(mbxcb_table[i]);
137 p_mbxinib = &(mbxinib_table[i]);
138 p_mbxinib->mbxatr = TA_NOEXS;
139 p_mbxcb->p_mbxinib = ((const MBXINIB *) p_mbxinib);
140 }
141}
142
143#endif /* TOPPERS_mbxini */
144
145/*
146 * メッセージ優先度の取出し
147 */
148#define MSGPRI(pk_msg) (((T_MSG_PRI *)(pk_msg))->msgpri)
149
150/*
151 * 優先度順メッセージキューへの挿入
152 */
153Inline void
154enqueue_msg_pri(T_MSG **ppk_prevmsg_next, T_MSG *pk_msg)
155{
156 T_MSG *pk_nextmsg;
157
158 while ((pk_nextmsg = *ppk_prevmsg_next) != NULL) {
159 if (MSGPRI(pk_nextmsg) > MSGPRI(pk_msg)) {
160 break;
161 }
162 ppk_prevmsg_next = &(pk_nextmsg->pk_next);
163 }
164 pk_msg->pk_next = pk_nextmsg;
165 *ppk_prevmsg_next = pk_msg;
166}
167
168/*
169 * メールボックスの生成
170 */
171#ifdef TOPPERS_cre_mbx
172
173ER
174cre_mbx(ID mbxid, const T_CMBX *pk_cmbx)
175{
176 MBXCB *p_mbxcb;
177 MBXINIB *p_mbxinib;
178 ER ercd;
179
180 LOG_CRE_MBX_ENTER(mbxid, pk_cmbx);
181 CHECK_INIRTN();
182 CHECK_MBXID(mbxid);
183 CHECK_RSATR(pk_cmbx->mbxatr, TA_TPRI|TA_MPRI);
184 CHECK_MPRI(pk_cmbx->maxmpri);
185 CHECK_NOSPT(pk_cmbx->mprihd == NULL);
186 p_mbxcb = get_mbxcb(mbxid);
187
188 if (p_mbxcb->p_mbxinib->mbxatr != TA_NOEXS) {
189 ercd = E_OBJ;
190 }
191 else {
192 p_mbxinib = (MBXINIB *)(p_mbxcb->p_mbxinib);
193 p_mbxinib->mbxatr = pk_cmbx->mbxatr;
194 p_mbxinib->maxmpri = pk_cmbx->maxmpri;
195
196 queue_initialize(&(p_mbxcb->wait_queue));
197 p_mbxcb->pk_head = NULL;
198 ercd = E_OK;
199 }
200
201 error_exit:
202 LOG_CRE_MBX_LEAVE(ercd);
203 return(ercd);
204}
205
206#endif /* TOPPERS_cre_mbx */
207
208/*
209 * メールボックスへの送信
210 */
211#ifdef TOPPERS_snd_mbx
212
213ER
214snd_mbx(ID mbxid, T_MSG *pk_msg)
215{
216 MBXCB *p_mbxcb;
217 TCB *p_tcb;
218 ER ercd;
219
220 LOG_SND_MBX_ENTER(mbxid, pk_msg);
221 CHECK_TSKCTX_UNL();
222 CHECK_MBXID(mbxid);
223 p_mbxcb = get_mbxcb(mbxid);
224 CHECK_NOEXS(p_mbxcb->p_mbxinib->mbxatr);
225 CHECK_PAR((p_mbxcb->p_mbxinib->mbxatr & TA_MPRI) == 0U
226 || (TMIN_MPRI <= MSGPRI(pk_msg)
227 && MSGPRI(pk_msg) <= p_mbxcb->p_mbxinib->maxmpri));
228
229 t_lock_cpu();
230 if (!queue_empty(&(p_mbxcb->wait_queue))) {
231 p_tcb = (TCB *) queue_delete_next(&(p_mbxcb->wait_queue));
232 ((WINFO_MBX *)(p_tcb->p_winfo))->pk_msg = pk_msg;
233 if (wait_complete(p_tcb)) {
234 dispatch();
235 }
236 ercd = E_OK;
237 }
238 else if ((p_mbxcb->p_mbxinib->mbxatr & TA_MPRI) != 0U) {
239 enqueue_msg_pri(&(p_mbxcb->pk_head), pk_msg);
240 ercd = E_OK;
241 }
242 else {
243 pk_msg->pk_next = NULL;
244 if (p_mbxcb->pk_head != NULL) {
245 p_mbxcb->pk_last->pk_next = pk_msg;
246 }
247 else {
248 p_mbxcb->pk_head = pk_msg;
249 }
250 p_mbxcb->pk_last = pk_msg;
251 ercd = E_OK;
252 }
253 t_unlock_cpu();
254
255 error_exit:
256 LOG_SND_MBX_LEAVE(ercd);
257 return(ercd);
258}
259
260#endif /* TOPPERS_snd_mbx */
261
262/*
263 * メールボックスからの受信
264 */
265#ifdef TOPPERS_rcv_mbx
266
267ER
268rcv_mbx(ID mbxid, T_MSG **ppk_msg)
269{
270 MBXCB *p_mbxcb;
271 WINFO_MBX winfo_mbx;
272 ER ercd;
273
274 LOG_RCV_MBX_ENTER(mbxid, ppk_msg);
275 CHECK_DISPATCH();
276 CHECK_MBXID(mbxid);
277 p_mbxcb = get_mbxcb(mbxid);
278 CHECK_NOEXS(p_mbxcb->p_mbxinib->mbxatr);
279
280 t_lock_cpu();
281 if (p_mbxcb->pk_head != NULL) {
282 *ppk_msg = p_mbxcb->pk_head;
283 p_mbxcb->pk_head = (*ppk_msg)->pk_next;
284 ercd = E_OK;
285 }
286 else {
287 p_runtsk->tstat = (TS_WAITING | TS_WAIT_MBX);
288 wobj_make_wait((WOBJCB *) p_mbxcb, (WINFO_WOBJ *) &winfo_mbx);
289 dispatch();
290 ercd = winfo_mbx.winfo.wercd;
291 if (ercd == E_OK) {
292 *ppk_msg = winfo_mbx.pk_msg;
293 }
294 }
295 t_unlock_cpu();
296
297 error_exit:
298 LOG_RCV_MBX_LEAVE(ercd, *ppk_msg);
299 return(ercd);
300}
301
302#endif /* TOPPERS_rcv_mbx */
303
304/*
305 * メールボックスからの受信(ポーリング)
306 */
307#ifdef TOPPERS_prcv_mbx
308
309ER
310prcv_mbx(ID mbxid, T_MSG **ppk_msg)
311{
312 MBXCB *p_mbxcb;
313 ER ercd;
314
315 LOG_PRCV_MBX_ENTER(mbxid, ppk_msg);
316 CHECK_TSKCTX_UNL();
317 CHECK_MBXID(mbxid);
318 p_mbxcb = get_mbxcb(mbxid);
319 CHECK_NOEXS(p_mbxcb->p_mbxinib->mbxatr);
320
321 t_lock_cpu();
322 if (p_mbxcb->pk_head != NULL) {
323 *ppk_msg = p_mbxcb->pk_head;
324 p_mbxcb->pk_head = (*ppk_msg)->pk_next;
325 ercd = E_OK;
326 }
327 else {
328 ercd = E_TMOUT;
329 }
330 t_unlock_cpu();
331
332 error_exit:
333 LOG_PRCV_MBX_LEAVE(ercd, *ppk_msg);
334 return(ercd);
335}
336
337#endif /* TOPPERS_prcv_mbx */
338
339/*
340 * メールボックスからの受信(タイムアウトあり)
341 */
342#ifdef TOPPERS_trcv_mbx
343
344ER
345trcv_mbx(ID mbxid, T_MSG **ppk_msg, TMO tmout)
346{
347 MBXCB *p_mbxcb;
348 WINFO_MBX winfo_mbx;
349 TMEVTB tmevtb;
350 ER ercd;
351
352 LOG_TRCV_MBX_ENTER(mbxid, ppk_msg, tmout);
353 CHECK_DISPATCH();
354 CHECK_MBXID(mbxid);
355 CHECK_TMOUT(tmout);
356 p_mbxcb = get_mbxcb(mbxid);
357 CHECK_NOEXS(p_mbxcb->p_mbxinib->mbxatr);
358
359 t_lock_cpu();
360 if (p_mbxcb->pk_head != NULL) {
361 *ppk_msg = p_mbxcb->pk_head;
362 p_mbxcb->pk_head = (*ppk_msg)->pk_next;
363 ercd = E_OK;
364 }
365 else if (tmout == TMO_POL) {
366 ercd = E_TMOUT;
367 }
368 else {
369 p_runtsk->tstat = (TS_WAITING | TS_WAIT_MBX);
370 wobj_make_wait_tmout((WOBJCB *) p_mbxcb, (WINFO_WOBJ *) &winfo_mbx,
371 &tmevtb, tmout);
372 dispatch();
373 ercd = winfo_mbx.winfo.wercd;
374 if (ercd == E_OK) {
375 *ppk_msg = winfo_mbx.pk_msg;
376 }
377 }
378 t_unlock_cpu();
379
380 error_exit:
381 LOG_TRCV_MBX_LEAVE(ercd, *ppk_msg);
382 return(ercd);
383}
384
385#endif /* TOPPERS_trcv_mbx */
386
387/*
388 * メールボックスの再初期化
389 */
390#ifdef TOPPERS_ini_mbx
391
392ER
393ini_mbx(ID mbxid)
394{
395 MBXCB *p_mbxcb;
396 bool_t dspreq;
397 ER ercd;
398
399 LOG_INI_MBX_ENTER(mbxid);
400 CHECK_TSKCTX_UNL();
401 CHECK_MBXID(mbxid);
402 p_mbxcb = get_mbxcb(mbxid);
403 CHECK_NOEXS(p_mbxcb->p_mbxinib->mbxatr);
404
405 t_lock_cpu();
406 dspreq = init_wait_queue(&(p_mbxcb->wait_queue));
407 p_mbxcb->pk_head = NULL;
408 if (dspreq) {
409 dispatch();
410 }
411 ercd = E_OK;
412 t_unlock_cpu();
413
414 error_exit:
415 LOG_INI_MBX_LEAVE(ercd);
416 return(ercd);
417}
418
419#endif /* TOPPERS_ini_mbx */
420
421/*
422 * メールボックスの状態参照
423 */
424#ifdef TOPPERS_ref_mbx
425
426ER
427ref_mbx(ID mbxid, T_RMBX *pk_rmbx)
428{
429 MBXCB *p_mbxcb;
430 ER ercd;
431
432 LOG_REF_MBX_ENTER(mbxid, pk_rmbx);
433 CHECK_TSKCTX_UNL();
434 CHECK_MBXID(mbxid);
435 p_mbxcb = get_mbxcb(mbxid);
436 CHECK_NOEXS(p_mbxcb->p_mbxinib->mbxatr);
437
438 t_lock_cpu();
439 pk_rmbx->wtskid = wait_tskid(&(p_mbxcb->wait_queue));
440 pk_rmbx->pk_msg = p_mbxcb->pk_head;
441 ercd = E_OK;
442 t_unlock_cpu();
443
444 error_exit:
445 LOG_REF_MBX_LEAVE(ercd, pk_rmbx);
446 return(ercd);
447}
448
449#endif /* TOPPERS_ref_mbx */
Note: See TracBrowser for help on using the repository browser.