📄 rtos.c
字号:
}
#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 + -