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

📄 rtos.c

📁 一个完整的rtos源代码.运行在嵌入80186 cpu上.提供4个任务,信号灯,定时器,schedule等.
💻 C
📖 第 1 页 / 共 4 页
字号:
	}
#endif

	if( tskid == TSK_SELF )
	{
		tcb = currentrun;
	}
	else
	{
		tcb = &tcbtbl[tskid - 1];
	}

	SRkeep = InterruptDisable();

#ifndef NO_ERCHK
	if( tcb->tskstat == TTS_DMT )
	{
		error_trap( "chg_pri", E_OBJ );
		set_SR( SRkeep );
		return E_OBJ;
	}

	if( tcb->tskstat == NULL )
	{
		error_trap( "chg_pri", E_NOEXS );
		set_SR( SRkeep );
		return E_NOEXS;
	}
#endif

	if( tskpri == TPRI_INI )
		tskpri = tcb->itskpri;

	if( tcb->tskstat == TTS_RUN )
	{
		delete_queue( (T_QUEUE *)tcb );
		add_queue( &readyqueue[tskpri - 1], (T_QUEUE *)tcb );
		lasttskpri = tcb->tskpri;
		tcb->tskpri = tskpri;
		if( tskpri >= lasttskpri )
		{
			next_ready();
		}
	}

	else if( tcb->tskstat == TTS_RDY )
	{
		delete_queue( (T_QUEUE *)tcb );
		add_queue( &readyqueue[tskpri - 1], (T_QUEUE *)tcb );
		tcb->tskpri = tskpri;
		it_which( tcb );
	}

	else{
		tcb->tskpri = tskpri;
	}

	dispatch();

	set_SR( SRkeep );

	return E_OK;
}
#endif

#if defined(_TIME_SLICE_) || defined(USED_ROT_RDQ)
/*-----------------------------------------------------------------------------
; Rotate Tasks on the Ready Queue [S]
-----------------------------------------------------------------------------*/
ER rot_rdq( PRI tskpri )
{
	//T_TSKCB *tcb;
	STATUS_REG SRkeep;					/* SR(Status Register) keep area */

#ifdef DEBUG_OS
	set_dbgtrc(currentrun, "rot_rdq");
#endif

#ifndef NO_ERCHK
	if( (tskpri < 0) || (tskpri > RDYQMAX) )
	{
		error_trap( "rot_rdq", E_PAR );
		return E_PAR;
	}
#endif

	SRkeep = InterruptDisable();

	if( tskpri == TPRI_RUN ){
		tskpri = currentrun->tskpri;
	}

	rotate_queue( &readyqueue[tskpri - 1] );

	if( tskpri == currentrun->tskpri ){
		next_ready();
		dispatch();
	}

	set_SR( SRkeep );

	return E_OK;
}
#endif

#ifdef USED_REL_WAI
/*-----------------------------------------------------------------------------
; Release Wait of Other Task [S]
-----------------------------------------------------------------------------*/
ER rel_wai( ID tskid )
{
	T_TSKCB *tcb;
	STATUS_REG SRkeep;					/* SR(Status Register) keep area */

#ifdef DEBUG_OS
	set_dbgtrc(currentrun, "rel_wai");
#endif

#ifndef NO_ERCHK
	if( (tskid <= 0) || (tskid > TSKMAX) )
	{
		error_trap( "rel_wai", E_NOSPT );
		return E_ID;
	}
#endif

	tcb = &tcbtbl[tskid - 1];

#ifndef NO_ERCHK
	if( (tcb == currentrun) && !(sysstat & TSS_INDP) )
	{
		error_trap( "rel_wai", E_OBJ );
		return E_OBJ;
	}
#endif

	SRkeep = InterruptDisable();

#ifndef NO_ERCHK
	if ( tcb->tskstat == NULL )
	{
		error_trap( "rel_wai", E_NOEXS );
		set_SR( SRkeep );
		return E_NOEXS;
	}

	if( !(tcb->tskstat & TTS_WAI) )
	{
		error_trap( "rel_wai", E_OBJ );
		set_SR( SRkeep );
		return E_OBJ;
	}
#endif

	tcb->wupcnt = 0;
	wakeup_task( E_RLWAI, tcb, TRUE );

	set_SR( SRkeep );

	return E_OK;
}
#endif

#ifdef USED_GET_TID
/*-----------------------------------------------------------------------------
; Get Task Identifier [S]
-----------------------------------------------------------------------------*/
ER get_tid( ID *p_tskid )
{
	STATUS_REG SRkeep;					/* SR(Status Register) keep area */

	*p_tskid = 0;

#ifdef DEBUG_OS
	set_dbgtrc(currentrun, "get_tid");
#endif

	SRkeep = InterruptDisable();

#ifndef NO_ERCHK
	if( (sysstat&(TSS_INDP | TSS_DINT)) || (currentrun == NULL) )
	{
		error_trap( "get_tid", E_NOEXS );
		set_SR( SRkeep );
		*p_tskid = FALSE;
		return E_NOEXS;
	}
#endif

	*p_tskid = (currentrun - tcbtbl) + 1;

	set_SR( SRkeep );

	return E_OK;
}
#endif

/*=============================================================================
; Task-Dependent Synchronization Functions
=============================================================================*/
#ifdef USED_SLP_TSK
/*-----------------------------------------------------------------------------
; Sleep Task [R]
-----------------------------------------------------------------------------*/
ER slp_tsk( void )
{
	ER ercd;
	STATUS_REG SRkeep;					/* SR(Status Register) keep area */

#ifdef DEBUG_OS
	set_dbgtrc(currentrun, "slp_tsk");
#endif

#ifndef NO_ERCHK
	if( sysstat != TSS_TSK )
	{
		error_trap( "slp_tsk", E_CTX );
		return E_CTX;
	}
#endif

	SRkeep = InterruptDisable();

	if( currentrun->wupcnt > 0 ) {
		currentrun->wupcnt--;
		set_SR( SRkeep );
		return E_OK;
	}

	ercd = wait_task( TTW_SLP, NULL, FALSE);

	set_SR( SRkeep );

	return ercd;
}
#endif

#ifdef USED_WUP_TSK
/*-----------------------------------------------------------------------------
; Wakeup Other Task [R]
-----------------------------------------------------------------------------*/
ER wup_tsk( ID tskid )
{
	T_TSKCB *tcb;
	STATUS_REG SRkeep;					/* SR(Status Register) keep area */

#ifdef DEBUG_OS
	set_dbgtrc(currentrun, "wup_tsk");
#endif

#ifndef NO_ERCHK
	if( (tskid <= 0) || (tskid > TSKMAX) )
	{
		error_trap( "wup_tsk", E_ID );
		return E_ID;
	}

	if( (tcb == currentrun) && !(sysstat & TSS_INDP) )
	{
		error_trap( "wup_tsk", E_OBJ );
		return E_OBJ;
	}
#endif

	tcb = &tcbtbl[tskid - 1];

	SRkeep = InterruptDisable();

#ifndef NO_ERCHK
	if( tcb->tskstat == NULL )
	{
		error_trap( "wup_tsk", E_NOEXS );
		set_SR( SRkeep );
		return E_NOEXS;
	}

	if( tcb->tskstat == TTS_DMT )
	{
		error_trap( "wup_tsk", E_OBJ );
		set_SR( SRkeep );
		return E_OBJ;
	}
#endif

	if( !(tcb->tskstat & TTS_WAI) || tcb->tskwait != TTW_SLP )
	{
#ifndef NO_ERCHK
		if ( tcb->wupcnt == MAX_WUPCNT )
		{
			error_trap( "wup_tsk", E_QOVR );
			set_SR( SRkeep );
			return E_QOVR;
		}
#endif
		tcb->wupcnt++;
	}
	else
	{
		wakeup_task( E_OK, tcb, TRUE );
	}

	set_SR( SRkeep );

	return E_OK;
}
#endif

