source: rtos_arduino/trunk/asp_1.9.2/kernel/mailbox.c@ 136

Last change on this file since 136 was 136, checked in by ertl-honda, 8 years ago

ライブラリとOS及びベーシックなサンプルの追加.

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