source: UsbWattMeter/trunk/asp_dcre/kernel/mailbox.c

Last change on this file was 167, checked in by coas-nagasima, 8 years ago

MIMEにSJISを設定

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