#ifdef USED_CAN_WUP
/*-----------------------------------------------------------------------------
; Cancel Wakeup Request [S]
-----------------------------------------------------------------------------*/
ER can_wup( INT *p_wupcnt, ID tskid )
{
	T_TSKCB *tcb;
	STATUS_REG SRkeep;					/* SR(Status Register) keep area */

#ifdef DEBUG_OS
	set_dbgtrc(currentrun, "can_wup");
#endif

	*p_wupcnt = 0;

#ifndef NO_ERCHK
	if( (tskid < 0) || (tskid > TSKMAX) )
	{
		error_trap( "can_wup", E_ID );
		return E_ID;
	}
#endif

	if( tskid == TSK_SELF )
	{
		tcb = currentrun;
	}
	else
	{
		tcb = &tcbtbl[tskid - 1];
	}

	SRkeep = InterruptDisable();

#ifndef NO_ERCHK
	if( (tskid == TSK_SELF) && (sysstat & TSS_INDP) )
	{
		error_trap( "can_wup", E_ID );
		set_SR( SRkeep );
		return E_ID;
	}

	if( tcb->tskstat == NULL )
	{
		error_trap( "can_wup", E_NOEXS );
		set_SR( SRkeep );
		return E_NOEXS;
	}

	if( tcb->tskstat == TTS_DMT )
	{
		error_trap( "can_wup", E_OBJ );
		set_SR( SRkeep );
		return E_OBJ;
	}
#endif

	*p_wupcnt = tcb->wupcnt;
	tcb->wupcnt = 0;

	set_SR( SRkeep );

	return E_OK;
}
#endif

#ifdef USED_SUS_TSK
/*-----------------------------------------------------------------------------
; Suspend Other Task [S]
-----------------------------------------------------------------------------*/
ER sus_tsk( ID tskid )
{
	T_TSKCB *tcb;
	STATUS_REG SRkeep;					/* SR(Status Register) keep area */

#ifdef DEBUG_OS
	set_dbgtrc(currentrun, "sus_tsk");
#endif

#ifndef NO_ERCHK
	if( (tskid <= 0) || (tskid > TSKMAX) )
	{
		error_trap( "sus_tsk", E_ID );
		return E_ID;
	}

	if( (tcb == currentrun) && !(sysstat & TSS_INDP) )
	{
		error_trap( "sus_tsk", E_OBJ );
		return E_OBJ;
	}
#endif

	tcb = &tcbtbl[tskid - 1];

	SRkeep = InterruptDisable();

#ifndef NO_ERCHK
	if( tcb->tskstat == NULL )
	{
		error_trap( "sus_tsk", E_NOEXS );
		set_SR( SRkeep );
		return E_NOEXS;
	}

	if( tcb->tskstat == TTS_DMT )
	{
		error_trap( "sus_tsk", E_OBJ );
		set_SR( SRkeep );
		return E_OBJ;
	}
#endif

#ifndef NO_ERCHK
	if( tcb->tskstat & TTS_SUS )
	{
#ifdef NO_SUSCNT
		error_trap( "sus_tsk", E_QOVR );
		set_SR( SRkeep );
		return E_QOVR;
#else
		if( tcb->suscnt >= MAX_SUSCNT )
		{
			error_trap( "sus_tsk", E_QOVR );
			set_SR( SRkeep );
			return E_QOVR;
		}
		tcb->suscnt++;
#endif
	}
	else
	{
#endif
		tcb->tskstat |= TTS_SUS;

		if( tcb == currentrun )
		{
			next_ready();
			delaydispatch = TRUE;
		}
#ifndef NO_ERCHK
	}
#endif

	set_SR( SRkeep );

	return E_OK;
}
#endif

#ifdef USED_RSM_TSK
/*-----------------------------------------------------------------------------
; Resume Suspended Task [S]
-----------------------------------------------------------------------------*/
ER rsm_tsk( ID tskid )
{
	T_TSKCB *tcb;
	STATUS_REG SRkeep;					/* SR(Status Register) keep area */

#ifdef DEBUG_OS
	set_dbgtrc(currentrun, "rsm_tsk");
#endif

#ifndef NO_ERCHK
	if( (tskid <= 0) || (tskid > TSKMAX) )
	{
		error_trap( "rsm_tsk", E_ID );
		return E_ID;
	}

	if( tcb == currentrun )
	{
		error_trap( "rsm_tsk", E_OBJ );
		return E_OBJ;
	}
#endif

	tcb = &tcbtbl[tskid - 1];

	SRkeep = InterruptDisable();

#ifndef NO_ERCHK
	if( tcb->tskstat == NULL )
	{
		error_trap( "rsm_tsk", E_NOEXS );
		set_SR( SRkeep );
		return E_NOEXS;
	}

	if( !(tcb->tskstat & TTS_SUS) )
	{
		error_trap( "rsm_tsk", E_OBJ );
		set_SR( SRkeep );
		return E_OBJ;
	}

	if( tcb->tskstat == TTS_DMT )
	{
		error_trap( "rsm_tsk", E_OBJ );
		set_SR( SRkeep );
		return E_OBJ;
	}
#endif

#ifndef NO_SUSCNT
	if( tcb->suscnt > 0 )
	{
		tcb->suscnt--;
	}
	else
	{
#endif
		tcb->tskstat &= ~TTS_SUS;
		if( !(tcb->tskstat & TTS_WAI) )
		{
			tcb->tskstat = TTS_RDY;
			it_which( tcb );
			dispatch();
		}
#ifndef NO_SUSCNT
	}
#endif

	set_SR( SRkeep );

	return E_OK;
}
#endif

