source: rubycfg_asp/trunk/asp_dcre/kernel/mailbox.c@ 313

Last change on this file since 313 was 313, checked in by coas-nagasima, 7 years ago

ソースを追加

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
  • Property svn:mime-type set to text/x-csrc
File size: 12.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 * 上記著作権者
12は,以下の(1)~(4)の条件を満たす場合に限り,本ソフトウェ
13 * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
14 * 変・再é…
15å¸ƒï¼ˆä»¥ä¸‹ï¼Œåˆ©ç”¨ã¨å‘¼ã¶ï¼‰ã™ã‚‹ã“とを無償で許諾する.
16 * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
17 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
18 * スコード中に含まれていること.
19 * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
20 * 用できる形で再é…
21å¸ƒã™ã‚‹å ´åˆã«ã¯ï¼Œå†é…
22å¸ƒã«ä¼´ã†ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆï¼ˆåˆ©ç”¨
23 * 者
24マニュアルなど)に,上記の著作権表示,この利用条件および下記
25 * の無保証規定を掲載すること.
26 * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
27 * 用できない形で再é…
28å¸ƒã™ã‚‹å ´åˆã«ã¯ï¼Œæ¬¡ã®ã„ずれかの条件を満たすこ
29 * と.
30 * (a) 再é…
31å¸ƒã«ä¼´ã†ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆï¼ˆåˆ©ç”¨è€…
32マニュアルなど)に,上記の著
33 * 作権表示,この利用条件および下記の無保証規定を掲載すること.
34 * (b) 再é…
35å¸ƒã®å½¢æ…
36‹ã‚’,別に定める方法によって,TOPPERSプロジェクトに
37 * 報告すること.
38 * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
39 * 害からも,上記著作権者
40およびTOPPERSプロジェクトをå…
41è²¬ã™ã‚‹ã“と.
42 * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
43 * 由に基づく請求からも,上記著作権者
44およびTOPPERSプロジェクトを
45 * å…
46è²¬ã™ã‚‹ã“と.
47 *
48 * 本ソフトウェアは,無保証で提供されているものである.上記著作権者
49お
50 * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
51 * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
52 * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
53 * の責任を負わない.
54 *
55 * $Id: mailbox.c 313 2017-07-23 04:50:32Z coas-nagasima $
56 */
57
58/*
59 * メールボックス機能
60 */
61
62#include "kernel_impl.h"
63#include "check.h"
64#include "task.h"
65#include "wait.h"
66#include "mailbox.h"
67
68/*
69 * トレースログマクロのデフォルト定義
70 */
71#ifndef LOG_ACRE_MBX_ENTER
72#define LOG_ACRE_MBX_ENTER(pk_cmbx)
73#endif /* LOG_ACRE_MBX_ENTER */
74
75#ifndef LOG_ACRE_MBX_LEAVE
76#define LOG_ACRE_MBX_LEAVE(ercd)
77#endif /* LOG_ACRE_MBX_LEAVE */
78
79#ifndef LOG_DEL_MBX_ENTER
80#define LOG_DEL_MBX_ENTER(mbxid)
81#endif /* LOG_DEL_MBX_ENTER */
82
83#ifndef LOG_DEL_MBX_LEAVE
84#define LOG_DEL_MBX_LEAVE(ercd)
85#endif /* LOG_DEL_MBX_LEAVE */
86
87#ifndef LOG_SND_MBX_ENTER
88#define LOG_SND_MBX_ENTER(mbxid, pk_msg)
89#endif /* LOG_SND_MBX_ENTER */
90
91#ifndef LOG_SND_MBX_LEAVE
92#define LOG_SND_MBX_LEAVE(ercd)
93#endif /* LOG_SND_MBX_LEAVE */
94
95#ifndef LOG_RCV_MBX_ENTER
96#define LOG_RCV_MBX_ENTER(mbxid, ppk_msg)
97#endif /* LOG_RCV_MBX_ENTER */
98
99#ifndef LOG_RCV_MBX_LEAVE
100#define LOG_RCV_MBX_LEAVE(ercd, pk_msg)
101#endif /* LOG_RCV_MBX_LEAVE */
102
103#ifndef LOG_PRCV_MBX_ENTER
104#define LOG_PRCV_MBX_ENTER(mbxid, ppk_msg)
105#endif /* LOG_PRCV_MBX_ENTER */
106
107#ifndef LOG_PRCV_MBX_LEAVE
108#define LOG_PRCV_MBX_LEAVE(ercd, pk_msg)
109#endif /* LOG_PRCV_MBX_LEAVE */
110
111#ifndef LOG_TRCV_MBX_ENTER
112#define LOG_TRCV_MBX_ENTER(mbxid, ppk_msg, tmout)
113#endif /* LOG_TRCV_MBX_ENTER */
114
115#ifndef LOG_TRCV_MBX_LEAVE
116#define LOG_TRCV_MBX_LEAVE(ercd, pk_msg)
117#endif /* LOG_TRCV_MBX_LEAVE */
118
119#ifndef LOG_INI_MBX_ENTER
120#define LOG_INI_MBX_ENTER(mbxid)
121#endif /* LOG_INI_MBX_ENTER */
122
123#ifndef LOG_INI_MBX_LEAVE
124#define LOG_INI_MBX_LEAVE(ercd)
125#endif /* LOG_INI_MBX_LEAVE */
126
127#ifndef LOG_REF_MBX_ENTER
128#define LOG_REF_MBX_ENTER(mbxid, pk_rmbx)
129#endif /* LOG_REF_MBX_ENTER */
130
131#ifndef LOG_REF_MBX_LEAVE
132#define LOG_REF_MBX_LEAVE(ercd, pk_rmbx)
133#endif /* LOG_REF_MBX_LEAVE */
134
135/*
136 * メールボックスの数
137 */
138#define tnum_mbx ((uint_t)(tmax_mbxid - TMIN_MBXID + 1))
139#define tnum_smbx ((uint_t)(tmax_smbxid - TMIN_MBXID + 1))
140
141/*
142 * メールボックスIDからメールボックス管理ブロックを取り出すためのマクロ
143 */
144#define INDEX_MBX(mbxid) ((uint_t)((mbxid) - TMIN_MBXID))
145#define get_mbxcb(mbxid) (&(mbxcb_table[INDEX_MBX(mbxid)]))
146
147#ifdef TOPPERS_mbxini
148
149/*
150 * 使用していないメールボックス管理ブロックのリスト
151 */
152QUEUE free_mbxcb;
153
154/*
155 * メールボックス機能の初期化
156 */
157void
158initialize_mailbox(void)
159{
160 uint_t i, j;
161 MBXCB *p_mbxcb;
162 MBXINIB *p_mbxinib;
163
164 for (i = 0; i < tnum_smbx; i++) {
165 p_mbxcb = &(mbxcb_table[i]);
166 queue_initialize(&(p_mbxcb->wait_queue));
167 p_mbxcb->p_mbxinib = &(mbxinib_table[i]);
168 p_mbxcb->pk_head = NULL;
169 }
170 queue_initialize(&free_mbxcb);
171 for (j = 0; i < tnum_mbx; i++, j++) {
172 p_mbxcb = &(mbxcb_table[i]);
173 p_mbxinib = &(ambxinib_table[j]);
174 p_mbxinib->mbxatr = TA_NOEXS;
175 p_mbxcb->p_mbxinib = ((const MBXINIB *) p_mbxinib);
176 queue_insert_prev(&free_mbxcb, &(p_mbxcb->wait_queue));
177 }
178}
179
180#endif /* TOPPERS_mbxini */
181
182/*
183 * メッセージ優å…
184ˆåº¦ã®å–出し
185 */
186#define MSGPRI(pk_msg) (((T_MSG_PRI *)(pk_msg))->msgpri)
187
188/*
189 * 優å…
190ˆåº¦é †ãƒ¡ãƒƒã‚»ãƒ¼ã‚¸ã‚­ãƒ¥ãƒ¼ã¸ã®æŒ¿å…
191¥
192 */
193Inline void
194enqueue_msg_pri(T_MSG **ppk_prevmsg_next, T_MSG *pk_msg)
195{
196 T_MSG *pk_nextmsg;
197
198 while ((pk_nextmsg = *ppk_prevmsg_next) != NULL) {
199 if (MSGPRI(pk_nextmsg) > MSGPRI(pk_msg)) {
200 break;
201 }
202 ppk_prevmsg_next = &(pk_nextmsg->pk_next);
203 }
204 pk_msg->pk_next = pk_nextmsg;
205 *ppk_prevmsg_next = pk_msg;
206}
207
208/*
209 * メールボックスの生成
210 */
211#ifdef TOPPERS_acre_mbx
212
213ER_UINT
214acre_mbx(const T_CMBX *pk_cmbx)
215{
216 MBXCB *p_mbxcb;
217 MBXINIB *p_mbxinib;
218 ER ercd;
219
220 LOG_ACRE_MBX_ENTER(pk_cmbx);
221 CHECK_TSKCTX_UNL();
222 CHECK_RSATR(pk_cmbx->mbxatr, TA_TPRI|TA_MPRI);
223 CHECK_MPRI(pk_cmbx->maxmpri);
224 CHECK_NOSPT(pk_cmbx->mprihd == NULL);
225
226 t_lock_cpu();
227 if (tnum_mbx == 0 || queue_empty(&free_mbxcb)) {
228 ercd = E_NOID;
229 }
230 else {
231 p_mbxcb = ((MBXCB *) queue_delete_next(&free_mbxcb));
232 p_mbxinib = (MBXINIB *)(p_mbxcb->p_mbxinib);
233 p_mbxinib->mbxatr = pk_cmbx->mbxatr;
234 p_mbxinib->maxmpri = pk_cmbx->maxmpri;
235
236 queue_initialize(&(p_mbxcb->wait_queue));
237 p_mbxcb->pk_head = NULL;
238 ercd = MBXID(p_mbxcb);
239 }
240 t_unlock_cpu();
241
242 error_exit:
243 LOG_ACRE_MBX_LEAVE(ercd);
244 return(ercd);
245}
246
247#endif /* TOPPERS_acre_mbx */
248
249/*
250 * メールボックスの削除
251 */
252#ifdef TOPPERS_del_mbx
253
254ER
255del_mbx(ID mbxid)
256{
257 MBXCB *p_mbxcb;
258 MBXINIB *p_mbxinib;
259 bool_t dspreq;
260 ER ercd;
261
262 LOG_DEL_MBX_ENTER(mbxid);
263 CHECK_TSKCTX_UNL();
264 CHECK_MBXID(mbxid);
265 p_mbxcb = get_mbxcb(mbxid);
266
267 t_lock_cpu();
268 if (p_mbxcb->p_mbxinib->mbxatr == TA_NOEXS) {
269 ercd = E_NOEXS;
270 }
271 else if (MBXID(p_mbxcb) > tmax_smbxid) {
272 dspreq = init_wait_queue(&(p_mbxcb->wait_queue));
273 p_mbxinib = (MBXINIB *)(p_mbxcb->p_mbxinib);
274 p_mbxinib->mbxatr = TA_NOEXS;
275 queue_insert_prev(&free_mbxcb, &(p_mbxcb->wait_queue));
276 if (dspreq) {
277 dispatch();
278 }
279 ercd = E_OK;
280 }
281 else {
282 ercd = E_OBJ;
283 }
284 t_unlock_cpu();
285
286 error_exit:
287 LOG_DEL_MBX_LEAVE(ercd);
288 return(ercd);
289}
290
291#endif /* TOPPERS_del_mbx */
292
293/*
294 * メールボックスへの送信
295 */
296#ifdef TOPPERS_snd_mbx
297
298ER
299snd_mbx(ID mbxid, T_MSG *pk_msg)
300{
301 MBXCB *p_mbxcb;
302 TCB *p_tcb;
303 ER ercd;
304
305 LOG_SND_MBX_ENTER(mbxid, pk_msg);
306 CHECK_TSKCTX_UNL();
307 CHECK_MBXID(mbxid);
308 p_mbxcb = get_mbxcb(mbxid);
309
310 t_lock_cpu();
311 if (p_mbxcb->p_mbxinib->mbxatr == TA_NOEXS) {
312 ercd = E_NOEXS;
313 }
314 else if (!((p_mbxcb->p_mbxinib->mbxatr & TA_MPRI) == 0U
315 || (TMIN_MPRI <= MSGPRI(pk_msg)
316 && MSGPRI(pk_msg) <= p_mbxcb->p_mbxinib->maxmpri))) {
317 ercd = E_PAR;
318 }
319 else if (!queue_empty(&(p_mbxcb->wait_queue))) {
320 p_tcb = (TCB *) queue_delete_next(&(p_mbxcb->wait_queue));
321 ((WINFO_MBX *)(p_tcb->p_winfo))->pk_msg = pk_msg;
322 if (wait_complete(p_tcb)) {
323 dispatch();
324 }
325 ercd = E_OK;
326 }
327 else if ((p_mbxcb->p_mbxinib->mbxatr & TA_MPRI) != 0U) {
328 enqueue_msg_pri(&(p_mbxcb->pk_head), pk_msg);
329 ercd = E_OK;
330 }
331 else {
332 pk_msg->pk_next = NULL;
333 if (p_mbxcb->pk_head != NULL) {
334 p_mbxcb->pk_last->pk_next = pk_msg;
335 }
336 else {
337 p_mbxcb->pk_head = pk_msg;
338 }
339 p_mbxcb->pk_last = pk_msg;
340 ercd = E_OK;
341 }
342 t_unlock_cpu();
343
344 error_exit:
345 LOG_SND_MBX_LEAVE(ercd);
346 return(ercd);
347}
348
349#endif /* TOPPERS_snd_mbx */
350
351/*
352 * メールボックスからの受信
353 */
354#ifdef TOPPERS_rcv_mbx
355
356ER
357rcv_mbx(ID mbxid, T_MSG **ppk_msg)
358{
359 MBXCB *p_mbxcb;
360 WINFO_MBX winfo_mbx;
361 ER ercd;
362
363 LOG_RCV_MBX_ENTER(mbxid, ppk_msg);
364 CHECK_DISPATCH();
365 CHECK_MBXID(mbxid);
366 p_mbxcb = get_mbxcb(mbxid);
367
368 t_lock_cpu();
369 if (p_mbxcb->p_mbxinib->mbxatr == TA_NOEXS) {
370 ercd = E_NOEXS;
371 }
372 else if (p_mbxcb->pk_head != NULL) {
373 *ppk_msg = p_mbxcb->pk_head;
374 p_mbxcb->pk_head = (*ppk_msg)->pk_next;
375 ercd = E_OK;
376 }
377 else {
378 p_runtsk->tstat = (TS_WAITING | TS_WAIT_MBX);
379 wobj_make_wait((WOBJCB *) p_mbxcb, (WINFO_WOBJ *) &winfo_mbx);
380 dispatch();
381 ercd = winfo_mbx.winfo.wercd;
382 if (ercd == E_OK) {
383 *ppk_msg = winfo_mbx.pk_msg;
384 }
385 }
386 t_unlock_cpu();
387
388 error_exit:
389 LOG_RCV_MBX_LEAVE(ercd, *ppk_msg);
390 return(ercd);
391}
392
393#endif /* TOPPERS_rcv_mbx */
394
395/*
396 * メールボックスからの受信(ポーリング)
397 */
398#ifdef TOPPERS_prcv_mbx
399
400ER
401prcv_mbx(ID mbxid, T_MSG **ppk_msg)
402{
403 MBXCB *p_mbxcb;
404 ER ercd;
405
406 LOG_PRCV_MBX_ENTER(mbxid, ppk_msg);
407 CHECK_TSKCTX_UNL();
408 CHECK_MBXID(mbxid);
409 p_mbxcb = get_mbxcb(mbxid);
410
411 t_lock_cpu();
412 if (p_mbxcb->p_mbxinib->mbxatr == TA_NOEXS) {
413 ercd = E_NOEXS;
414 }
415 else if (p_mbxcb->pk_head != NULL) {
416 *ppk_msg = p_mbxcb->pk_head;
417 p_mbxcb->pk_head = (*ppk_msg)->pk_next;
418 ercd = E_OK;
419 }
420 else {
421 ercd = E_TMOUT;
422 }
423 t_unlock_cpu();
424
425 error_exit:
426 LOG_PRCV_MBX_LEAVE(ercd, *ppk_msg);
427 return(ercd);
428}
429
430#endif /* TOPPERS_prcv_mbx */
431
432/*
433 * メールボックスからの受信(タイムアウトあり)
434 */
435#ifdef TOPPERS_trcv_mbx
436
437ER
438trcv_mbx(ID mbxid, T_MSG **ppk_msg, TMO tmout)
439{
440 MBXCB *p_mbxcb;
441 WINFO_MBX winfo_mbx;
442 TMEVTB tmevtb;
443 ER ercd;
444
445 LOG_TRCV_MBX_ENTER(mbxid, ppk_msg, tmout);
446 CHECK_DISPATCH();
447 CHECK_MBXID(mbxid);
448 CHECK_TMOUT(tmout);
449 p_mbxcb = get_mbxcb(mbxid);
450
451 t_lock_cpu();
452 if (p_mbxcb->p_mbxinib->mbxatr == TA_NOEXS) {
453 ercd = E_NOEXS;
454 }
455 else if (p_mbxcb->pk_head != NULL) {
456 *ppk_msg = p_mbxcb->pk_head;
457 p_mbxcb->pk_head = (*ppk_msg)->pk_next;
458 ercd = E_OK;
459 }
460 else if (tmout == TMO_POL) {
461 ercd = E_TMOUT;
462 }
463 else {
464 p_runtsk->tstat = (TS_WAITING | TS_WAIT_MBX);
465 wobj_make_wait_tmout((WOBJCB *) p_mbxcb, (WINFO_WOBJ *) &winfo_mbx,
466 &tmevtb, tmout);
467 dispatch();
468 ercd = winfo_mbx.winfo.wercd;
469 if (ercd == E_OK) {
470 *ppk_msg = winfo_mbx.pk_msg;
471 }
472 }
473 t_unlock_cpu();
474
475 error_exit:
476 LOG_TRCV_MBX_LEAVE(ercd, *ppk_msg);
477 return(ercd);
478}
479
480#endif /* TOPPERS_trcv_mbx */
481
482/*
483 * メールボックスの再初期化
484 */
485#ifdef TOPPERS_ini_mbx
486
487ER
488ini_mbx(ID mbxid)
489{
490 MBXCB *p_mbxcb;
491 bool_t dspreq;
492 ER ercd;
493
494 LOG_INI_MBX_ENTER(mbxid);
495 CHECK_TSKCTX_UNL();
496 CHECK_MBXID(mbxid);
497 p_mbxcb = get_mbxcb(mbxid);
498
499 t_lock_cpu();
500 if (p_mbxcb->p_mbxinib->mbxatr == TA_NOEXS) {
501 ercd = E_NOEXS;
502 }
503 else {
504 dspreq = init_wait_queue(&(p_mbxcb->wait_queue));
505 p_mbxcb->pk_head = NULL;
506 if (dspreq) {
507 dispatch();
508 }
509 ercd = E_OK;
510 }
511 t_unlock_cpu();
512
513 error_exit:
514 LOG_INI_MBX_LEAVE(ercd);
515 return(ercd);
516}
517
518#endif /* TOPPERS_ini_mbx */
519
520/*
521 * メールボックスの状æ…
522‹å‚ç…
523§
524 */
525#ifdef TOPPERS_ref_mbx
526
527ER
528ref_mbx(ID mbxid, T_RMBX *pk_rmbx)
529{
530 MBXCB *p_mbxcb;
531 ER ercd;
532
533 LOG_REF_MBX_ENTER(mbxid, pk_rmbx);
534 CHECK_TSKCTX_UNL();
535 CHECK_MBXID(mbxid);
536 p_mbxcb = get_mbxcb(mbxid);
537
538 t_lock_cpu();
539 if (p_mbxcb->p_mbxinib->mbxatr == TA_NOEXS) {
540 ercd = E_NOEXS;
541 }
542 else {
543 pk_rmbx->wtskid = wait_tskid(&(p_mbxcb->wait_queue));
544 pk_rmbx->pk_msg = p_mbxcb->pk_head;
545 ercd = E_OK;
546 }
547 t_unlock_cpu();
548
549 error_exit:
550 LOG_REF_MBX_LEAVE(ercd, pk_rmbx);
551 return(ercd);
552}
553
554#endif /* TOPPERS_ref_mbx */
Note: See TracBrowser for help on using the repository browser.