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

📄 time_calls.c

📁 tkernel操作系统的源代码,是一位日本教授领导开发的,占有很大市场
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *---------------------------------------------------------------------- *    T-Kernel * *    Copyright (C) 2004 by Ken Sakamura. All rights reserved. *    T-Kernel is distributed under the T-License. *---------------------------------------------------------------------- * *    Version:   1.01.00 *    Released by T-Engine Forum(http://www.t-engine.org) at 2004/6/28. * *---------------------------------------------------------------------- *//* *	time_calls.c (T-Kernel/OS) *	Time Management Function */#include "kernel.h"#include "timer.h"#include "task.h"#include "wait.h"#include "check.h"#include "tkdev_timer.h"/* * Set system clock */SYSCALL ER _tk_set_tim( SYSTIM *pk_tim ){	CHECK_PAR(pk_tim->hi >= 0);	BEGIN_CRITICAL_SECTION;	real_time_ofs = ll_sub(toLSYSTIM(pk_tim), current_time);	END_CRITICAL_SECTION;	return E_OK;}/* * Refer system clock */SYSCALL ER _tk_get_tim( SYSTIM *pk_tim ){	BEGIN_CRITICAL_SECTION;	*pk_tim = toSYSTIM(real_time());	END_CRITICAL_SECTION;	return E_OK;}/* * Refer system operating time */SYSCALL ER _tk_get_otm( SYSTIM *pk_tim ){	BEGIN_CRITICAL_SECTION;	*pk_tim = toSYSTIM(current_time);	END_CRITICAL_SECTION;	return E_OK;}#if USE_DBGSPT/* * Refer system clock */SYSCALL ER _td_get_tim( SYSTIM *tim, UINT *ofs ){	BEGIN_DISABLE_INTERRUPT;	*ofs = get_hw_timer_nsec();	*tim = toSYSTIM(real_time());	END_DISABLE_INTERRUPT;	return E_OK;}/* * Refer system operating time */SYSCALL ER _td_get_otm( SYSTIM *tim, UINT *ofs ){	BEGIN_DISABLE_INTERRUPT;	*ofs = get_hw_timer_nsec();	*tim = toSYSTIM(current_time);	END_DISABLE_INTERRUPT;	return E_OK;}#endif /* USE_DBGSPT *//* ------------------------------------------------------------------------ *//* * Definition of task delay wait specification */LOCAL WSPEC wspec_dly = { TTW_DLY, NULL, NULL };/* * Task delay */SYSCALL ER _tk_dly_tsk( RELTIM dlytim ){	ER	ercd = E_OK;	CHECK_PAR((TMO)dlytim >= 0);	CHECK_DISPATCH();	if ( dlytim > 0 ) {		BEGIN_CRITICAL_SECTION;		/* Check wait disable */		if ( (ctxtsk->waitmask & TTW_DLY) != 0 ) {			ercd = E_DISWAI;		} else {			ctxtsk->wspec = &wspec_dly;			ctxtsk->wid = 0;			ctxtsk->wercd = &ercd;			make_wait(dlytim, TA_NULL);			QueInit(&ctxtsk->tskque);		}		END_CRITICAL_SECTION;	}	return ercd;}/* ------------------------------------------------------------------------ *//* *	Cyclic handler */#ifdef NUM_CYCIDEXPORT ID	max_cycid;	/* Maximum interval start ID *//* * Cyclic handler control block */typedef struct cyclic_handler_control_block {	VP	exinf;		/* Extended information */	ATR	cycatr;		/* Cyclic handler attribute */	FP	cychdr;		/* Cyclic handler address */	UINT	cycstat;	/* Cyclic handler state */	RELTIM	cyctim;		/* Cyclic time */	TMEB	cyctmeb;	/* Timer event block */#if TA_GP	VP	gp;		/* Global pointer */#endif#if USE_OBJECT_NAME	UB	name[OBJECT_NAME_LENGTH];	/* name */#endif} CYCCB;LOCAL CYCCB	*cyccb_table;	/* Cyclic handler control block */LOCAL QUEUE	free_cyccb;	/* FreeQue */#define get_cyccb(id)	( &cyccb_table[INDEX_CYC(id)] )/* * Initialization of cyclic handler control block */EXPORT ER cyclichandler_initialize( void ){	CYCCB	*cyccb, *end;	W	n;	/* Get system information */	n = _tk_get_cfn("TMaxCycId", &max_cycid, 1);	if ( n < 1 || NUM_CYCID < 1 ) return E_SYS;	/* Create cyclic handler control block */	cyccb_table = Imalloc(NUM_CYCID * sizeof(CYCCB));	if ( cyccb_table == NULL ) return E_NOMEM;	/* Register all control blocks onto FeeQue*/	QueInit(&free_cyccb);	end = cyccb_table + NUM_CYCID;	for ( cyccb = cyccb_table; cyccb < end; cyccb++ ) {		cyccb->cychdr = NULL; /* Unregistered handler */		QueInsert((QUEUE*)cyccb, &free_cyccb);	}	return E_OK;}/* * Next startup time */Inline LSYSTIM cyc_next_time( CYCCB *cyccb ){	LSYSTIM		tm;	longlong	n;	tm = ll_add(cyccb->cyctmeb.time, ltoll(cyccb->cyctim));	if ( ll_cmp(tm, current_time) <= 0 ) {		/* Adjust time to be later than current time */		tm = ll_sub(current_time, cyccb->cyctmeb.time);		n  = li_div(tm, cyccb->cyctim);		ll_inc(&n);		tm = li_mul(n, cyccb->cyctim);		tm = ll_add(cyccb->cyctmeb.time, tm);	}	return tm;}/* * Register timer event queue */Inline void cyc_timer_insert( CYCCB *cyccb, LSYSTIM tm ){	LOCAL void call_cychdr( CYCCB* );	timer_insert_abs(&cyccb->cyctmeb, tm, (CBACK)call_cychdr, cyccb);}/* * Cyclic handler routine */LOCAL void call_cychdr( CYCCB *cyccb ){	/* Set next startup time */	cyc_timer_insert(cyccb, cyc_next_time(cyccb));	/* Execute cyclic handler / Enable interrupt nest */	ENABLE_INTERRUPT_UPTO(TIMER_INTLEVEL);#if TA_GP	CallUserHandler((INT)cyccb->exinf, 0, 0, cyccb->cychdr, cyccb->gp);#else	(*cyccb->cychdr)(cyccb->exinf);#endif	DISABLE_INTERRUPT;}/* * Immediate call of cyclic handler  */LOCAL void immediate_call_cychdr( CYCCB *cyccb ){	/* Set next startup time */	cyc_timer_insert(cyccb, cyc_next_time(cyccb));	/* Execute cyclic handler in task-independent part	   (Keep interrupt disabled) */	ENTER_TASK_INDEPENDENT;#if TA_GP	CallUserHandler((INT)cyccb->exinf, 0, 0, cyccb->cychdr, cyccb->gp);#else	(*cyccb->cychdr)(cyccb->exinf);#endif	LEAVE_TASK_INDEPENDENT;}/* * Create cyclic handler  */SYSCALL ID _tk_cre_cyc P1( T_CCYC *pk_ccyc ){	const ATR VALID_CYCATR = {		 TA_HLNG		|TA_STA		|TA_PHS		|TA_GP#if USE_OBJECT_NAME		|TA_DSNAME#endif	};	CYCCB	*cyccb;	LSYSTIM	tm;	ER	ercd = E_OK;	CHECK_RSATR(pk_ccyc->cycatr, VALID_CYCATR);	CHECK_PAR(pk_ccyc->cychdr != NULL);	CHECK_PAR(pk_ccyc->cyctim > 0);	BEGIN_CRITICAL_SECTION;	/* Get control block from FreeQue */	cyccb = (CYCCB*)QueRemoveNext(&free_cyccb);	if ( cyccb == NULL ) {		ercd = E_LIMIT;		goto error_exit;	}	/* Initialize control block */	cyccb->exinf   = pk_ccyc->exinf;	cyccb->cycatr  = pk_ccyc->cycatr;	cyccb->cychdr  = pk_ccyc->cychdr;	cyccb->cyctim  = pk_ccyc->cyctim;#if USE_OBJECT_NAME	if ( (pk_ccyc->cycatr & TA_DSNAME) != 0 ) {		strncpy(cyccb->name, pk_ccyc->dsname, OBJECT_NAME_LENGTH);	}#endif#if TA_GP	if ( (pk_ccyc->cycatr & TA_GP) != 0 ) gp = pk_ccyc->gp;	cyccb->gp = gp;#endif	/* First startup time	 *	To guarantee the start of handler after the specified time,	 *	add TIMER_PERIOD. 	 */	tm = ll_add(current_time, ltoll(pk_ccyc->cycphs));	tm = ll_add(tm, ltoll(TIMER_PERIOD));	if ( (pk_ccyc->cycatr & TA_STA) != 0 ) {		/* Start cyclic handler */		cyccb->cycstat = TCYC_STA;		if ( pk_ccyc->cycphs == 0 ) {			/* Immediate execution */			cyccb->cyctmeb.time = tm;			immediate_call_cychdr(cyccb);		} else {			/* Register onto timer event queue */			cyc_timer_insert(cyccb, tm);		}	} else {		/* Initialize only counter */		cyccb->cycstat = TCYC_STP;		cyccb->cyctmeb.time = tm;	}	ercd = ID_CYC(cyccb - cyccb_table);    error_exit:	END_CRITICAL_SECTION;	return ercd;}/* * Delete cyclic handler  */SYSCALL ER _tk_del_cyc( ID cycid ){	CYCCB	*cyccb;	ER	ercd = E_OK;	CHECK_CYCID(cycid);	cyccb = get_cyccb(cycid);	BEGIN_CRITICAL_SECTION;	if ( cyccb->cychdr == NULL ) { /* Unregistered handler */		ercd = E_NOEXS;	} else {		if ( (cyccb->cycstat & TCYC_STA) != 0 ) {			/* Delete timer event queue */			timer_delete(&cyccb->cyctmeb);		}		/* Return to FreeQue */		QueInsert((QUEUE*)cyccb, &free_cyccb);		cyccb->cychdr = NULL; /* Unregistered handler */	}	END_CRITICAL_SECTION;	return ercd;}/* * Start cyclic handler  */SYSCALL ER _tk_sta_cyc( ID cycid ){	CYCCB	*cyccb;	LSYSTIM	tm;	ER	ercd = E_OK;	CHECK_CYCID(cycid);	cyccb = get_cyccb(cycid);	BEGIN_CRITICAL_SECTION;	if ( cyccb->cychdr == NULL ) { /* Unregistered handler */		ercd = E_NOEXS;		goto error_exit;	}	if ( (cyccb->cycatr & TA_PHS) != 0 ) {		/* Continue cyclic phase */		if ( (cyccb->cycstat & TCYC_STA) == 0 ) {			/* Start cyclic handler */			tm = cyccb->cyctmeb.time;			if ( ll_cmp(tm, current_time) <= 0 ) {				tm = cyc_next_time(cyccb);			}			cyc_timer_insert(cyccb, tm);		}	} else {		/* Reset cyclic interval */		if ( (cyccb->cycstat & TCYC_STA) != 0 ) {			/* Stop once */			timer_delete(&cyccb->cyctmeb);		}		/* Start cyclic handler */		cyc_timer_insert(cyccb,			ll_add(current_time, ltoll(cyccb->cyctim)));	}	cyccb->cycstat |= TCYC_STA;    error_exit:	END_CRITICAL_SECTION;	return ercd;}/* * Stop cyclic handler  */SYSCALL ER _tk_stp_cyc( ID cycid ){	CYCCB	*cyccb;	ER	ercd = E_OK;	CHECK_CYCID(cycid);	cyccb = get_cyccb(cycid);	BEGIN_CRITICAL_SECTION;	if ( cyccb->cychdr == NULL ) { /* Unregistered handler */		ercd = E_NOEXS;	} else {		if ( (cyccb->cycstat & TCYC_STA) != 0 ) {			/* Stop cyclic handler */			timer_delete(&cyccb->cyctmeb);		}		cyccb->cycstat &= ~TCYC_STA;	}	END_CRITICAL_SECTION;	return ercd;}/* * Refer cyclic handler state */SYSCALL ER _tk_ref_cyc( ID cycid, T_RCYC* pk_rcyc ){	CYCCB	*cyccb;	LSYSTIM	tm;	ER	ercd = E_OK;	CHECK_CYCID(cycid);	cyccb = get_cyccb(cycid);	BEGIN_CRITICAL_SECTION;	if ( cyccb->cychdr == NULL ) { /* Unregistered handler */		ercd = E_NOEXS;	} else {		tm = cyccb->cyctmeb.time;		if ( (cyccb->cycstat & TCYC_STA) == 0 ) {			if ( ll_cmp(tm, current_time) <= 0 ) {				tm = cyc_next_time(cyccb);			}		}		tm = ll_sub(tm, current_time);		tm = ll_sub(tm, ltoll(TIMER_PERIOD));		if ( ll_sign(tm) < 0 ) tm = ltoll(0);		pk_rcyc->exinf   = cyccb->exinf;		pk_rcyc->lfttim  = tm;		pk_rcyc->cycstat = cyccb->cycstat;	}	END_CRITICAL_SECTION;	return ercd;}

⌨️ 快捷键说明

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