/*=============================================================================
; Synchronization and Communication Functions
=============================================================================*/
#if SEMMAX
#ifdef USED_SIG_SEM
/*-----------------------------------------------------------------------------
; Signal Semaphore [R]
-----------------------------------------------------------------------------*/
ER sig_sem( ID semid )
{
	T_SEMCB *scb;
	T_TSKCB *tcb;
	STATUS_REG SRkeep;					/* SR(Status Register) keep area */

#ifdef DEBUG_OS
	set_dbgtrc(currentrun, "sig_sem");
#endif

#ifndef NO_ERCHK
	if( (semid <= 0) || (semid > SEMMAX) )
	{
		error_trap( "sig_sem", E_ID );
		return E_ID;
	}
#endif

	scb = &semtbl[semid - 1];

	SRkeep = InterruptDisable();

#ifndef NO_ERCHK
	if( scb->semcnt >= scb->maxsem )
	{
		error_trap( "sig_sem", E_QOVR );
		set_SR( SRkeep );
		return E_QOVR;
	}
	
#if 0
	/* To avoid the dead lock and priority inversion */
	if( (sysstat == TSS_TSK)
	 && ((scb->sempri) != (currentrun->tskpri)) )
	{
		error_trap( "sig_sem", 0 );
	}
#endif
#endif

	if( (T_SEMCB *)(scb->queue.next) == scb )
	{
		scb->semcnt++;
	}
	else
	{
		tcb = (T_TSKCB *)(scb->queue.next);

		wakeup_task( E_OK, tcb, TRUE );
	}

	set_SR( SRkeep );

	return E_OK;
}
#endif

#ifdef USED_WAI_SEM
/*-----------------------------------------------------------------------------
; Wait on Semaphore [R]
-----------------------------------------------------------------------------*/
ER wai_sem( ID semid )
{
	T_SEMCB *scb;
	ER		ercd;
	STATUS_REG SRkeep;					/* SR(Status Register) keep area */

#ifdef DEBUG_OS
	set_dbgtrc(currentrun, "wai_sem");
#endif

#ifndef NO_ERCHK
	if( (semid <= 0) || (semid > SEMMAX) )
	{
		error_trap( "wai_sem", E_ID );
		return E_ID;
	}

	if( sysstat & (TSS_INDP | TSS_DDSP) )
	{
		error_trap( "wai_sem", E_CTX );
		return E_CTX;
	}
#endif

	scb = &semtbl[semid - 1];

	SRkeep = InterruptDisable();

#ifndef NO_ERCHK
#if 0
	/* To avoid the dead lock and priority inversion */
	if( (scb->sempri) != (currentrun->tskpri) )
	{
		error_trap( "wai_sem", 0 );
	}
#endif
#endif

	if( scb->semcnt > 0 )
	{
		scb->semcnt--;
		set_SR( SRkeep );
		return E_OK;
	}

	ercd = wait_task( TTW_SEM, (T_QUEUE *)scb, TRUE );

	set_SR( SRkeep );

	return ercd;
}
#endif

#ifdef USED_PREQ_SEM
/*-----------------------------------------------------------------------------
; Poll and Request Semaphore [R]
-----------------------------------------------------------------------------*/
ER preq_sem( ID semid )
{

	T_SEMCB *scb;
	STATUS_REG SRkeep;					/* SR(Status Register) keep area */

⌨️ 快捷键说明

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