📄 rtos.c
字号:
/****************************************************************************************
* Copyright (c) 2002 ZORAN Corporation, All Rights Reserved
* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF ZORAN CORPORATION
*
* File: $Workfile: rtos.c $
*
* Description:
* ============
*
*
* Log:
* ====
* $Revision: 6 $
* Last Modified by $Author: Leonh $ at $Modtime: 8/27/03 10:29a $
****************************************************************************************
* Updates:
****************************************************************************************
* $Log: /SourceCode/I64_Common/I64_Reference/Kernel/uITRON/rtos.c $
*
* 6 8/27/03 10:57a Leonh
* add the debug function for get the satus if the semaphore is set
*
* 5 03-04-17 11:53 Jerryc
* share reflasher burner APIS with capture_logo and store_ps_in_flash
* features.
*
* 11 23/04/02 9:27 Nirm
* - Added dependency in "Config.h".
*
* 10 27/03/02 8:32 Nirm
* - Corrected typo in the name of InterruptEnable().
*
* 9 26/03/02 23:18 Nirm
* - Documentation.
*
* 8 25/03/02 14:05 Nirm
* Added #include directive.
*
* 7 18/02/02 10:56 Atai
* make global to static
*
* 5 19/01/02 13:01 Atai
* Change error debug printing
*
* 4 1/15/02 2:17p Tomasp
* - code cleanup
* - removed compilation warnings
* - functions _disable and _enable replaced by InterruptDisable and
* InterruptEnable to prevent name colisions with function in embedded.h
*
* 3 9/01/02 18:31 Nirm
* Corrected Include-Paths.
****************************************************************************************/
/****************************************************************************
; Copyright (c) 1999,2000 by Hiroshi Iwabuchi, Japan
; All Rights Reserved.
;
; Pragram Name : IW-RTOS
;
;***************************************************************************/
/* ////////////////////////////////////////////////////////////////////////////
; DEFINE
//////////////////////////////////////////////////////////////////////////// */
#include "Config.h" // Global Configuration - do not remove!
#define _RTOS_H
#define RTOS_DEBUG
/* ////////////////////////////////////////////////////////////////////////////
; INCLUDE
//////////////////////////////////////////////////////////////////////////// */
#include <stdlib.h>
#include "Include\SysDefs.h"
#include "Kernel\uITRON\rtos.h"
/* ////////////////////////////////////////////////////////////////////////////
; INTERNAL Subroutine
//////////////////////////////////////////////////////////////////////////// */
static ER dispatch( void );
static void it_which( T_TSKCB *a_tsk );
static void next_ready( void );
static ER wait_task( UINT tskwait, T_QUEUE *queue, BOOL add_flg );
static void wakeup_task( ER ercd, T_TSKCB *tcb, BOOL add_flg );
static void add_queue( T_QUEUE *top_queue, T_QUEUE *a_queue );
static void delete_queue( T_QUEUE *a_queue );
#if defined(_TIME_SLICE_) || defined(USED_ROT_RDQ)
static T_QUEUE *get_queue( T_QUEUE *a_queue );
static void rotate_queue( T_QUEUE *a_queue );
#endif
static void *blcalloc(void);
static void blcfree( void *blk );
/* ////////////////////////////////////////////////////////////////////////////
; WORK AREA
//////////////////////////////////////////////////////////////////////////// */
#ifdef DEBUG_OS
/* Debug trace */
BOOL dbg_trc_ena; /* enable flag */
int dbg_trc_wrp; /* buffer write pointer */
T_DBGTRCCB dbgtrctbl[TRACEMAXCNT]; /* buffer */
#endif
#ifndef NO_ERCHK
static UH dispatch_counter;
#endif
static UH sysstat; /* system status */
static UH intnest; /* interrupt nesting counter */
static BOOL delaydispatch; /* delayed dispatch flag */
static SYSTIME systim; /* 1msec unit */
#ifdef _TIME_SLICE_
static INT systmslc; /* 0=none. unit is tick */
#endif
static T_TSKCB *currentrun; /* current run task */
static T_TSKCB *nextrun; /* next run task */
static T_QUEUE readyqueue[RDYQMAX]; /* ready queue (same priority queue) */
static T_TSKCB tcbtbl[TSKMAX]; /* task control block */
#if SEMMAX
static T_SEMCB semtbl[SEMMAX]; /* semphore control block */
#endif
#if FLGMAX
static T_FLGCB flgtbl[FLGMAX]; /* event flag control block */
#endif
#if MAILMAX
static T_MSGCB mailbox[MAILMAX]; /* mail box control block */
#endif
static T_DLYCB delyqueue; /* delay task control block */
#if MEM_BLOCK_MAX
static T_MEMBLC mempool[MEM_BLOCK_MAX]; /* memory pool */
static T_MPFCB mpf; /* fixed block memory pool control block */
#endif
static T_MPLCB mpl; /* variable block memory pool control block */
#ifndef NO_ERCHK
static ID error_task_id; /* error task ID */
static char *error_message; /* error message */
static ER error_code; /* error code */
#endif
/* ////////////////////////////////////////////////////////////////////////////
; PROGRAM
//////////////////////////////////////////////////////////////////////////// */
/*=============================================================================
; Disable interrupt and return status register
=============================================================================*/
STATUS_REG InterruptDisable (void)
{
asm
{
pushf
pop ax
cli
}
return (_AX);
}
/*=============================================================================
; Enable interrupt and return status register
=============================================================================*/
STATUS_REG InterruptEnable (void)
{
asm
{
pushf
pop ax
sti
}
return (_AX);
}
/*=============================================================================
; Set status register
=============================================================================*/
void set_SR ( STATUS_REG sr )
{
asm
{
push sr
popf
}
}
#ifndef NO_ERCHK
/*=============================================================================
; ERROR
=============================================================================*/
void error_trap( char *s, ER ercd )
{
#ifdef _DEBUG
InterruptDisable();
#ifdef RTOS_DEBUG
tr_printf(("\n### Error trap: TaskID=%x ErrCode=%d",(ID)((currentrun - tcbtbl) + 1),ercd));
#endif
error_task_id = (ID)((currentrun - tcbtbl) + 1);
error_message = s;
error_code = ercd;
for(;;) ;
#else
return;
#endif
}
#endif
/*=============================================================================
; Initialize RTOS
=============================================================================*/
#ifdef _TIME_SLICE_
void init_rtos( ID tskid, PRI tskpri, INT tmslc )
#else
void init_rtos( ID tskid, PRI tskpri )
#endif
{
int i;
InterruptDisable();
sysstat = (TSS_LOC | TSS_INDP);
intnest = 0;
delaydispatch = FALSE;
currentrun = &tcbtbl[tskid - 1];
nextrun = NULL;
for( i = 0; i < RDYQMAX; i++)
{
T_QUEUE *rdyque = &readyqueue[i];
rdyque->next = rdyque->prev = rdyque;
}
for( i = 0; i < TSKMAX; i++)
{
T_TSKCB *tcb = &tcbtbl[i];
tcb->queue.next = (T_QUEUE *)tcb;
tcb->queue.prev = (T_QUEUE *)tcb;
tcb->stackp = NULL;
//tcb->tskstat = NULL;
//tcb->tskpri = tcb->itskpri = RDYQMAX;
}
currentrun->tskpri = currentrun->itskpri = tskpri;
#ifdef _TIME_SLICE_
currentrun->tmslc = tmslc;
#endif
currentrun->tskwait = FALSE;
currentrun->wupcnt = 0;
#ifndef NO_SUSCNT
currentrun->suscnt = 0;
#endif
#ifndef NO_ERCHK
currentrun->ttltic = 0;
#endif
currentrun->tskstat = TTS_RUN;
add_queue( &readyqueue[tskpri - 1], (T_QUEUE *)currentrun );
#if SEMMAX
for( i = 0; i < SEMMAX; i++)
{
T_SEMCB *semcb = &semtbl[i];
semcb->queue.next = (T_QUEUE *)semcb;
semcb->queue.prev = (T_QUEUE *)semcb;
semcb->semcnt = semcb->maxsem = 1;
#ifdef SUPPORT_CAPTURE_LOGO
if((i == SEM_READY_FOR_CL -1) || (i == SEM_CL_FINISHED -1))
semcb->semcnt = 0;
#endif
}
#endif
#if FLGMAX
for( i = 0; i < FLGMAX; i++)
{
T_FLGCB *flgcb = &flgtbl[i];
flgcb->queue.next = (T_QUEUE *)flgcb;
flgcb->queue.prev = (T_QUEUE *)flgcb;
flgcb->flgptn = 0;
}
#endif
#if MAILMAX
for( i = 0; i < MAILMAX; i++)
{
T_MSGCB *msgcb = &mailbox[i];
msgcb->queue.next = (T_QUEUE *)msgcb;
msgcb->queue.prev = (T_QUEUE *)msgcb;
msgcb->head = msgcb->tail = 0;
}
#endif
for (i = 0;i < MEM_BLOCK_MAX;i++)
{
T_MEMBLC *mb = &mempool[i];
mb->attr = MEMORY_BLOCK_NOT_USED;
}
mpf.queue.next = (T_QUEUE *) &mpf;
mpf.queue.prev = (T_QUEUE *) &mpf;
mpl.queue.next = (T_QUEUE *) &mpl;
mpl.queue.prev = (T_QUEUE *) &mpl;
delyqueue.queue.next = (T_QUEUE *) &delyqueue;
delyqueue.queue.prev = (T_QUEUE *) &delyqueue;
systim = 0;
#ifdef _TIME_SLICE_
systmslc = 0;
#endif
#ifdef DEBUG_OS
dbg_trc_ena = TRUE;
dbg_trc_wrp = TRACEMAXCNT - 1;
#endif
#ifndef NO_ERCHK
dispatch_counter = 0;
#endif
}
/*=============================================================================
; Initialize task
=============================================================================*/
#ifdef _TIME_SLICE_
void init_task( ID tskid, T_CONTEXT *stackp, FP task, PRI tskpri, INT tmslc )
#else
void init_task( ID tskid, T_CONTEXT *stackp, FP task, PRI tskpri )
#endif
{
T_TSKCB *tcb = &tcbtbl[tskid - 1];
tcb->istackp = (T_CONTEXT *)((UB*)stackp-sizeof(T_CONTEXT));
(tcb->istackp)->task = tcb->itask = task;
// (tcb->istackp)->f = get_current_flag_enable_int ();
// (tcb->istackp)->ds = get_current_ds ();
// (tcb->istackp)->es = get_current_es ();
tcb->tskstat = TTS_DMT;
tcb->itskpri = tskpri;
#ifdef _TIME_SLICE_
tcb->tmslc = tmslc;
#endif
}
#ifndef NO_ERCHK
#if SEMMAX
/*=============================================================================
; Initialize semaphore
=============================================================================*/
void init_sem( ID semid, PRI sempri )
{
if( (semid <= 0) || (semid > SEMMAX) )
{
error_trap( "init_sem", E_ID );
}
semtbl[semid - 1].sempri = sempri;
}
#endif
#endif
/*=============================================================================
; Start RTOS
=============================================================================*/
void start_rtos( void )
{
sysstat = TSS_TSK;
next_ready();
dispatch();
set_SR( INIT_SR_VALUE );
}
/*=============================================================================
; Task Management Functions
=============================================================================*/
#ifdef USED_DIS_DSP
/*-----------------------------------------------------------------------------
; Disable Dispatch [R]
-----------------------------------------------------------------------------*/
ER dis_dsp( void )
{
STATUS_REG SRkeep; /* SR(Status Register) keep area */
#ifdef DEBUG_OS
set_dbgtrc(currentrun, "dis_dsp");
#endif
#ifndef NO_ERCHK
if ( sysstat & (TSS_INDP | TSS_DINT) )
{
error_trap( "dis_dsp", E_CTX );
return E_CTX;
}
#endif
SRkeep = InterruptDisable();
sysstat |= TSS_DDSP;
set_SR( SRkeep );
return E_OK;
}
#endif
#ifdef USED_ENA_DSP
/*-----------------------------------------------------------------------------
; Enable Dispatch [R]
-----------------------------------------------------------------------------*/
ER ena_dsp( void )
{
STATUS_REG SRkeep; /* SR(Status Register) keep area */
#ifdef DEBUG_OS
set_dbgtrc(currentrun, "ena_dsp");
#endif
#ifndef NO_ERCHK
if( sysstat & (TSS_INDP | TSS_DINT) )
{
error_trap( "ena_dsp", E_CTX );
return E_CTX;
}
#endif
SRkeep = InterruptDisable();
sysstat &= ~TSS_DDSP;
if( delaydispatch )
dispatch();
set_SR( SRkeep );
return E_OK;
}
#endif
#ifdef USED_STA_TSK
/*-----------------------------------------------------------------------------
; Start Task [S]
-----------------------------------------------------------------------------*/
#pragma argsused
ER sta_tsk( ID tskid, INT stacd )
{
T_TSKCB *tcb;
T_CONTEXT *stackp;
STATUS_REG SRkeep; /* SR(Status Register) keep area */
#ifdef DEBUG_OS
set_dbgtrc(currentrun, "sta_tsk");
#endif
#ifndef NO_ERCHK
if( (tskid <= 0) || (tskid > TSKMAX) )
{
error_trap( "sta_tsk", E_ID );
return E_ID;
}
#endif
tcb = &tcbtbl[tskid - 1];
SRkeep = InterruptDisable();
stackp = tcb->istackp;
#ifndef NO_ERCHK
if( tcb->tskstat == NULL )
{
error_trap( "sta_tsk", E_NOEXS );
set_SR( SRkeep );
return E_NOEXS;
}
if( tcb->tskstat != TTS_DMT )
{
error_trap( "sta_tsk", E_OBJ );
set_SR( SRkeep );
return E_OBJ;
}
#endif
tcb->stackp = stackp;
tcb->tskstat = TTS_RDY;
tcb->tskpri = tcb->itskpri;
tcb->tskwait = FALSE;
tcb->wupcnt = 0;
#ifndef NO_SUSCNT
tcb->suscnt = 0;
#endif
#ifndef NO_ERCHK
tcb->ttltic = 0;
#endif
#ifdef _SH4_
stackp->FPSCR = 0x00040001;
#endif
//stackp->status = INIT_SR_VALUE;
//stackp->argreg = stacd;
stackp->task = tcb->itask;
add_queue( &readyqueue[tcb->tskpri - 1], (T_QUEUE *)tcb );
it_which( tcb );
dispatch();
set_SR( SRkeep );
return E_OK;
}
#endif
#ifdef USED_EXT_TSK
/*-----------------------------------------------------------------------------
; Exit Issuing Task [S]
-----------------------------------------------------------------------------*/
void ext_tsk( void )
{
STATUS_REG SRkeep; /* SR(Status Register) keep area */
SRkeep = InterruptDisable();
#ifdef DEBUG_OS
set_dbgtrc(currentrun, "ext_tsk");
#endif
#ifndef NO_ERCHK
if( sysstat != TSS_TSK )
{
error_trap( "ext_tsk", 0 );
set_SR( SRkeep );
for(;;) ;
}
#endif
delete_queue( (T_QUEUE *)currentrun );
currentrun->tskstat = TTS_DMT;
next_ready();
dispatch();
set_SR( SRkeep );
for(;;) ;
}
#endif
#ifdef USED_TER_TSK
/*-----------------------------------------------------------------------------
; Terminate Other Task [S]
-----------------------------------------------------------------------------*/
ER ter_tsk ( ID tskid )
{
T_TSKCB *tcb;
STATUS_REG SRkeep; /* SR(Status Register) keep area */
#ifdef DEBUG_OS
set_dbgtrc(currentrun, "ter_tsk");
#endif
#ifndef NO_ERCHK
if( (tskid <= 0) || (tskid > TSKMAX) )
{
error_trap( "ter_tsk", E_ID );
return E_ID;
}
#endif
tcb = &tcbtbl[tskid - 1];
SRkeep = InterruptDisable();
#ifndef NO_ERCHK
if( tcb->tskstat == NULL )
{
error_trap( "ter_tsk", E_NOEXS );
set_SR( SRkeep );
return E_NOEXS;
}
if( (currentrun == tcb) && !(sysstat & (TSS_INDP | TSS_DINT)) )
{
error_trap( "ter_tsk", E_OBJ );
set_SR( SRkeep );
return E_OBJ;
}
if( tcb->tskstat == TTS_DMT )
{
error_trap( "ter_tsk", E_OBJ );
set_SR( SRkeep );
return E_OBJ;
}
#endif
delete_queue( (T_QUEUE *)tcb );
tcb->tskstat = TTS_DMT;
set_SR( SRkeep );
return E_OK;
}
#endif
#ifdef USED_CHG_PRI
/*-----------------------------------------------------------------------------
; Change Task Priority [S]
-----------------------------------------------------------------------------*/
ER chg_pri( ID tskid, PRI tskpri )
{
T_TSKCB *tcb;
PRI lasttskpri;
STATUS_REG SRkeep; /* SR(Status Register) keep area */
#ifdef DEBUG_OS
set_dbgtrc(currentrun, "chg_pri");
#endif
#ifndef NO_ERCHK
if( (tskid < 0) || (tskid > TSKMAX) )
{
error_trap( "chg_pri", E_ID );
return E_ID;
}
if( (tskpri < 0) || (tskpri > RDYQMAX) )
{
error_trap( "chg_pri", E_PAR );
return E_PAR;
}
#endif
#ifndef NO_ERCHK
if( (tskid == TSK_SELF) && (sysstat & (TSS_INDP | TSS_DINT)) )
{
error_trap( "chg_pri", E_OBJ );
return E_OBJ;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -