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

📄 mailbox.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. * *---------------------------------------------------------------------- *//* *	mailbox.c *	Mailbox *//** [BEGIN Common Definitions] */#include "kernel.h"#include "task.h"#include "wait.h"#include "check.h"#include "mailbox.h"/** [END Common Definitions] */#if CFN_MAX_MBXID > 0#ifdef USE_FUNC_MBXCB_TABLENoinit(EXPORT MBXCB	knl_mbxcb_table[NUM_MBXID]);	/* Mailbox control block */Noinit(EXPORT QUEUE	knl_free_mbxcb);	/* FreeQue */#endif /* USE_FUNC_MBXCB_TABLE */#ifdef USE_FUNC_MAILBOX_INITIALIZE/* * Initialization of mailbox control block  */EXPORT ER knl_mailbox_initialize( void ){	MBXCB	*mbxcb, *end;	/* Get system information */	if ( NUM_MBXID < 1 ) {		return E_SYS;	}	/* Register all control blocks onto FreeQue */	QueInit(&knl_free_mbxcb);	end = knl_mbxcb_table + NUM_MBXID;	for ( mbxcb = knl_mbxcb_table; mbxcb < end; mbxcb++ ) {		mbxcb->mbxid = 0;		QueInsert(&mbxcb->wait_queue, &knl_free_mbxcb);	}	return E_OK;}#endif /* USE_FUNC_MAILBOX_INITIALIZE */#ifdef USE_FUNC_TK_CRE_MBX/* * Create mailbox */SYSCALL ID tk_cre_mbx_impl( T_CMBX *pk_cmbx ){	const ATR VALID_MBXATR = {		 TA_MPRI		|TA_TPRI#if USE_OBJECT_NAME		|TA_DSNAME#endif	};	MBXCB	*mbxcb;	ID	mbxid;	ER	ercd;	CHECK_RSATR(pk_cmbx->mbxatr, VALID_MBXATR);	BEGIN_CRITICAL_SECTION;	/* Get control block from FreeQue */	mbxcb = (MBXCB*)QueRemoveNext(&knl_free_mbxcb);	if ( mbxcb == NULL ) {		ercd = E_LIMIT;	} else {		mbxid = ID_MBX(mbxcb - knl_mbxcb_table);		/* Initialize control block */		QueInit(&mbxcb->wait_queue);		mbxcb->mbxid  = mbxid;		mbxcb->exinf  = pk_cmbx->exinf;		mbxcb->mbxatr = pk_cmbx->mbxatr;		mbxcb->mq_head.msgque[0] = NULL;#if USE_OBJECT_NAME		if ( (pk_cmbx->mbxatr & TA_DSNAME) != 0 ) {			strncpy((char*)mbxcb->name, (char*)pk_cmbx->dsname,				OBJECT_NAME_LENGTH);		}#endif		ercd = mbxid;	}	END_CRITICAL_SECTION;	return ercd;}#endif /* USE_FUNC_TK_CRE_MBX */#ifdef USE_FUNC_TK_DEL_MBX/* * Delete mailbox */SYSCALL ER tk_del_mbx_impl( ID mbxid ){	MBXCB	*mbxcb;	ER	ercd = E_OK;	CHECK_MBXID(mbxid);	mbxcb = get_mbxcb(mbxid);	BEGIN_CRITICAL_SECTION;	if ( mbxcb->mbxid == 0 ) {		ercd = E_NOEXS;	} else {		/* Release wait state of task (E_DLT) */		knl_wait_delete(&mbxcb->wait_queue);		/* Return to FreeQue */		QueInsert(&mbxcb->wait_queue, &knl_free_mbxcb);		mbxcb->mbxid = 0;	}	END_CRITICAL_SECTION;	return ercd;}#endif /* USE_FUNC_TK_DEL_MBX */#ifdef USE_FUNC_TK_SND_MBX/* * Send to mailbox */SYSCALL ER tk_snd_mbx_impl( ID mbxid, T_MSG *pk_msg ){	MBXCB	*mbxcb;	TCB	*tcb;	ER	ercd = E_OK;	CHECK_MBXID(mbxid);	mbxcb = get_mbxcb(mbxid);	BEGIN_CRITICAL_SECTION;	if (mbxcb->mbxid == 0) {		ercd = E_NOEXS;		goto error_exit;	}	if ( (mbxcb->mbxatr & TA_MPRI) != 0 ) {		if ( ((T_MSG_PRI*)pk_msg)->msgpri <= 0 ) {			ercd = E_PAR;			goto error_exit;		}	}	if ( !isQueEmpty(&mbxcb->wait_queue) ) {		/* Directly send to receive wait task */		tcb = (TCB*)(mbxcb->wait_queue.next);		*tcb->winfo.mbx.ppk_msg = pk_msg;		knl_wait_release_ok(tcb);	} else {		/* Connect message to queue */		if ( (mbxcb->mbxatr & TA_MPRI) != 0 ) {			/* Connect message to queue following priority */			knl_queue_insert_mpri((T_MSG_PRI*)pk_msg, &mbxcb->mq_head);		} else {			/* Connect to end of queue */			nextmsg(pk_msg) = NULL;			if ( headmsg(mbxcb) == NULL ) {				headmsg(mbxcb) = pk_msg;			} else {				nextmsg(mbxcb->mq_tail) = pk_msg;			}			mbxcb->mq_tail = pk_msg;		}	}    error_exit:	END_CRITICAL_SECTION;	return ercd;}#endif /* USE_FUNC_TK_SND_MBX */#ifdef USE_FUNC_TK_RCV_MBX/* * Processing if the priority of wait task changes */LOCAL void mbx_chg_pri( TCB *tcb, INT oldpri ){	MBXCB	*mbxcb;	mbxcb = get_mbxcb(tcb->wid);	knl_gcb_change_priority((GCB*)mbxcb, tcb);}/* * Definition of mailbox wait specification */LOCAL WSPEC knl_wspec_mbx_tfifo = { TTW_MBX, NULL, NULL };LOCAL WSPEC knl_wspec_mbx_tpri  = { TTW_MBX, mbx_chg_pri, NULL };/* * Receive from mailbox */SYSCALL ER tk_rcv_mbx_impl( ID mbxid, T_MSG **ppk_msg, TMO tmout ){	MBXCB	*mbxcb;	ER	ercd = E_OK;	CHECK_MBXID(mbxid);	CHECK_TMOUT(tmout);	CHECK_DISPATCH();	mbxcb = get_mbxcb(mbxid);	BEGIN_CRITICAL_SECTION;	if ( mbxcb->mbxid == 0 ) {		ercd = E_NOEXS;		goto error_exit;	}	if ( headmsg(mbxcb) != NULL ) {		/* Get message from head of queue */		*ppk_msg = headmsg(mbxcb);		headmsg(mbxcb) = nextmsg(*ppk_msg);	} else {		/* Ready for receive wait */		knl_ctxtsk->wspec = ( (mbxcb->mbxatr & TA_TPRI) != 0 )?					&knl_wspec_mbx_tpri: &knl_wspec_mbx_tfifo;		knl_ctxtsk->wercd = &ercd;		knl_ctxtsk->winfo.mbx.ppk_msg = ppk_msg;		knl_gcb_make_wait((GCB*)mbxcb, tmout);	}    error_exit:	END_CRITICAL_SECTION;	return ercd;}#endif /* USE_FUNC_TK_RCV_MBX */#ifdef USE_FUNC_TK_REF_MBX/* * Refer mailbox state  */SYSCALL ER tk_ref_mbx_impl( ID mbxid, T_RMBX *pk_rmbx ){	MBXCB	*mbxcb;	ER	ercd = E_OK;	CHECK_MBXID(mbxid);	mbxcb = get_mbxcb(mbxid);	BEGIN_CRITICAL_SECTION;	if ( mbxcb->mbxid == 0 ) {		ercd = E_NOEXS;	} else {		pk_rmbx->exinf = mbxcb->exinf;		pk_rmbx->wtsk = knl_wait_tskid(&mbxcb->wait_queue);		pk_rmbx->pk_msg = headmsg(mbxcb);	}	END_CRITICAL_SECTION;	return ercd;}#endif /* USE_FUNC_TK_REF_MBX *//* ------------------------------------------------------------------------ *//* *	Debugger support function */#if USE_DBGSPT#ifdef USE_FUNC_MAILBOX_GETNAME#if USE_OBJECT_NAME/* * Get object name from control block */EXPORT ER knl_mailbox_getname(ID id, UB **name){	MBXCB	*mbxcb;	ER	ercd = E_OK;	CHECK_MBXID(id);	BEGIN_DISABLE_INTERRUPT;	mbxcb = get_mbxcb(id);	if ( mbxcb->mbxid == 0 ) {		ercd = E_NOEXS;		goto error_exit;	}	if ( (mbxcb->mbxatr & TA_DSNAME) == 0 ) {		ercd = E_OBJ;		goto error_exit;	}	*name = mbxcb->name;    error_exit:	END_DISABLE_INTERRUPT;	return ercd;}#endif /* USE_OBJECT_NAME */#endif /* USE_FUNC_MAILBOX_GETNAME */#ifdef USE_FUNC_TD_LST_MBX/* * Refer mailbox usage state */SYSCALL INT td_lst_mbx_impl( ID list[], INT nent ){	MBXCB	*mbxcb, *end;	INT	n = 0;	BEGIN_DISABLE_INTERRUPT;	end = knl_mbxcb_table + NUM_MBXID;	for ( mbxcb = knl_mbxcb_table; mbxcb < end; mbxcb++ ) {		if ( mbxcb->mbxid == 0 ) {			continue;		}		if ( n++ < nent ) {			*list++ = mbxcb->mbxid;		}	}	END_DISABLE_INTERRUPT;	return n;}#endif /* USE_FUNC_TD_LST_MBX */#ifdef USE_FUNC_TD_REF_MBX/* * Refer mailbox state */SYSCALL ER td_ref_mbx_impl( ID mbxid, TD_RMBX *pk_rmbx ){	MBXCB	*mbxcb;	ER	ercd = E_OK;	CHECK_MBXID(mbxid);	mbxcb = get_mbxcb(mbxid);	BEGIN_DISABLE_INTERRUPT;	if ( mbxcb->mbxid == 0 ) {		ercd = E_NOEXS;	} else {		pk_rmbx->exinf = mbxcb->exinf;		pk_rmbx->wtsk = knl_wait_tskid(&mbxcb->wait_queue);		if ( headmsg(mbxcb) != NULL ) {			pk_rmbx->pk_msg = headmsg(mbxcb);		} else {			pk_rmbx->pk_msg = NULL; /* No message */		}	}	END_DISABLE_INTERRUPT;	return ercd;}#endif /* USE_FUNC_TD_REF_MBX */#ifdef USE_FUNC_TD_MBX_QUE/* * Refer mailbox wait queue */SYSCALL INT td_mbx_que_impl( ID mbxid, ID list[], INT nent ){	MBXCB	*mbxcb;	QUEUE	*q;	ER	ercd = E_OK;	CHECK_MBXID(mbxid);	mbxcb = get_mbxcb(mbxid);	BEGIN_DISABLE_INTERRUPT;	if ( mbxcb->mbxid == 0 ) {		ercd = E_NOEXS;	} else {		INT n = 0;		for ( q = mbxcb->wait_queue.next; q != &mbxcb->wait_queue; q = q->next ) {			if ( n++ < nent ) {				*list++ = ((TCB*)q)->tskid;			}		}		ercd = n;	}	END_DISABLE_INTERRUPT;	return ercd;}#endif /* USE_FUNC_TD_MBX_QUE */#endif /* USE_DBGSPT */#endif /* CFN_MAX_MBXID */

⌨️ 快捷键说明

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