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

📄 rtos.c

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

/****************************************************************************************
 *  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 + -