?? task.c
字號:
/**********************************************************************************
* task.c
* coded by hspark@ce.cnu.ac.kr
* date : 2001/06/23
* modified by hjahn@ce.cnu.ac.kr
* date : 2003/03/03
**********************************************************************************/
#include "kernel\\mk_sys.h"
#include "kernel\\mk_task.h"
#include "kernel\\mk_hisr.h"
#include "kernel\\mk_ddi.h"
#include "kernel\\mk_sem.h"
#include "kernel\\mk_mem.h"
#include "kernel\\mk_event.h"
void *MK_System_Stack;
static unsigned char MK_ReadyGroup;
static unsigned char MK_ReadyMiddleGroup[4];
static unsigned char MK_ReadyTable[4][8];
MK_TASK *MK_pTaskReadyListHead[MK_TASK_MAX_PRIORITY+1];
MK_TASK *MK_pTaskReadyListTail[MK_TASK_MAX_PRIORITY+1];
MK_TASK *MK_pTaskListHead, *MK_pTaskListTail;
MK_TASK *MK_pTaskDelayedListHead;
MK_TASK *MK_pCurrentTask;
static int MK_CountNesting;
static UCHAR MK_TotalTasks;
static UCHAR MK_ContextSwitchFlags;
static UCHAR MK_SchedulePolicy;
static unsigned char const MK_MapTable[] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80};
static unsigned char const MK_UnMapTable[] = {
0, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0
};
MK_TASK MK_IdleTask;
//static UINT MK_IdleTaskStack[1024]; /* Word aligned 4096 Byte */
#define IdleTask_StackSize 1024
static ULONG MK_IdleTaskStack[IdleTask_StackSize]; //1024*2]; /* Word aligned 4096 Byte */
//extern MK_EnterIRQ(void);
static VOID
MK_IdleTaskFunction(ULONG Arg1, VOID *Arg2)
{
volatile INT i=0;
while(1)
{
i++;
//MK_Printf("i");
#if 0 /*for interrupt test*/
MK_EnterIRQ();
MK_IntEnter();
MK_TimeTick();
MK_IntExit();
//MK_InfoPrintf(MK_TASK_WARNING, "-");
#endif
}
}
VOID
MK_TaskInitialize(VOID)
{
INT i,j;
MK_ReadyGroup = 0;
for(i=0; i<4 ;i++)
{
MK_ReadyMiddleGroup[i] = 0;
}
for(i=0; i<4; i++)
{
for(j=0; j<8; j++)
{
MK_ReadyTable[i][j] = 0;
}
}
MK_pTaskListHead = MK_NULL;
MK_pTaskListTail = MK_NULL;
for(i=0; i<MK_TASK_MAX_PRIORITY+1; i++)
{
MK_pTaskReadyListHead[i] = MK_NULL;
MK_pTaskReadyListTail[i] = MK_NULL;
}
MK_pTaskDelayedListHead = MK_NULL;
MK_pCurrentTask = MK_NULL;
/* Re-Initialize Global Varialbes for Save */
MK_TotalTasks = 0;
MK_CountNesting = 0;
MK_ContextSwitchFlags = FALSE;
MK_SchedulePolicy = MK_TASK_RR;
MK_CreateTask(&MK_IdleTask, MK_IdleTaskFunction, MK_TASK_MAX_PRIORITY,
"IdleTask", MK_DEFAULT_TIMESLICE, (CHAR *)MK_IdleTaskStack, IdleTask_StackSize*4/* 4096*2*/, 0, 0);
MK_Resume(&MK_IdleTask);
}
VOID
MK_Start(VOID)
{
MK_TASK *pTask;
INT Flags;
INT Priority;
Flags = MK_InterruptDisable(); /* Critical Region */
if(MK_ContextSwitchFlags == FALSE)
{
Priority = MK_GetHighPriority();
pTask = MK_pTaskReadyListHead[Priority];
MK_pCurrentTask = pTask;
MK_ContextSwitchEnable();
MK_StartHighPriorityTask(&pTask->t_CurrentOfStack);
}
MK_InterruptRestore(Flags); /* Never reach this line */
}
VOID
MK_TaskMagicCheck( MK_TASK *pTask, CHAR *argv)
{
INT Flags;
Flags = MK_InterruptDisable();
if( (pTask->t_Magic != MK_TASK_MAGIC) && (pTask->t_Magic != MK_HISR_MAGIC) )
{
#if MK_DEBUG_PRINT
MK_Panic("Magic Error_%s\n", argv);
#endif
}
MK_InterruptRestore( Flags );
}
VOID
MK_Schedule(VOID)
{
MK_TASK *pOldTask, *pNewTask;
INT Flags;
int Priority;
MK_HISR *pHisr;
Flags = MK_InterruptDisable();
if(MK_ContextSwitchFlags == TRUE)
{
pHisr = MK_NULL;
for (Priority=0; Priority<MK_HISR_MAX_PRIORITY+1; Priority++)
{
if (MK_pActiveHISRListHead[Priority])
{
pHisr = MK_pActiveHISRListHead[Priority];
break;
}
}
if(pHisr != MK_NULL)
{
if(pHisr != (MK_HISR *)MK_pCurrentTask)
{
pOldTask = MK_pCurrentTask;
pNewTask = (MK_TASK *)pHisr;
MK_pCurrentTask = pNewTask;
MK_ContextSwitch(&pOldTask->t_CurrentOfStack,
&pNewTask->t_CurrentOfStack);
}
}
/* context switch from hisr to task, when all HISR is finished. */
else if(MK_pCurrentTask->t_Magic == MK_HISR_MAGIC)
{
pOldTask = MK_pCurrentTask;
Priority = MK_GetHighPriority();
pNewTask = MK_pTaskReadyListHead[Priority];
MK_pCurrentTask = pNewTask;
MK_ContextSwitch(&pOldTask->t_CurrentOfStack,
&pNewTask->t_CurrentOfStack);
}
else /* Normal Task Schedule */
{
pOldTask = MK_pCurrentTask;
Priority = MK_GetHighPriority();
if(!(pOldTask->t_Status & MK_TASK_READY) || (Priority != pOldTask->t_Priority))
{
pNewTask = MK_pTaskReadyListHead[Priority];
MK_pCurrentTask = pNewTask;
//#if MK_DEBUG
// MK_TaskMagicCheck( MK_pCurrentTask, "S2");
//#endif
MK_ContextSwitch(&pOldTask->t_CurrentOfStack,
&pNewTask->t_CurrentOfStack);
//#if MK_DEBUG
// MK_TaskMagicCheck( MK_pCurrentTask, "S3");
//#endif
}
Priority = MK_GetPriority( MK_pCurrentTask );
if(MK_pTaskReadyListHead[Priority] != MK_pTaskReadyListTail[Priority])
{
/* When more than 2 Task exist */
if(pOldTask->t_RemainedTimeSlice <= 0)
{
pNewTask = pOldTask->t_pTaskReadyNext;
pNewTask->t_pTaskReadyPrev = MK_NULL;
MK_pTaskReadyListHead[Priority] = pNewTask;
pOldTask->t_pTaskReadyPrev = MK_pTaskReadyListTail[Priority];
pOldTask->t_pTaskReadyNext = MK_NULL;
MK_pTaskReadyListTail[Priority]->t_pTaskReadyNext = pOldTask;
MK_pTaskReadyListTail[Priority] = pOldTask;
pOldTask->t_RemainedTimeSlice = pOldTask->t_TimeSlice;
MK_pCurrentTask = pNewTask;
//#if MK_DEBUG
// MK_TaskMagicCheck( MK_pCurrentTask, "S4");
//#endif
MK_ContextSwitch(&pOldTask->t_CurrentOfStack,
&pNewTask->t_CurrentOfStack);
//#if MK_DEBUG
// MK_TaskMagicCheck( MK_pCurrentTask, "S5");
//#endif
}
}
else /* When Only One Task exists */
{
pOldTask->t_RemainedTimeSlice = pOldTask->t_TimeSlice;
}
}
}
MK_InterruptRestore(Flags);
}
INT
MK_ChangePriority(MK_TASK *pTask, INT NewPrio)
{
MK_PENDING_LIST *pPendingList;
INT Priority;
INT Flags;
if (pTask == MK_NULL)
{
#if MK_DEBUG_PRINT
MK_InfoPrintf(MK_TASK_WARNING, "MK_ChangePriority() - Task for change priority doesn't exist! Task(%s)\n", MK_pCurrentTask->t_pName);
#endif
return MK_ERROR;
}
if(pTask->t_Magic != MK_TASK_MAGIC)
{
#if MK_DEBUG_PRINT
MK_Panic("MK_ChangePriority() - Magic error!\n");
#endif
return MK_RESOURCE_ERROR;
}
if(NewPrio < MK_TASK_MIN_PRIORITY || NewPrio > MK_TASK_MAX_PRIORITY)
{
#if MK_DEBUG_PRINT
MK_InfoPrintf(MK_TASK_WARNING, "MK_ChangePriority() - Task priority get out of range! Task(%s)\n", MK_pCurrentTask->t_pName);
#endif
return MK_ERROR;
}
Flags = MK_InterruptDisable(); /* Critical Region */
Priority = pTask->t_Priority;
if(Priority == Idle_Task)
{
#if MK_DEBUG_PRINT
MK_InfoPrintf(MK_TASK_WARNING, "MK_ChangePriority() - Task priority doesn't change into 255(reserved IDLE Task)! Task(%s)\n", MK_pCurrentTask->t_pName);
#endif
MK_InterruptRestore(Flags);
return MK_ERROR;
}
if(pTask->t_Status & MK_TASK_READY)
{
MK_DeleteTaskFromReadyList(pTask);
pTask->t_Priority = NewPrio;
MK_InsertTaskToReadyList(pTask);
MK_Schedule();
}
else
/* when signaled, can both SLEEP, PENDING */
{
pTask->t_Priority = NewPrio;
pPendingList = (MK_PENDING_LIST *)pTask->t_PendingList;
if(pPendingList->p_Options == MK_SERVICE_PRIORITY)
{
MK_DeleteTaskFromPendingList(pPendingList, pTask);
MK_InsertTaskToPendingList(pPendingList, pTask);
}
}
MK_InterruptRestore(Flags);
return Priority;
}
INT
MK_GetPriority(MK_TASK *pTask)
{
if (pTask == MK_NULL)
{
#if MK_DEBUG_PRINT
MK_InfoPrintf(MK_TASK_WARNING, "MK_GetTaskName() - Task doesn't exist! Task(%s)\n", MK_pCurrentTask->t_pName);
#endif
return MK_ERROR;
}
if(pTask->t_Magic != MK_TASK_MAGIC)
{
#if MK_DEBUG_PRINT
MK_Panic("MK_GetPriority() - Magic error!\n");
#endif
return MK_RESOURCE_ERROR;
}
return pTask->t_Priority;
}
CHAR *MK_GetTaskName(MK_TASK *pTask)
{
if (pTask == MK_NULL)
{
#if MK_DEBUG_PRINT
MK_InfoPrintf(MK_TASK_WARNING, "MK_GetTaskName() - Task doesn't exist! Task(%s)\n", MK_pCurrentTask->t_pName);
#endif
return MK_NULL;
}
if(pTask->t_Magic != MK_TASK_MAGIC)
{
#if MK_DEBUG_PRINT
MK_Panic("MK_GetTaskName() - Magic error!\n");
#endif
return MK_NULL;
}
return (CHAR *)pTask->t_pName;
}
MK_TASK *
MK_GetCurrentTask(VOID)
{
MK_TASK *MK_pTask;
int Flags;
Flags = MK_InterruptDisable();
MK_pTask = MK_pCurrentTask;
MK_InterruptRestore(Flags);
return MK_pTask;
}
UINT
MK_GetCurrentTaskStackPointer(VOID)
{
return MK_pCurrentTask->t_CurrentOfStack;
}
/* Coded by hjahn */
LONG
MK_ChangeTimeSlice(MK_TASK *pTask, LONG newTimeSlice)
{
LONG oldTimeSlice;
INT Flags;
if (pTask == MK_NULL)
{
#if MK_DEBUG_PRINT
MK_InfoPrintf(MK_TASK_WARNING, "MK_GetTaskName() - Task doesn't exist! Task(%s)\n", MK_pCurrentTask->t_pName);
#endif
return MK_ERROR;
}
if(pTask->t_Magic != MK_TASK_MAGIC)
{
#if MK_DEBUG_PRINT
MK_Panic("MK_ChangeTimeSlice() - Magic error!\n");
#endif
return MK_RESOURCE_ERROR;
}
if(newTimeSlice <= 0)
{
#if MK_DEBUG_PRINT
MK_InfoPrintf(MK_TASK_WARNING, "MK_ChangeTimeSlice() - Task's TimeSlice get out of range! Task(%s)\n", MK_pCurrentTask->t_pName);
#endif
return MK_ERROR;
}
Flags = MK_InterruptDisable(); /* Critical Region */
oldTimeSlice = pTask->t_TimeSlice;
pTask->t_TimeSlice = newTimeSlice;
pTask->t_RemainedTimeSlice = newTimeSlice;
pTask->t_UsedTimeSlice = 0;
MK_InterruptRestore(Flags);
return oldTimeSlice;
}
INT
MK_GetTotalTasks(VOID)
{
return MK_TotalTasks;
}
VOID
MK_AddTotalTasks(VOID)
{
MK_TotalTasks++;
}
VOID
MK_DelTotalTasks(VOID)
{
MK_TotalTasks--;
}
/* coded by hjahn - end */
STATUS
MK_InsertTaskToReadyList(MK_TASK *pTask)
{
INT Flags;
INT Priority;
INT GroupValue, MiddleGroupValue, TableValue;
if (pTask == MK_NULL)
{
#if MK_DEBUG_PRINT
MK_InfoPrintf(MK_TASK_WARNING, "MK_GetTaskName() - Task doesn't exist! Task(%s)\n", MK_pCurrentTask->t_pName);
#endif
return MK_ERROR;
}
if(pTask->t_Magic == MK_HISR_MAGIC)
{
#if MK_DEBUG_PRINT
MK_Panic("MK_InsertTaskToReadyList() - Hisr is inserted but, error!\n");
#endif
return MK_RESOURCE_ERROR;
}
if(pTask->t_Magic != MK_TASK_MAGIC)
{
#if MK_DEBUG_PRINT
MK_Panic("MK_InsertTaskToReadyList() - Magic error!\n");
#endif
return MK_RESOURCE_ERROR;
}
if(pTask->t_Status & MK_TASK_READY)
{
#if MK_DEBUG_PRINT
//MK_InfoPrintf(MK_TASK_WARNING, "MK_InsertTaskToReadyList() - READY status task should changed READY status! Task(%s)\n", MK_pCurrentTask->t_pName);
#endif
return MK_ERROR;
}
Flags = MK_InterruptDisable(); /* Critical Region */
Priority = pTask->t_Priority;
/* Insert Task to READY List */
if(MK_pTaskReadyListTail[Priority] == MK_NULL)
{
pTask->t_pTaskReadyNext = MK_NULL;
pTask->t_pTaskReadyPrev = MK_NULL;
MK_pTaskReadyListHead[Priority] = pTask;
MK_pTaskReadyListTail[Priority] = pTask;
/* modify Ready Group, MiddleGroup, Table */
GroupValue = Priority & 0x000000C0; /* 7bit ~ 8bit */
MiddleGroupValue = Priority & 0x00000038; /* 3bit ~ 6bit */
TableValue = Priority & 0x00000007; /* 0bit ~ 2bit */
MK_ReadyGroup |= MK_MapTable[GroupValue>>6];
MK_ReadyMiddleGroup[GroupValue>>6] |= MK_MapTable[MiddleGroupValue>>3];
MK_ReadyTable[GroupValue>>6][MiddleGroupValue>>3] |= MK_MapTable[TableValue];
}
else
{
pTask->t_pTaskReadyNext = MK_NULL;
pTask->t_pTaskReadyPrev = MK_pTaskReadyListTail[Priority];
MK_pTaskReadyListTail[Priority]->t_pTaskReadyNext = pTask;
MK_pTaskReadyListTail[Priority] = pTask;
}
pTask->t_Status |= MK_TASK_READY;
MK_InterruptRestore(Flags);
return MK_NO_ERROR;
}
STATUS
MK_DeleteTaskFromReadyList(MK_TASK *pTask)
{
INT Flags;
INT Priority;
INT GroupValue, MiddleGroupValue, TableValue;
if (pTask == MK_NULL)
{
#if MK_DEBUG_PRINT
MK_InfoPrintf(MK_TASK_WARNING, "MK_GetTaskName() - Task doesn't exist! Task(%s)\n", MK_pCurrentTask->t_pName);
#endif
return MK_ERROR;
}
if(pTask->t_Magic != MK_TASK_MAGIC)
{
#if MK_DEBUG_PRINT
MK_Panic("MK_DeleteTaskFromReadyList() - Magic error!\n");
#endif
return MK_RESOURCE_ERROR;
}
if( !(pTask->t_Status & MK_TASK_READY) )
{
#if MK_DEBUG_PRINT
//MK_InfoPrintf(MK_TASK_WARNING, "MK_DeleteTaskFromReadyList() - task Deleting from READY list is not READY status! Task(%s)\n", MK_pCurrentTask->t_pName);
#endif
return MK_ERROR;
}
Flags = MK_InterruptDisable(); /* Critical Region */
Priority = pTask->t_Priority;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -