?? rtmk.c
字號(hào):
/************************************************************************
*
* Module name : RTMK.C
*
* Module description :
* This module contains task management functions for RTMK.
*
* About jmp_buf:
* + Borland C++ compiler defines jmp_buf as a pointer to a data structure:
* struct __jmp_buf
* {
* unsigned j_sp;
* unsigned j_ss;
* unsigned j_flag;
* unsigned j_cs;
* unsigned j_ip;
* unsigned j_bp;
* unsigned j_di;
* unsigned j_es;
* unsigned j_si;
* unsigned j_ds;
* };
* to store information of registers.
*
* + WatCom C++ compiler defines jmp_buf as a 13 integer array to store
* information of registers:
* [0] = BX
* [1] = CX
* [2] = DX
* [3] = SI
* [4] = DI
* [5] = BP
* [6] = SP
* [7] = ES
* [8] = DS
* [9] = CS
* [10] = IP
* [11] = Don't know yet (flags ?)
* [12] = SS
*
* Project : RTMK
*
* Target platform : DOS
*
* Compiler & Library : BC++ 3.1
*
* Author : Richard Shen
*
* Creation date : 16 August, 1995
*
************************************************************************/
#include <memory.h>
#ifdef __DOS__
# include <stdlib.h>
# include <dos.h>
# include <signal.h>
# include <conio.h>
#endif /* __DOS__ */
#include <rtmk.h>
#include <errors.h>
#include "rtmkloc.h"
/************************************************************************
* S T A T I C V A R I A B L E S *
************************************************************************/
/*
NOTE: numProcess declared as FAR, when it is referenced by Borland C++
compiler, ES register will be used.
*/
#ifdef __DOS__
static int far numProcess; /* Number of Processes created */
#else
static int numProcess; /* Number of Processes created */
#endif /* __DOS__ */
/************************************************************************
* Function name : RtmkRun
* Description : Main entry point of RTMK kernel
* :
* Parameters : -
* Returns : SUCCESSFUL
* Author : Richard Shen
* -----------------------------------------------------------------------
* Date By Description
* -----------------------------------------------------------------------
* 16Aug95 RCS Created.
************************************************************************/
uint RtmkRun(void)
{
/* Initialise kernel data */
memset(&pcsTable[0], 0, sizeof(pcsTable));
numProcess = 0;
curProcess = NULL;
readyProcess = 0;
#ifdef __DOS__
servingInt = FALSE;
#endif /* __DOS__ */
/* Create the default task */
RtmkStartTask(&curProcess, NULL, 0);
Scheduler(NULL, FALSE);
return(SUCCESSFUL);
} /* RtmkRun() */
/************************************************************************
* Function name : RtmkStartTask
* Description : Create an application task
* :
* Parameters : process - Task control block
* : taskEntry - Task entry point. NULL if running code
* : stackSize - Size of task's stack
* Returns : -
* Author : Richard Shen
* -----------------------------------------------------------------------
* Date By Description
* -----------------------------------------------------------------------
* 16Aug95 RCS Created.
************************************************************************/
uint RtmkStartTask(PROCESS *process, void (*taskEntry)(void), uint stackSize)
{
uint procMask;
#ifdef __DOS__
char far *stack;
#endif /* __DOS__ */
/* Last task is the kernel task */
if (numProcess > MAX_TASKS - 1)
{
*process = NULL;
return(ERR_MAX_TASKS);
} /* end of if */
*process = &pcsTable[numProcess];
if (taskEntry)
{
#ifdef __DOS__
/* Register application task to kernel */
#if defined __TURBOC__
(*process)->context->j_ip = FP_OFF(taskEntry);
(*process)->context->j_cs = FP_SEG(taskEntry);
(*process)->context->j_flag = 0;
/* Process stack */
stack = (char far *)calloc(stackSize, sizeof(char));
if (stack == NULL)
{
*process = NULL;
return(ERR_STACK);
} /* end of if */
/*
Set up segment registers. By default, the compiler assumes that
SS is equal to DS for small, tiny or medium module. For large,
huge or compact module, DS is not equal to SS.
*/
(*process)->context->j_ss = FP_SEG((void far *)stack);
(*process)->context->j_sp = (uint )stack + stackSize;
(*process)->context->j_bp = (*process)->context->j_sp; /* Assume BP = SP */
/* Set up DS register */
#if defined(__LARGE__) || defined(__HUGE__) || defined(__COMPACT__)
(*process)->context->j_ds = _DS;
#else
(*process)->context->j_ds = (*process)->context->j_ss;
#endif /* __LARGE || __HUGE__ || __COMPACT__ */
/* Set up ES register */
(*process)->context->j_es = _ES;
/* Set up flags register */
(*process)->context->j_flag = _FLAGS;
#elif defined __WATCOMC__
/* Process stack */
stack = (char far *)calloc(stackSize, sizeof(char));
if (stack == NULL)
{
*process = NULL;
return(ERR_STACK);
} /* end of if */
(*process)->context[6] = (uint )stack + stackSize; /* SP */
(*process)->context[5] = (*process)->context[6]; /* BP = SP */
(*process)->context[7] = sysContext[7]; /* ES */
(*process)->context[8] = sysContext[8]; /* DS */
(*process)->context[9] = FP_SEG(taskEntry); /* CS */
(*process)->context[10] = FP_OFF(taskEntry); /* IP */
(*process)->context[12] = FP_SEG((void far *)stack); /* SS */
#endif /* __TURBOC__ else __WATCOMC__ */
#else
/* Allocate stack for application task using target specific compiler */
/* Then set up process context */
#endif /* __DOS__ */
} /* end of if */
(*process)->evWait = 0; /* No waiting events */
(*process)->evReceived = 0; /* No received events */
procMask = READY_MASK >> numProcess; /* Set up task status */
(*process)->procMask = procMask;
(*process)->priority = MAX_TASKS - numProcess;/* Set up priority */
(*process)->msgPending = FALSE; /* No message pending */
(*process)->msgSender = NULL;
numProcess++; /* Update process counter */
DisableInterrupt();
readyProcess |= procMask; /* The process is now ready to take the CPU */
EnableInterrupt();
return(SUCCESSFUL);
} /* RtmkStartTask() */
/************************************************************************
* Function name : Scheduler
* Description : The context of the current process is saved and the
* : system switch to the ready process. If nextProcess
* : is NULL, the higher priority ready process is searched,
* : else the process is the ready process.
* :
* Parameters : nextProcess - Process to be scheduled to
* : ronudRobin - TRUE if manual round robin
* Returns : -
* Author : Richard Shen
* -----------------------------------------------------------------------
* Date By Description
* -----------------------------------------------------------------------
* 16Aug95 RCS Created.
************************************************************************/
void Scheduler(PROCESS nextProcess, BOOLEAN roundRobin)
{
PROCESS highest;
int count;
uint mask;
uint maxPrior;
/* Save the context of current process */
if (!setjmp(curProcess->context))
{
if (nextProcess && roundRobin == FALSE)
curProcess = nextProcess;
else
{
highest = NULL;
while (highest == NULL)
{
mask = READY_MASK;
maxPrior = 0;
for (count = 0; count < MAX_TASKS; count++)
{
if ((mask & readyProcess) != 0)
{
/* Keep searching for highest priority process */
if (maxPrior < pcsTable[count].priority)
{
highest = &pcsTable[count];
maxPrior = highest->priority;
} /* end of if */
} /* end of if */
mask >>= 1;
} /* end of for */
/*
If highest is NULL, no ready task found, just wait.
Some tasks might just wait for a hardware interrupt event.
*/
if (highest)
{
if (highest == curProcess)
{
if ((readyProcess & highest->procMask))
return;
highest = NULL; /* Current task is in wait mode */
continue;
} /* end of if */
curProcess = highest;
} /* end of if */
} /* end of while */
} /* end of else */
longjmp(curProcess->context, 1); /* Switch to the scheduled process */
} /* end of if */
} /* Scheduler() */
/************************************************************************
* Function name : RtmkChangePriority
* Description : Change priority of a task
* :
* Parameters : process - Task control block
* : newPriority - New priority
* Returns : priority changed to, or ERR_TASK_ID if invalid task ID
* Author : Richard Shen
* -----------------------------------------------------------------------
* Date By Description
* -----------------------------------------------------------------------
* 16Aug95 RCS Created.
************************************************************************/
uchar RtmkChangePriority(PROCESS process, uchar newPriority)
{
uchar oldPriority;
oldPriority = process->priority;
process->priority = newPriority;
return(oldPriority);
} /* RtmkChangePriority() */
/************************************************************************
* Function name : RtmkGetPriority
* Description : Get priority of a task
* :
* Parameters : tid - Task control block
* Returns : priority changed to, or ERR_TASK_ID if invalid task ID
* Author : Richard Shen
* -----------------------------------------------------------------------
* Date By Description
* -----------------------------------------------------------------------
* 16Aug95 RCS Created.
************************************************************************/
uchar RtmkGetPriority(PROCESS process)
{
return(process->priority);
} /* RtmkGetPriority() */
/************************************************************************
* Function name : RtmkCurrent
* Description : Get current running process control block
* :
* Parameters : -
* Returns : curProcess
* Author : Richard Shen
* -----------------------------------------------------------------------
* Date By Description
* -----------------------------------------------------------------------
* 22Aug95 RCS Created.
************************************************************************/
PROCESS RtmkCurrent(void)
{
return(curProcess);
} /* RtmkCurrent() */
/************************************************************************
* Function name : EnableInterrupt
* Description : Enables interrupts
* :
* Parameters : -
* Returns : -
* Author : Richard Shen
* ----------------------------------------------------------------------
* Date By Description
* ----------------------------------------------------------------------
* 09Oct95 RCS Created.
************************************************************************/
void EnableInterrupt(void)
{
if (servingInt == 0)
enable();
} /* EnableInterrupt() */
/************************************************************************
* Function name : DisableInterrupt
* Description : Disables interrupts
* :
* Parameters : -
* Returns : -
* Author : Richard Shen
* ----------------------------------------------------------------------
* Date By Description
* ----------------------------------------------------------------------
* 09Oct95 RCS Created.
************************************************************************/
void DisableInterrupt(void)
{
if (servingInt == 0)
disable();
} /* DisableInterrupt() */
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -