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

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

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

File size: 11.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-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: eventflag.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 "eventflag.h"
67
68/*
69 * トレースログマクロのデフォルト定義
70 */
71#ifndef LOG_SET_FLG_ENTER
72#define LOG_SET_FLG_ENTER(flgid, setptn)
73#endif /* LOG_SET_FLG_ENTER */
74
75#ifndef LOG_SET_FLG_LEAVE
76#define LOG_SET_FLG_LEAVE(ercd)
77#endif /* LOG_SET_FLG_LEAVE */
78
79#ifndef LOG_ISET_FLG_ENTER
80#define LOG_ISET_FLG_ENTER(flgid, setptn)
81#endif /* LOG_ISET_FLG_ENTER */
82
83#ifndef LOG_ISET_FLG_LEAVE
84#define LOG_ISET_FLG_LEAVE(ercd)
85#endif /* LOG_ISET_FLG_LEAVE */
86
87#ifndef LOG_CLR_FLG_ENTER
88#define LOG_CLR_FLG_ENTER(flgid, clrptn)
89#endif /* LOG_CLR_FLG_ENTER */
90
91#ifndef LOG_CLR_FLG_LEAVE
92#define LOG_CLR_FLG_LEAVE(ercd)
93#endif /* LOG_CLR_FLG_LEAVE */
94
95#ifndef LOG_WAI_FLG_ENTER
96#define LOG_WAI_FLG_ENTER(flgid, waiptn, wfmode, p_flgptn)
97#endif /* LOG_WAI_FLG_ENTER */
98
99#ifndef LOG_WAI_FLG_LEAVE
100#define LOG_WAI_FLG_LEAVE(ercd, flgptn)
101#endif /* LOG_WAI_FLG_LEAVE */
102
103#ifndef LOG_POL_FLG_ENTER
104#define LOG_POL_FLG_ENTER(flgid, waiptn, wfmode, p_flgptn)
105#endif /* LOG_POL_FLG_ENTER */
106
107#ifndef LOG_POL_FLG_LEAVE
108#define LOG_POL_FLG_LEAVE(ercd, flgptn)
109#endif /* LOG_POL_FLG_LEAVE */
110
111#ifndef LOG_TWAI_FLG_ENTER
112#define LOG_TWAI_FLG_ENTER(flgid, waiptn, wfmode, p_flgptn, tmout)
113#endif /* LOG_TWAI_FLG_ENTER */
114
115#ifndef LOG_TWAI_FLG_LEAVE
116#define LOG_TWAI_FLG_LEAVE(ercd, flgptn)
117#endif /* LOG_TWAI_FLG_LEAVE */
118
119#ifndef LOG_INI_FLG_ENTER
120#define LOG_INI_FLG_ENTER(flgid)
121#endif /* LOG_INI_FLG_ENTER */
122
123#ifndef LOG_INI_FLG_LEAVE
124#define LOG_INI_FLG_LEAVE(ercd)
125#endif /* LOG_INI_FLG_LEAVE */
126
127#ifndef LOG_REF_FLG_ENTER
128#define LOG_REF_FLG_ENTER(flgid, pk_rflg)
129#endif /* LOG_REF_FLG_ENTER */
130
131#ifndef LOG_REF_FLG_LEAVE
132#define LOG_REF_FLG_LEAVE(ercd, pk_rflg)
133#endif /* LOG_REF_FLG_LEAVE */
134
135/*
136 * イベントフラグの数
137 */
138#define tnum_flg ((uint_t)(tmax_flgid - TMIN_FLGID + 1))
139
140/*
141 * イベントフラグIDからイベントフラグ管理ブロックを取り出すためのマクロ
142 */
143#define INDEX_FLG(flgid) ((uint_t)((flgid) - TMIN_FLGID))
144#define get_flgcb(flgid) (&(flgcb_table[INDEX_FLG(flgid)]))
145
146/*
147 * イベントフラグ機能の初期化
148 */
149#ifdef TOPPERS_flgini
150
151void
152initialize_eventflag(void)
153{
154 uint_t i;
155 FLGCB *p_flgcb;
156
157 for (i = 0; i < tnum_flg; i++) {
158 p_flgcb = &(flgcb_table[i]);
159 queue_initialize(&(p_flgcb->wait_queue));
160 p_flgcb->p_flginib = &(flginib_table[i]);
161 p_flgcb->flgptn = p_flgcb->p_flginib->iflgptn;
162 }
163}
164
165#endif /* TOPPERS_flgini */
166
167/*
168 * イベントフラグ待
169ち解除条件のチェック
170 */
171#ifdef TOPPERS_flgcnd
172
173bool_t
174check_flg_cond(FLGCB *p_flgcb, FLGPTN waiptn, MODE wfmode, FLGPTN *p_flgptn)
175{
176 if ((wfmode & TWF_ORW) != 0U ? (p_flgcb->flgptn & waiptn) != 0U
177 : (p_flgcb->flgptn & waiptn) == waiptn) {
178 *p_flgptn = p_flgcb->flgptn;
179 if ((p_flgcb->p_flginib->flgatr & TA_CLR) != 0U) {
180 p_flgcb->flgptn = 0U;
181 }
182 return(true);
183 }
184 return(false);
185}
186
187#endif /* TOPPERS_flgcnd */
188
189/*
190 * イベントフラグのセット
191 */
192#ifdef TOPPERS_set_flg
193
194ER
195set_flg(ID flgid, FLGPTN setptn)
196{
197 FLGCB *p_flgcb;
198 QUEUE *p_queue;
199 TCB *p_tcb;
200 WINFO_FLG *p_winfo_flg;
201 bool_t dspreq = false;
202 ER ercd;
203
204 LOG_SET_FLG_ENTER(flgid, setptn);
205 CHECK_TSKCTX_UNL();
206 CHECK_FLGID(flgid);
207 p_flgcb = get_flgcb(flgid);
208
209 t_lock_cpu();
210 p_flgcb->flgptn |= setptn;
211 p_queue = p_flgcb->wait_queue.p_next;
212 while (p_queue != &(p_flgcb->wait_queue)) {
213 p_tcb = (TCB *) p_queue;
214 p_queue = p_queue->p_next;
215 p_winfo_flg = (WINFO_FLG *)(p_tcb->p_winfo);
216 if (check_flg_cond(p_flgcb, p_winfo_flg->waiptn,
217 p_winfo_flg->wfmode, &(p_winfo_flg->flgptn))) {
218 queue_delete(&(p_tcb->task_queue));
219 if (wait_complete(p_tcb)) {
220 dspreq = true;
221 }
222 if ((p_flgcb->p_flginib->flgatr & TA_CLR) != 0U) {
223 break;
224 }
225 }
226 }
227 if (dspreq) {
228 dispatch();
229 }
230 ercd = E_OK;
231 t_unlock_cpu();
232
233 error_exit:
234 LOG_SET_FLG_LEAVE(ercd);
235 return(ercd);
236}
237
238#endif /* TOPPERS_set_flg */
239
240/*
241 * イベントフラグのセット(非タスクコンテキスト用)
242 */
243#ifdef TOPPERS_iset_flg
244
245ER
246iset_flg(ID flgid, FLGPTN setptn)
247{
248 FLGCB *p_flgcb;
249 QUEUE *p_queue;
250 TCB *p_tcb;
251 WINFO_FLG *p_winfo_flg;
252 ER ercd;
253
254 LOG_ISET_FLG_ENTER(flgid, setptn);
255 CHECK_INTCTX_UNL();
256 CHECK_FLGID(flgid);
257 p_flgcb = get_flgcb(flgid);
258
259 i_lock_cpu();
260 p_flgcb->flgptn |= setptn;
261 p_queue = p_flgcb->wait_queue.p_next;
262 while (p_queue != &(p_flgcb->wait_queue)) {
263 p_tcb = (TCB *) p_queue;
264 p_queue = p_queue->p_next;
265 p_winfo_flg = (WINFO_FLG *)(p_tcb->p_winfo);
266 if (check_flg_cond(p_flgcb, p_winfo_flg->waiptn,
267 p_winfo_flg->wfmode, &(p_winfo_flg->flgptn))) {
268 queue_delete(&(p_tcb->task_queue));
269 if (wait_complete(p_tcb)) {
270 reqflg = true;
271 }
272 if ((p_flgcb->p_flginib->flgatr & TA_CLR) != 0U) {
273 break;
274 }
275 }
276 }
277 ercd = E_OK;
278 i_unlock_cpu();
279
280 error_exit:
281 LOG_ISET_FLG_LEAVE(ercd);
282 return(ercd);
283}
284
285#endif /* TOPPERS_iset_flg */
286
287/*
288 * イベントフラグのクリア
289 */
290#ifdef TOPPERS_clr_flg
291
292ER
293clr_flg(ID flgid, FLGPTN clrptn)
294{
295 FLGCB *p_flgcb;
296 ER ercd;
297
298 LOG_CLR_FLG_ENTER(flgid, clrptn);
299 CHECK_TSKCTX_UNL();
300 CHECK_FLGID(flgid);
301 p_flgcb = get_flgcb(flgid);
302
303 t_lock_cpu();
304 p_flgcb->flgptn &= clrptn;
305 ercd = E_OK;
306 t_unlock_cpu();
307
308 error_exit:
309 LOG_CLR_FLG_LEAVE(ercd);
310 return(ercd);
311}
312
313#endif /* TOPPERS_clr_flg */
314
315/*
316 * イベントフラグ待
317ち
318 */
319#ifdef TOPPERS_wai_flg
320
321ER
322wai_flg(ID flgid, FLGPTN waiptn, MODE wfmode, FLGPTN *p_flgptn)
323{
324 FLGCB *p_flgcb;
325 WINFO_FLG winfo_flg;
326 ER ercd;
327
328 LOG_WAI_FLG_ENTER(flgid, waiptn, wfmode, p_flgptn);
329 CHECK_DISPATCH();
330 CHECK_FLGID(flgid);
331 CHECK_PAR(waiptn != 0U);
332 CHECK_PAR(wfmode == TWF_ORW || wfmode == TWF_ANDW);
333 p_flgcb = get_flgcb(flgid);
334
335 t_lock_cpu();
336 if ((p_flgcb->p_flginib->flgatr & TA_WMUL) == 0U
337 && !queue_empty(&(p_flgcb->wait_queue))) {
338 ercd = E_ILUSE;
339 }
340 else if (check_flg_cond(p_flgcb, waiptn, wfmode, p_flgptn)) {
341 ercd = E_OK;
342 }
343 else {
344 winfo_flg.waiptn = waiptn;
345 winfo_flg.wfmode = wfmode;
346 p_runtsk->tstat = (TS_WAITING | TS_WAIT_FLG);
347 wobj_make_wait((WOBJCB *) p_flgcb, (WINFO_WOBJ *) &winfo_flg);
348 dispatch();
349 ercd = winfo_flg.winfo.wercd;
350 if (ercd == E_OK) {
351 *p_flgptn = winfo_flg.flgptn;
352 }
353 }
354 t_unlock_cpu();
355
356 error_exit:
357 LOG_WAI_FLG_LEAVE(ercd, *p_flgptn);
358 return(ercd);
359}
360
361#endif /* TOPPERS_wai_flg */
362
363/*
364 * イベントフラグ待
365ち(ポーリング)
366 */
367#ifdef TOPPERS_pol_flg
368
369ER
370pol_flg(ID flgid, FLGPTN waiptn, MODE wfmode, FLGPTN *p_flgptn)
371{
372 FLGCB *p_flgcb;
373 ER ercd;
374
375 LOG_POL_FLG_ENTER(flgid, waiptn, wfmode, p_flgptn);
376 CHECK_TSKCTX_UNL();
377 CHECK_FLGID(flgid);
378 CHECK_PAR(waiptn != 0U);
379 CHECK_PAR(wfmode == TWF_ORW || wfmode == TWF_ANDW);
380 p_flgcb = get_flgcb(flgid);
381
382 t_lock_cpu();
383 if ((p_flgcb->p_flginib->flgatr & TA_WMUL) == 0U
384 && !queue_empty(&(p_flgcb->wait_queue))) {
385 ercd = E_ILUSE;
386 }
387 else if (check_flg_cond(p_flgcb, waiptn, wfmode, p_flgptn)) {
388 ercd = E_OK;
389 }
390 else {
391 ercd = E_TMOUT;
392 }
393 t_unlock_cpu();
394
395 error_exit:
396 LOG_POL_FLG_LEAVE(ercd, *p_flgptn);
397 return(ercd);
398}
399
400#endif /* TOPPERS_pol_flg */
401
402/*
403 * イベントフラグ待
404ち(タイムアウトあり)
405 */
406#ifdef TOPPERS_twai_flg
407
408ER
409twai_flg(ID flgid, FLGPTN waiptn, MODE wfmode, FLGPTN *p_flgptn, TMO tmout)
410{
411 FLGCB *p_flgcb;
412 WINFO_FLG winfo_flg;
413 TMEVTB tmevtb;
414 ER ercd;
415
416 LOG_TWAI_FLG_ENTER(flgid, waiptn, wfmode, p_flgptn, tmout);
417 CHECK_DISPATCH();
418 CHECK_FLGID(flgid);
419 CHECK_PAR(waiptn != 0U);
420 CHECK_PAR(wfmode == TWF_ORW || wfmode == TWF_ANDW);
421 CHECK_TMOUT(tmout);
422 p_flgcb = get_flgcb(flgid);
423
424 t_lock_cpu();
425 if ((p_flgcb->p_flginib->flgatr & TA_WMUL) == 0U
426 && !queue_empty(&(p_flgcb->wait_queue))) {
427 ercd = E_ILUSE;
428 }
429 else if (check_flg_cond(p_flgcb, waiptn, wfmode, p_flgptn)) {
430 ercd = E_OK;
431 }
432 else if (tmout == TMO_POL) {
433 ercd = E_TMOUT;
434 }
435 else {
436 winfo_flg.waiptn = waiptn;
437 winfo_flg.wfmode = wfmode;
438 p_runtsk->tstat = (TS_WAITING | TS_WAIT_FLG);
439 wobj_make_wait_tmout((WOBJCB *) p_flgcb, (WINFO_WOBJ *) &winfo_flg,
440 &tmevtb, tmout);
441 dispatch();
442 ercd = winfo_flg.winfo.wercd;
443 if (ercd == E_OK) {
444 *p_flgptn = winfo_flg.flgptn;
445 }
446 }
447 t_unlock_cpu();
448
449 error_exit:
450 LOG_TWAI_FLG_LEAVE(ercd, *p_flgptn);
451 return(ercd);
452}
453
454#endif /* TOPPERS_twai_flg */
455
456/*
457 * イベントフラグの再初期化
458 */
459#ifdef TOPPERS_ini_flg
460
461ER
462ini_flg(ID flgid)
463{
464 FLGCB *p_flgcb;
465 bool_t dspreq;
466 ER ercd;
467
468 LOG_INI_FLG_ENTER(flgid);
469 CHECK_TSKCTX_UNL();
470 CHECK_FLGID(flgid);
471 p_flgcb = get_flgcb(flgid);
472
473 t_lock_cpu();
474 dspreq = init_wait_queue(&(p_flgcb->wait_queue));
475 p_flgcb->flgptn = p_flgcb->p_flginib->iflgptn;
476 if (dspreq) {
477 dispatch();
478 }
479 ercd = E_OK;
480 t_unlock_cpu();
481
482 error_exit:
483 LOG_INI_FLG_LEAVE(ercd);
484 return(ercd);
485}
486
487#endif /* TOPPERS_ini_flg */
488
489/*
490 * イベントフラグの状æ…
491‹å‚ç…
492§
493 */
494#ifdef TOPPERS_ref_flg
495
496ER
497ref_flg(ID flgid, T_RFLG *pk_rflg)
498{
499 FLGCB *p_flgcb;
500 ER ercd;
501
502 LOG_REF_FLG_ENTER(flgid, pk_rflg);
503 CHECK_TSKCTX_UNL();
504 CHECK_FLGID(flgid);
505 p_flgcb = get_flgcb(flgid);
506
507 t_lock_cpu();
508 pk_rflg->wtskid = wait_tskid(&(p_flgcb->wait_queue));
509 pk_rflg->flgptn = p_flgcb->flgptn;
510 ercd = E_OK;
511 t_unlock_cpu();
512
513 error_exit:
514 LOG_REF_FLG_LEAVE(ercd, pk_rflg);
515 return(ercd);
516}
517
518#endif /* TOPPERS_ref_flg */
Note: See TracBrowser for help on using the repository browser.