📄 rtos.c
字号:
return E_ID;
}
if( (blf == (VP)NULL) || (blf == (VP)NADR) )
{
error_trap( "rel_blf", E_PAR );
return E_PAR;
}
#endif
SRkeep = InterruptDisable();
blcfree( blf );
tcb = (T_TSKCB *)(mpf.queue.next);
if( (T_QUEUE *)tcb != (T_QUEUE *)&mpf )
{
a_blf = blcalloc();
if( a_blf == NULL )
{
set_SR( SRkeep );
return E_OK;
}
tcb->ans = (VP*)a_blf;
wakeup_task( E_OK, tcb, TRUE );
}
set_SR( SRkeep );
return E_OK;
}
#endif
#ifdef USED_GET_BLF
/*-----------------------------------------------------------------------------
; Get Fixed-Size Memory Block [E]
-----------------------------------------------------------------------------*/
ER get_blf( VP *p_blf, ID mplid)
{
ER ercd;
STATUS_REG SRkeep; /* SR(Status Register) keep area */
#ifdef DEBUG_OS
set_dbgtrc(currentrun, "get_blf");
#endif
*p_blf = NULL;
#ifndef NO_ERCHK
if( mplid != 1 )
{
error_trap( "get_blf", E_PAR );
return E_ID;
}
if( sysstat & (TSS_INDP | TSS_DDSP) )
{
error_trap( "get_blf", E_CTX );
return E_CTX;
}
#endif
SRkeep = InterruptDisable();
*p_blf = blcalloc();
if( *p_blf != NULL )
{
set_SR( SRkeep );
return E_OK;
}
ercd = wait_task( TTW_MPF, (T_QUEUE *)&mpf, TRUE );
*p_blf = (VP*)(currentrun->ans);
set_SR( SRkeep );
return ercd;
}
#endif
#ifdef USED_PGET_BLF
/*-----------------------------------------------------------------------------
; Poll and Get Fixed-Size Memory Block [E]
-----------------------------------------------------------------------------*/
ER pget_blf( VP *p_blf, ID mplid )
{
ER ercd;
STATUS_REG SRkeep; /* SR(Status Register) keep area */
#ifdef DEBUG_OS
set_dbgtrc(currentrun, "pget_blf");
#endif
*p_blf = NULL;
#ifndef NO_ERCHK
if( mplid != 1 )
{
error_trap( "pget_blf", E_ID );
return E_ID;
}
#endif
SRkeep = InterruptDisable();
*p_blf = blcalloc();
if( *p_blf == NULL )
ercd = E_TMOUT;
else
ercd = E_OK;
set_SR( SRkeep );
return ercd;
}
#endif
/*=============================================================================
; Interrupt Management Functions
=============================================================================*/
#ifdef USED_LOC_CPU
/*-----------------------------------------------------------------------------
; Lock CPU [R]
-----------------------------------------------------------------------------*/
ER loc_cpu( void )
{
#ifdef DEBUG_OS
set_dbgtrc(currentrun, "loc_cpu");
#endif
#ifndef NO_ERCHK
if( sysstat & TSS_INDP )
{
error_trap( "loc_cpu", E_CTX );
return E_CTX;
}
#endif
InterruptDisable();
sysstat |= TSS_LOC;
return E_OK;
}
#endif
#ifdef USED_UNL_CPU
/*-----------------------------------------------------------------------------
; Unlock CPU [R]
-----------------------------------------------------------------------------*/
ER unl_cpu( void )
{
#ifdef DEBUG_OS
set_dbgtrc(currentrun, "unl_cpu");
#endif
#ifndef NO_ERCHK
if ( sysstat & TSS_INDP )
{
error_trap( "unl_cpu", E_CTX );
return E_CTX;
}
#endif
sysstat &= ~TSS_LOC;
if( delaydispatch )
dispatch();
InterruptEnable();
return E_OK;
}
#endif
/*-----------------------------------------------------------------------------
; Entrance of interrupt
-----------------------------------------------------------------------------*/
void ent_int( void )
{
STATUS_REG SRkeep; /* SR(Status Register) keep area */
SRkeep = InterruptDisable();
intnest++;
sysstat |= TSS_INDP;
set_SR( SRkeep );
}
/*-----------------------------------------------------------------------------
; Return from Interrupt Handler [R]
-----------------------------------------------------------------------------*/
void ret_int( void )
{
STATUS_REG SRkeep; /* SR(Status Register) keep area */
SRkeep = InterruptDisable();
intnest--;
if( !intnest ){
sysstat &= ~TSS_INDP;
if( delaydispatch ){
dispatch();
}
}
set_SR( SRkeep );
}
/*=============================================================================
; Time Management Functions
=============================================================================*/
#ifdef USED_SET_TIM
/*-----------------------------------------------------------------------------
; Set System Clock [S]
-----------------------------------------------------------------------------*/
ER set_tim( SYSTIME *pk_tim )
{
STATUS_REG SRkeep; /* SR(Status Register) keep area */
#ifdef DEBUG_OS
set_dbgtrc(currentrun, "set_tim");
#endif
#ifndef NO_ERCHK
if( pk_tim == NULL )
{
error_trap( "set_tim", E_PAR );
return E_PAR;
}
#endif
SRkeep = InterruptDisable();
systim = *pk_tim;
set_SR( SRkeep );
return E_OK;
}
#endif
#ifdef USED_GET_TIM
/*-----------------------------------------------------------------------------
; Get System Clock [S]
-----------------------------------------------------------------------------*/
ER get_tim( SYSTIME *pk_tim )
{
STATUS_REG SRkeep; /* SR(Status Register) keep area */
#ifdef DEBUG_OS
set_dbgtrc(currentrun, "get_tim");
#endif
#ifndef NO_ERCHK
if( pk_tim == NULL )
{
error_trap( "get_tim", E_PAR );
return E_PAR;
}
#endif
SRkeep = InterruptDisable();
*pk_tim = systim;
set_SR( SRkeep );
return E_OK;
}
#endif
#ifdef USED_DLY_TSK
/*-----------------------------------------------------------------------------
; Delay Task [S]
-----------------------------------------------------------------------------*/
ER dly_tsk( DLYTIME dlytim )
{
T_TSKCB *tcb;
STATUS_REG SRkeep; /* SR(Status Register) keep area */
ER ercd;
SYSTIME st;
#ifdef DEBUG_OS
set_dbgtrc(currentrun, "dly_tsk");
#endif
#ifndef NO_ERCHK
if( dlytim <= 0 )
{
error_trap( "dly_tsk", E_PAR );
return E_PAR;
}
if( sysstat & (TSS_INDP | TSS_DDSP) )
{
error_trap( "dly_tsk", E_CTX );
return E_CTX;
}
#endif
SRkeep = InterruptDisable();
st = systim + (SYSTIME)dlytim;
currentrun->waistm = &st;
for( tcb = (T_TSKCB *)(delyqueue.queue.next);
#if 1
((T_DLYCB *)tcb != &delyqueue) && (st >= *(tcb->waistm));
#else
((T_DLYCB *)tcb != &delyqueue) && (st <= *(tcb->waistm));
#endif
tcb = (T_TSKCB *)(tcb->queue.next) )
;
#if 1
ercd = wait_task( TTW_DLY, (T_QUEUE *)tcb, TRUE );
#else
ercd = wait_task( TTW_DLY, (T_QUEUE *)(tcb->queue.next), TRUE );
#endif
set_SR( SRkeep );
return ercd;
}
#endif
/*-----------------------------------------------------------------------------
; Timer Interrupt Handler
-----------------------------------------------------------------------------*/
void interrupt_timer( void )
{
T_TSKCB *tcb;
STATUS_REG SRkeep; /* SR(Status Register) keep area */
SRkeep = InterruptDisable();
systim += RTOS_TICK_MS;
#ifndef NO_ERCHK
if( currentrun->tskstat == TTS_RDY )
{
currentrun->ttltic += RTOS_TICK_MS;
}
#endif
for( tcb = (T_TSKCB *)(delyqueue.queue.next);
((T_DLYCB *)tcb != &delyqueue) && (systim >= *(tcb->waistm));
//tcb = (T_TSKCB *)(tcb->queue.next) ) // See comment below!
tcb = (T_TSKCB *)(delyqueue.queue.next) )
{
// NOTE: wakeup_task() has a side effect of changing the delyqueue, hence
// the iteration of this loop must NOT use the explicit value of tcb (which
// by now was changed to point at the next READY task, rather than the next
// delayed task).
wakeup_task( E_OK, tcb, FALSE );
#ifdef DEBUG_OS
set_dbgtrc(tcb, "TMOUT");
#endif
delaydispatch = TRUE;
}
#ifdef _TIME_SLICE_
if( systmslc )
{
if( systmslc == 1 )
{
#ifdef DEBUG_OS
dbg_trc_ena = FALSE;
#endif
rot_rdq( TPRI_RUN );
#ifdef DEBUG_OS
dbg_trc_ena = TRUE;
#endif
}
else{
systmslc--;
}
}
#endif
set_SR( SRkeep );
}
/*=============================================================================
; System Management Functions
=============================================================================*/
#ifdef USED_GET_VER
/*-----------------------------------------------------------------------------
; Get Version Information [R]
-----------------------------------------------------------------------------*/
ER get_ver( T_VER *pk_ver )
{
#ifdef DEBUG_OS
set_dbgtrc(currentrun, "get_ver");
#endif
if( pk_ver == NULL )
{
#ifndef NO_ERCHK
error_trap( "get_ver", E_PAR );
#endif
return E_PAR;
}
pk_ver->maker = 0x0000;
pk_ver->id = 0x0001;
pk_ver->spver = 0x5302;
pk_ver->prver = 0x0001;
pk_ver->prno[0] = 0x0000;
pk_ver->prno[1] = 0x0000;
pk_ver->prno[2] = 0x0000;
pk_ver->prno[3] = 0x0000;
pk_ver->cpu = 0x0000; /* 186 */
pk_ver->var = 0x8000; /* level S */
return E_OK;
}
#endif
/*=============================================================================
; Dispatcher
=============================================================================*/
static ER dispatch( void )
{
T_TSKCB *lastrun;
T_TSKCB *nextrun_tmp;
ER ercd;
ercd = E_OK;
if( sysstat == TSS_TSK )
{
delaydispatch = FALSE;
nextrun_tmp = nextrun;
nextrun = NULL;
if( (nextrun_tmp != NULL) && (nextrun_tmp != currentrun) )
{
if(currentrun->tskstat == TTS_RUN){
currentrun->tskstat = TTS_RDY;
}
lastrun = currentrun;
currentrun = nextrun_tmp;
currentrun->tskstat = TTS_RUN;
#ifdef _TIME_SLICE_
systmslc = currentrun->tmslc;
#endif
#ifdef DEBUG_OS
set_dbgtrc(currentrun, "dispatch");
#endif
#ifndef NO_ERCHK
dispatch_counter++;
#endif
ercd = change_stack( &(currentrun->stackp), &(lastrun->stackp) );
}
else
{
currentrun->tskstat = TTS_RUN;
}
}
else
{
delaydispatch = TRUE;
}
return ercd;
}
/*=============================================================================
; Functions For support
=============================================================================*/
/*-----------------------------------------------------------------------------
; Is it next-run-task ?
-----------------------------------------------------------------------------*/
static void it_which( T_TSKCB *a_tsk )
{
if( (a_tsk->tskpri < currentrun->tskpri)
&& ( (nextrun == NULL)
|| ( (nextrun != NULL) && (a_tsk->tskpri < nextrun->tskpri) )
)
)
{
if( !(a_tsk->tskstat & TTS_SUS) )
{
a_tsk->tskstat = TTS_RDY;
nextrun = a_tsk;
}
}
}
/*-----------------------------------------------------------------------------
; Next run task ?
-----------------------------------------------------------------------------*/
static void next_ready( void )
{
T_QUEUE *rdypri;
for( rdypri = &readyqueue[0]; rdypri <= &readyqueue[RDYQMAX-1]; rdypri++ )
{
nextrun = (T_TSKCB *)rdypri->next;
while( nextrun != (T_TSKCB *)rdypri )
{
if( !(nextrun->tskstat & TTS_SUS) )
return;
nextrun = (T_TSKCB *)(nextrun->queue.next);
}
}
nextrun = NULL;
}
/*=============================================================================
; Wait task
=============================================================================*/
static ER wait_task( UINT tskwait, T_QUEUE *queue, BOOL add_flg )
{
currentrun->tskstat |= TTS_WAI;
currentrun->tskwait = tskwait;
delete_queue( (T_QUEUE *)currentrun );
if( add_flg )
add_queue( queue, (T_QUEUE *)currentrun );
while( 1 )
{
next_ready();
if( nextrun != NULL ) break;
sysstat |= TSS_DDSP;
InterruptEnable();
__asm {
nop
nop
}
InterruptDisable();
sysstat &= ~TSS_DDSP;
}
return( dispatch() );
}
/*=============================================================================
; Wakeup task
=============================================================================*/
#pragma argsused
static void wakeup_task( ER ercd, T_TSKCB *tcb, BOOL dsp_flg )
{
tcb->tskstat &= ~TTS_WAI;
tcb->tskwait = FALSE;
//(tcb->stackp)->retval = ercd;
delete_queue( (T_QUEUE *)tcb );
add_queue( &readyqueue[tcb->tskpri - 1], (T_QUEUE *)tcb );
it_which( tcb );
if( dsp_flg )
dispatch();
}
/*=============================================================================
; Queue Handling Functions
=============================================================================*/
/*-----------------------------------------------------------------------------
; Add it to queue
-----------------------------------------------------------------------------*/
static void add_queue( T_QUEUE *top_queue, T_QUEUE *a_queue )
{
a_queue->next = top_queue;
a_queue->prev = top_queue->prev;
(top_queue->prev)->next = a_queue;
top_queue->prev = a_queue;
}
/*-----------------------------------------------------------------------------
; Delete it from queue
-----------------------------------------------------------------------------*/
static void delete_queue( T_QUEUE *a_queue )
{
(a_queue->next)->prev = a_queue->prev;
(a_queue->prev)->next = a_queue->next;
a_queue->prev = a_queue;
a_queue->next = a_queue;
}
#if defined(_TIME_SLICE_) || defined(USED_ROT_RDQ)
/*-----------------------------------------------------------------------------
; Get it from queue
-----------------------------------------------------------------------------*/
static T_QUEUE *get_queue( T_QUEUE *a_queue )
{
T_QUEUE *anode;
anode = a_queue->next;
delete_queue( anode );
return anode;
}
/*-----------------------------------------------------------------------------
; Rotate queue
-----------------------------------------------------------------------------*/
static void rotate_queue( T_QUEUE *a_queue )
{
if(a_queue != a_queue->next )
add_queue( a_queue, get_queue( a_queue ) );
}
#endif
#ifdef DEBUG_OS
/*=============================================================================
; Set debug information to trace buffer
=============================================================================*/
void set_dbgtrc(T_TSKCB *tsk, char* srvnm)
{
STATUS_REG SRkeep; /* SR(Status Register) keep area */
SRkeep = InterruptDisable();
if(!dbg_trc_ena) return;
if(dbg_trc_wrp >= TRACEMAXCNT - 1){
dbg_trc_wrp = 0;
}else{
dbg_trc_wrp++;
}
dbgtrctbl[dbg_trc_wrp].tskid = (tsk - tcbtbl) + 1;
dbgtrctbl[dbg_trc_wrp].tskpri = tsk->tskpri;
dbgtrctbl[dbg_trc_wrp].srvnm = srvnm;
dbgtrctbl[dbg_trc_wrp].tim = (UINT)systim;
set_SR( SRkeep );
}
#endif
static void *blcalloc(void)
{
T_MEMBLC *mb;
for (mb = mempool;mb < &mempool[MEM_BLOCK_MAX];mb++)
{
if (mb->attr == MEMORY_BLOCK_NOT_USED)
{
mb->attr = MEMORY_BLOCK_USED;
return (void*)(mb->data);
}
}
return NULL;
}
static void blcfree(void *mb)
{
((T_MEMBLC *)mb)->attr = MEMORY_BLOCK_NOT_USED;
}
/* end of file ///////////////////////////////////////////////////////////// */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -