⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 eventflag.c

📁 uT Kernel os source code for AT91
💻 C
字号:
/* *---------------------------------------------------------------------- *    micro T-Kernel * *    Copyright (C) 2006-2007 by Ken Sakamura. All rights reserved. *    micro T-Kernel is distributed under the micro T-License. *---------------------------------------------------------------------- * *    Version:   1.00.00 *    Released by T-Engine Forum(http://www.t-engine.org) at 2007/03/26. * *---------------------------------------------------------------------- *//* *	eventflag.c *	Event Flag *//** [BEGIN Common Definitions] */#include "kernel.h"#include "task.h"#include "wait.h"#include "check.h"#include "eventflag.h"/** [END Common Definitions] */#if CFN_MAX_FLGID > 0#ifdef USE_FUNC_FLGCB_TABLENoinit(EXPORT FLGCB	knl_flgcb_table[NUM_FLGID]);	/* Event flag control block */Noinit(EXPORT QUEUE	knl_free_flgcb);	/* FreeQue */#endif /* USE_FUNC_FLGCB_TABLE */#ifdef USE_FUNC_EVENTFLAG_INITIALIZE/* * Initialization of event flag control block  */EXPORT ER knl_eventflag_initialize( void ){	FLGCB	*flgcb, *end;	/* Get system information */	if ( NUM_FLGID < 1 ) {		return E_SYS;	}	/* Register all control blocks onto FreeQue */	QueInit(&knl_free_flgcb);	end = knl_flgcb_table + NUM_FLGID;	for ( flgcb = knl_flgcb_table; flgcb < end; flgcb++ ) {		flgcb->flgid = 0;		QueInsert(&flgcb->wait_queue, &knl_free_flgcb);	}	return E_OK;}#endif /* USE_FUNC_EVENTFLAG_INITIALIZE */#ifdef USE_FUNC_TK_CRE_FLG/* * Create event flag */SYSCALL ID tk_cre_flg_impl( T_CFLG *pk_cflg ){	const ATR VALID_FLGATR = {		 TA_TPRI		|TA_WMUL#if USE_OBJECT_NAME		|TA_DSNAME#endif	};	FLGCB	*flgcb;	ID	flgid;	ER	ercd;	CHECK_RSATR(pk_cflg->flgatr, VALID_FLGATR);	BEGIN_CRITICAL_SECTION;	/* Get control block from FreeQue */	flgcb = (FLGCB*)QueRemoveNext(&knl_free_flgcb);	if ( flgcb == NULL ) {		ercd = E_LIMIT;	} else {		flgid = ID_FLG(flgcb - knl_flgcb_table);		/* Initialize control block */		QueInit(&flgcb->wait_queue);		flgcb->flgid = flgid;		flgcb->exinf = pk_cflg->exinf;		flgcb->flgatr = pk_cflg->flgatr;		flgcb->flgptn = pk_cflg->iflgptn;#if USE_OBJECT_NAME		if ( (pk_cflg->flgatr & TA_DSNAME) != 0 ) {			strncpy((char*)flgcb->name, (char*)pk_cflg->dsname,				OBJECT_NAME_LENGTH);		}#endif		ercd = flgid;	}	END_CRITICAL_SECTION;	return ercd;}#endif /* USE_FUNC_TK_CRE_FLG */#ifdef USE_FUNC_TK_DEL_FLG/* * Delete event flag */SYSCALL ER tk_del_flg_impl( ID flgid ){	FLGCB	*flgcb;	ER	ercd = E_OK;	CHECK_FLGID(flgid);	flgcb = get_flgcb(flgid);	BEGIN_CRITICAL_SECTION;	if ( flgcb->flgid == 0 ) {		ercd = E_NOEXS;	} else {		/* Release wait state of task (E_DLT) */		knl_wait_delete(&flgcb->wait_queue);		/* Return to FreeQue */		QueInsert(&flgcb->wait_queue, &knl_free_flgcb);		flgcb->flgid = 0;	}	END_CRITICAL_SECTION;	return ercd;}#endif /* USE_FUNC_TK_DEL_FLG */#ifdef USE_FUNC_TK_SET_FLG/* * Event flag set */SYSCALL ER tk_set_flg_impl( ID flgid, UINT setptn ){	FLGCB	*flgcb;	TCB	*tcb;	QUEUE	*queue;	UINT	wfmode, waiptn;	ER	ercd = E_OK;	CHECK_FLGID(flgid);	flgcb = get_flgcb(flgid);	BEGIN_CRITICAL_SECTION;	if ( flgcb->flgid == 0 ) {		ercd = E_NOEXS;		goto error_exit;	}	/* Set event flag */	flgcb->flgptn |= setptn;	/* Search task which should be released */	queue = flgcb->wait_queue.next;	while ( queue != &flgcb->wait_queue ) {		tcb = (TCB*)queue;		queue = queue->next;		/* Meet condition for release wait? */		waiptn = tcb->winfo.flg.waiptn;		wfmode = tcb->winfo.flg.wfmode;		if ( knl_eventflag_cond(flgcb, waiptn, wfmode) ) {			/* Release wait */			*tcb->winfo.flg.p_flgptn = flgcb->flgptn;			knl_wait_release_ok(tcb);			/* Clear event flag */			if ( (wfmode & TWF_BITCLR) != 0 ) {				if ( (flgcb->flgptn &= ~waiptn) == 0 ) {					break;				}			}			if ( (wfmode & TWF_CLR) != 0 ) {				flgcb->flgptn = 0;				break;			}		}	}    error_exit:	END_CRITICAL_SECTION;	return ercd;}#endif /* USE_FUNC_TK_SET_FLG */#ifdef USE_FUNC_TK_CLR_FLG/* * Clear event flag  */SYSCALL ER tk_clr_flg_impl( ID flgid, UINT clrptn ){	FLGCB	*flgcb;	ER	ercd = E_OK;	CHECK_FLGID(flgid);	flgcb = get_flgcb(flgid);	BEGIN_CRITICAL_SECTION;	if ( flgcb->flgid == 0 ) {		ercd = E_NOEXS;	} else {		flgcb->flgptn &= clrptn;	}	END_CRITICAL_SECTION;	return ercd;}#endif /* USE_FUNC_TK_CLR_FLG */#ifdef USE_FUNC_TK_WAI_FLG/* * Processing if the priority of wait task changes */LOCAL void flg_chg_pri( TCB *tcb, INT oldpri ){	FLGCB	*flgcb;	flgcb = get_flgcb(tcb->wid);	knl_gcb_change_priority((GCB*)flgcb, tcb);}/* * Definition of event flag wait specification */LOCAL WSPEC knl_wspec_flg_tfifo = { TTW_FLG, NULL, NULL };LOCAL WSPEC knl_wspec_flg_tpri  = { TTW_FLG, flg_chg_pri, NULL };/* * Event flag wait */SYSCALL ER tk_wai_flg_impl( ID flgid, UINT waiptn, UINT wfmode, UINT *p_flgptn, TMO tmout ){	FLGCB	*flgcb;	ER	ercd = E_OK;	CHECK_FLGID(flgid);	CHECK_PAR(waiptn != 0);	CHECK_PAR((wfmode & ~(TWF_ORW|TWF_CLR|TWF_BITCLR)) == 0);	CHECK_TMOUT(tmout);	CHECK_DISPATCH();	flgcb = get_flgcb(flgid);	BEGIN_CRITICAL_SECTION;	if ( flgcb->flgid == 0 ) {		ercd = E_NOEXS;		goto error_exit;	}	if ( (flgcb->flgatr & TA_WMUL) == 0 && !isQueEmpty(&flgcb->wait_queue) ) {		/* Disable multiple tasks wait */		ercd = E_OBJ;		goto error_exit;	}	/* Meet condition for release wait? */	if ( knl_eventflag_cond(flgcb, waiptn, wfmode) ) {		*p_flgptn = flgcb->flgptn;		/* Clear event flag */		if ( (wfmode & TWF_BITCLR) != 0 ) {			flgcb->flgptn &= ~waiptn;		}		if ( (wfmode & TWF_CLR) != 0 ) {			flgcb->flgptn = 0;		}	} else {		/* Ready for wait */		knl_ctxtsk->wspec = ( (flgcb->flgatr & TA_TPRI) != 0 )?					&knl_wspec_flg_tpri: &knl_wspec_flg_tfifo;		knl_ctxtsk->wercd = &ercd;		knl_ctxtsk->winfo.flg.waiptn = waiptn;		knl_ctxtsk->winfo.flg.wfmode = wfmode;		knl_ctxtsk->winfo.flg.p_flgptn = p_flgptn;		knl_gcb_make_wait((GCB*)flgcb, tmout);	}    error_exit:	END_CRITICAL_SECTION;	return ercd;}#endif /* USE_FUNC_TK_WAI_FLG */#ifdef USE_FUNC_TK_REF_FLG/* * Check event flag state */SYSCALL ER tk_ref_flg_impl( ID flgid, T_RFLG *pk_rflg ){	FLGCB	*flgcb;	ER	ercd = E_OK;	CHECK_FLGID(flgid);	flgcb = get_flgcb(flgid);	BEGIN_CRITICAL_SECTION;	if ( flgcb->flgid == 0 ) {		ercd = E_NOEXS;	} else {		pk_rflg->exinf = flgcb->exinf;		pk_rflg->wtsk = knl_wait_tskid(&flgcb->wait_queue);		pk_rflg->flgptn = flgcb->flgptn;	}	END_CRITICAL_SECTION;	return ercd;}#endif /* USE_FUNC_TK_REF_FLG *//* ------------------------------------------------------------------------ *//* *	Debugger support function */#if USE_DBGSPT#ifdef USE_FUNC_EVENTFLAG_GETNAME#if USE_OBJECT_NAME/* * Get object name from control block */EXPORT ER knl_eventflag_getname(ID id, UB **name){	FLGCB	*flgcb;	ER	ercd = E_OK;	CHECK_FLGID(id);	BEGIN_DISABLE_INTERRUPT;	flgcb = get_flgcb(id);	if ( flgcb->flgid == 0 ) {		ercd = E_NOEXS;		goto error_exit;	}	if ( (flgcb->flgatr & TA_DSNAME) == 0 ) {		ercd = E_OBJ;		goto error_exit;	}	*name = flgcb->name;    error_exit:	END_DISABLE_INTERRUPT;	return ercd;}#endif /* USE_OBJECT_NAME */#endif /* USE_FUNC_EVENTFLAG_GETNAME */#ifdef USE_FUNC_TD_LST_FLG/* * Refer event flag usage state */SYSCALL INT td_lst_flg_impl( ID list[], INT nent ){	FLGCB	*flgcb, *end;	INT	n = 0;	BEGIN_DISABLE_INTERRUPT;	end = knl_flgcb_table + NUM_FLGID;	for ( flgcb = knl_flgcb_table; flgcb < end; flgcb++ ) {		if ( flgcb->flgid == 0 ) {			continue;		}		if ( n++ < nent ) {			*list++ = flgcb->flgid;		}	}	END_DISABLE_INTERRUPT;	return n;}#endif /* USE_FUNC_TD_LST_FLG */#ifdef USE_FUNC_TD_REF_FLG/* * Refer event flag state */SYSCALL ER td_ref_flg_impl( ID flgid, TD_RFLG *pk_rflg ){	FLGCB	*flgcb;	ER	ercd = E_OK;	CHECK_FLGID(flgid);	flgcb = get_flgcb(flgid);	BEGIN_DISABLE_INTERRUPT;	if ( flgcb->flgid == 0 ) {		ercd = E_NOEXS;	} else {		pk_rflg->exinf = flgcb->exinf;		pk_rflg->wtsk = knl_wait_tskid(&flgcb->wait_queue);		pk_rflg->flgptn = flgcb->flgptn;	}	END_DISABLE_INTERRUPT;	return ercd;}#endif /* USE_FUNC_TD_REF_FLG */#ifdef USE_FUNC_TD_FLG_QUE/* * Refer event flag wait queue */SYSCALL INT td_flg_que_impl( ID flgid, ID list[], INT nent ){	FLGCB	*flgcb;	QUEUE	*q;	ER	ercd = E_OK;	CHECK_FLGID(flgid);	flgcb = get_flgcb(flgid);	BEGIN_DISABLE_INTERRUPT;	if ( flgcb->flgid == 0 ) {		ercd = E_NOEXS;	} else {		INT n = 0;		for ( q = flgcb->wait_queue.next; q != &flgcb->wait_queue; q = q->next ) {			if ( n++ < nent ) {				*list++ = ((TCB*)q)->tskid;			}		}		ercd = n;	}	END_DISABLE_INTERRUPT;	return ercd;}#endif /* USE_FUNC_TD_FLG_QUE */#endif /* USE_DBGSPT */#endif /* CFN_MAX_FLGID */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -