📄 skp.c
字号:
/************************************************************************/
/* */
/* Copyright 1990-1992 by Accelerated Technology */
/* */
/* PROPRIETARY RIGHTS of Accelerated Technology are involved in the */
/* subject matter of this material. All manufacturing, reproduction, */
/* use, and sales rights pertaining to this subject matter are */
/* governed by the license agreement. The buyer or recipient of this */
/* package, implicitly accepts the terms of the license. */
/* */
/************************************************************************/
/************************************************************************/
/* */
/* FILE DESCRIPTION */
/* */
/* This file contains routines that coordinate the execution of */
/* competing application tasks. These routines are designed to */
/* be invoked through other nucleus executive routines. */
/* */
/* ROUTINES */
/* */
/* SKP_Initialize Scheduler Initialization */
/* SKP_Schedule Schedule tasks from the */
/* ready list */
/* SKP_Ready_Task Place task on ready list */
/* SKP_Suspend_Task Unconditionally suspends */
/* the task */
/* SKP_Move_To_End Place task at end of ready */
/* tasks of same priority */
/* SKP_Reset_Task Start task at beginning of */
/* its execution */
/* SKP_Maximum_Tasks Return the total number of */
/* tasks to the caller */
/* SKP_Set_Task_Priority Set task priority */
/* SKP_Get_Task_ID Get currently running ID */
/* SKP_Preemption Set/Clear the Preempt flag */
/* SKP_Set_Time_Slice Modify the task's time slice*/
/* SKP_Time_Slice Process a time slice */
/* SKP_Retrieve_Status Retrieve task status */
/* */
/* NOTES */
/* */
/* All routines except SKP_Set_Task_Priority, SKP_Get_Task_ID, */
/* SKP_Maximum_Tasks, and SKP_Retrieve_Status must have interrupts */
/* locked out prior to invocation. */
/* */
/************************************************************************/
/* Define necessary include files. */
#include "nu_defs.h" /* General constants */
#include "in_extr.h" /* Initialize references */
#include "sk_defs.h" /* Data structure defns */
#include "sk_extr.h" /* Scheduler routine defs */
#include "cl_extr.h" /* Clock routine defs */
/* Determine whether or not to bring in the Development Support component
external references. */
#if defined(NU_ENABLE_TIMING) || defined(NU_ENABLE_HISTORY)
#include "ds_extr.h"
#endif
/* Define global data structures to the scheduler. */
/* The pointer "SKP_TCB_List" is used to point to the list of
sequentially allocated TCBs. */
struct SK_TASK_CONTROL_BLOCK_STRUCT *SKP_TCB_List;
/* The pointer "SKP_Ready_List_Ptr" is used to point to the chain of ready
TCBs. If this pointer is NULL, there are no tasks ready for execution. */
struct SK_TASK_CONTROL_BLOCK_STRUCT *SKP_Ready_List_Ptr;
/* The pointer "SKP_Current_TCB_Ptr" is used to point to the currently
executing TCB. If this pointer is NULL, no task is executing. Note
that this pointer is modified by SKD routines. */
struct SK_TASK_CONTROL_BLOCK_STRUCT *SKP_Current_TCB_Ptr;
/* The signed variable "SKP_Current_Task_ID" contains the ID of the task
currently executing or the value assigned to NO_TASKS. */
signed int SKP_Current_Task_ID;
/* The signed variable "SKP_Total_Tasks" contains the total number of
tasks, as derived from the task definition list. */
signed int SKP_Total_Tasks;
/* Need to have a flag that temporarily disables performance timer setting
during the intitialization process. This is important since the DS
component's intialization has not been done yet! */
int SKP_In_Init;
/************************************************************************/
/* */
/* FUNCTION "SKP_Initialize" */
/* */
/* */
/* DESCRIPTION */
/* */
/* This function is used to allocate and initialize all of the */
/* task control blocks, task stacks, and various other data */
/* structures pertinent to scheduling tasks. */
/* */
/* AUTHOR */
/* */
/* William E. Lamie, Accelerated Technology */
/* */
/* CALLED FROM */
/* */
/* INP_Initialize High level initialization */
/* */
/* ROUTINES CALLED */
/* */
/* SKD_Init_Stack Initialize the appl stack */
/* INP_Memory_Alloc Allocate initial memory */
/* IND_Major_System_Error Error handling routine */
/* */
/* INPUTS */
/* */
/* IN_System_Tasks Task definition structure */
/* */
/* OUTPUTS */
/* */
/* SKP_TCB_List[] Task Control Blocks */
/* SKP_Ready_List_Ptr Ready list pointer */
/* SKP_Current_Task_ID Currently executing task ID */
/* SKP_Current_TCB_Ptr Currently executing TCB ptr */
/* */
/************************************************************************/
void SKP_Initialize(struct IN_TASK_DEFINITION_STRUCT *task_list)
{
int i; /* Working variable */
int bytes; /* Number of bytes to alloc */
/* Initialize the main scheduler variables. */
SKP_Total_Tasks = 0; /* Initially, no tasks */
SKP_Current_Task_ID = NU_SYSTEM; /* In system mode */
SKP_Ready_List_Ptr = NU_NULL; /* No tasks are ready */
SKP_Current_TCB_Ptr = NU_NULL; /* No task is running yet */
/* Figure out how many tasks are in the system. */
while (task_list[SKP_Total_Tasks].in_task_addr != END_OF_LIST)
{
/* Increment the total task count. */
SKP_Total_Tasks++;
}
/* Make sure there is at least one task. */
if (SKP_Total_Tasks <= 0)
IND_Major_System_Error(NU_NO_TASKS);
/* Allocate memory for all of the TCBs. */
bytes = sizeof(struct SK_TASK_CONTROL_BLOCK_STRUCT) * SKP_Total_Tasks;
SKP_TCB_List = (struct SK_TASK_CONTROL_BLOCK_STRUCT *)
INP_Memory_Alloc(bytes);
/* Indicate that task initialization is in progress. */
SKP_In_Init = NU_TRUE;
/* Initialize each task's TCB. This includes allocation of the task
stack. */
for (i = 0; i < SKP_Total_Tasks; i++)
{
/* Initialize the TCB entry. */
SKP_TCB_List[i].sk_task_id = i;
SKP_TCB_List[i].sk_priority = task_list[i].in_task_priority;
SKP_TCB_List[i].sk_suspend = NU_PURE_SUSPEND;
SKP_TCB_List[i].sk_scheduled = 0;
SKP_TCB_List[i].sk_nu_1 = 0xFF;
SKP_TCB_List[i].sk_nu_2 = 0xFF;
SKP_TCB_List[i].sk_task_addr = task_list[i].in_task_addr;
/* If the no preempt flag is set, set the preempt counter to 1. */
if (task_list[i].in_no_preempt)
SKP_TCB_List[i].sk_no_preempt = 1;
else
SKP_TCB_List[i].sk_no_preempt = 0;
/* Store off this task's initial time slice. */
SKP_TCB_List[i].sk_time_slice = task_list[i].in_time_slice;
/* Allocate the space for the stack. Note that the size is in terms
of unsigned variables. Also, allocate another unsigned word after
the stack to place a pattern in. Each time the task is resumed
check for this value. If it is not the pattern, someone has
slicked at least part of the task's stack. */
bytes = task_list[i].in_stack_size * sizeof(unsigned int);
SKP_TCB_List[i].sk_stack_size = task_list[i].in_stack_size;
SKP_TCB_List[i].sk_stack_base =
(unsigned int) INP_Memory_Alloc(bytes);
SKP_TCB_List[i].sk_stack_fence=
(unsigned int *) INP_Memory_Alloc(sizeof(unsigned int));
*SKP_TCB_List[i].sk_stack_fence= SK_STACK_PROTECT;
SKP_TCB_List[i].sk_ready_prev = NU_NULL;
SKP_TCB_List[i].sk_ready_next = NU_NULL;
/* Call "SKD_Init_Stack" to initialize the stack for this task. */
SKD_Init_Stack(&SKP_TCB_List[i]);
/* Call "SKD_Ready_Task" if this task is designated as an automatic
start task. */
if (task_list[i].in_auto_start)
{
/* Place this task on the ready list. */
SKP_Ready_Task(i);
}
}
/* Indicate that task initialization is over. */
SKP_In_Init = NU_FALSE;
} /* end of SKP_Initialize */
/************************************************************************/
/* */
/* FUNCTION "SKP_Schedule" */
/* */
/* */
/* DESCRIPTION */
/* */
/* This function continually monitors the ready list pointer for */
/* a value other than NULL. When one is found, the task */
/* associated with the first TCB on the list is started. */
/* */
/* AUTHOR */
/* */
/* William E. Lamie, Accelerated Technology */
/* */
/* CALLED FROM */
/* */
/* INP_Initialize High level initialization */
/* */
/* ROUTINES CALLED */
/* */
/* IND_Set_Interrupt_Level Turn interrupts on/off */
/* SKD_Control_To_Task Transfer control to task */
/* */
/* INPUTS */
/* */
/* SKP_Ready_List_Ptr Highest priority TCB ready */
/* */
/* OUTPUTS */
/* */
/* Task given control */
/* */
/************************************************************************/
/* This routine is optimized in assembly language, see SKD.S */
/* void SKP_Schedule() */
/* { */
/* void SKD_Control_To_Task(); */ /* Transfer control to task */
/* Enable interrupts for the scheduling loop. */
/* IND_Set_Interrupt_Level(NU_ENABLE_INTERRUPTS); */
/* This is the main execution loop of nucleus. */
/* while (NU_FOREVER) */
/* { */
/* Determine if there is anything to do. */
/* if (SKP_Ready_List_Ptr) */
/* { */
/* Disable interrupts in preparation to transfer execution to
the task. */
/* IND_Set_Interrupt_Level(NU_DISABLE_INTERRUPTS); */
/* Transfer control to the application task. */
/* SKD_Control_To_Task(SKP_Ready_List_Ptr); */
/* Enable interrupts while in the main scheduling loop. */
/* IND_Set_Interrupt_Level(NU_ENABLE_INTERRUPTS); */
/* } */
/* } */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -