📄 task.c
字号:
/******************************************************************************
Copyright (c) 2006 by RockOS.
All rights reserved.
This software is supported by the Rock Software Workroom only.
Any bugs please contact the author with e-mail or QQ:
E-mail : baobaoba520@yahoo.com.cn
QQ : 59681888
*******************************************************************************
File name : task.c
Description : task management in RockOS.
:
:
Auther : sunxinqiu
History :
2006-3-15 first release.
******************************************************************************/
#include "os.h"
/******************************************************************************
Function : HTASK taskCreate (TASK_INFO * pTaskInfo)
Params : pTaskInfo - the detail task information for this task.
:
:
:
Return : the task just created, or NULL_HANDLE if failed.
Description : This function is used to create a new task. In RockOS, the task
: identify should be assigned before the task is create.
******************************************************************************/
HTASK taskCreate (TASK_INFO * pTaskInfo)
{
HTASK task;
char name[MAX_NAME_LEN+1];
OS_ENTER_CRITICAL();
for (task = 0; task < MAX_SYS_TASK; task++)
{
if (g_sysTcb[task].state == OS_TASK_FREE)
{
g_sysTcb[task].state = OS_TASK_READY;
break;
}
}
OS_LEAVE_CRITICAL();
if (task >= MAX_SYS_TASK)
{
OS_error("taskCreate(): too many task in system, create task failed!!!\n");
return NULL_TASK;
}
/* basic task information. */
strncpy (&g_sysTcb[task].name[0], &pTaskInfo->name[0], MAX_NAME_LEN);
g_sysTcb[task].priority = pTaskInfo->priority;
g_sysTcb[task].runningPriority = pTaskInfo->priority;
g_sysTcb[task].delayTicks = 0;
/* task entry and its param. */
g_sysTcb[task].taskEntry = pTaskInfo->taskEntry;
g_sysTcb[task].pData = pTaskInfo->pData;
/* task options. */
g_sysTcb[task].option = pTaskInfo->option;
g_sysTcb[task].lockDepth = 0;
/* task msg queue. */
if (pTaskInfo->msgQSize != 0)
{
sprintf(&name[0], "task %d's msgQ", task);
g_sysTcb[task].hMsgQ = msgQCreate(task, pTaskInfo->msgQSize);
}
else
{
g_sysTcb[task].hMsgQ = NULL_HANDLE;
}
/* task semaphore queue (LIFO). */
if (pTaskInfo->semaQSize != 0)
{
sprintf(&name[0], "task %d's semaQ", task);
g_sysTcb[task].hmutexSemaQ = q_create(OS_QUEUE_LIFO, pTaskInfo->semaQSize, task, &name[0]);
}
else
{
g_sysTcb[task].hmutexSemaQ = NULL_HANDLE;
}
/* now create task stack. */
sprintf(&name[0], "task %d's stack", task);
g_sysTcb[task].stackSize = pTaskInfo->stackSize;
g_sysTcb[task].pStack = memAlloc(g_sysTcb[task].stackSize, task, &name[0]);
if (g_sysTcb[task].pStack == NULL)
{
OS_error("taskCreate(): memory not enough for task [%d]'s stack,total [%d] bytes!!!\n",
task, pTaskInfo->stackSize);
q_destroy(g_sysTcb[task].hmutexSemaQ);
q_destroy(g_sysTcb[task].hMsgQ);
memset (&g_sysTcb[task], 0, sizeof(TCB));
g_sysTcb[task].state = OS_TASK_FREE;
return OS_FAIL;
}
g_sysTcb[task].pSP = taskStackInit(g_sysTcb[task].pStack, g_sysTcb[task].stackSize,
(void *)g_sysTcb[task].taskEntry,
g_sysTcb[task].pData);
/* add this new task to ready task queue. */
OS_ENTER_CRITICAL();
q_add(g_readyTaskQueue, (HANDLE)task, g_sysTcb[task].runningPriority);
OS_LEAVE_CRITICAL();
#if DUMP_TASK_FSM != 0
/* dump the task fsm. */
OS_ENTER_CRITICAL();
taskFsmDump(g_taskFsm, task, OS_TASK_FREE, T_TRIG_CREATE, (void *)taskCreate);
OS_LEAVE_CRITICAL();
#endif
g_sysTcb[task].bFirstRun = OS_TRUE;
g_sysTcb[task].bDeprived = OS_FALSE;
g_sysTcb[task].bWaitTimeout = OS_FALSE;
/* start scheduler. */
OSScheduler();
return task;
}
/******************************************************************************
Function : STATUS taskDelete (HTASK task)
Params : task - the task to be delete.
:
:
:
Return : OS_SUCCESS or OS_FAIL
Description : This function is used to delete the task. It can be called by task
: itself explicitly, or be called by another task. (but it can't be
: called implicitly by the task entry terminate, this work is
: done by taskDeleteSelf()).
******************************************************************************/
STATUS taskDelete (HTASK task)
{
/* params check. */
if (task >= MAX_SYS_TASK)
{
OS_error("taskDelete(): task id [%d] out of range!!!\n", task);
return OS_FAIL;
}
if (g_sysTcb[task].state == OS_TASK_FREE)
{
OS_error("taskDelete(): task [%d] has been deleted before!!!\n", task);
return OS_SUCCESS;
}
#if DUMP_TASK_FSM != 0
/* dump the task fsm. */
OS_ENTER_CRITICAL();
taskFsmDump(g_taskFsm, task, g_sysTcb[task].state, T_TRIG_REMOVE, (void *)taskDelete);
OS_LEAVE_CRITICAL();
#endif
OS_ENTER_CRITICAL();
g_sysTcb[task].state = OS_TASK_REMOVING;
OS_LEAVE_CRITICAL();
if (task == g_runningTask)
{
OSScheduler();
}
return OS_SUCCESS;
}
/******************************************************************************
Function : STATUS taskDeleteSelf ()
Params : N/A
:
:
:
Return : OS_SUCCESS or OS_FAIL
Description : This function is used to delete the task itself, it is called
: implicitly by the task entry terminate.
******************************************************************************/
STATUS taskDeleteSelf ()
{
if (g_runningTask >= MAX_SYS_TASK)
{
OS_error("taskDeleteSelf(): self task id [%d] out of range!!!\n", g_runningTask);
return OS_FAIL;
}
if (g_runningTcb->state == OS_TASK_FREE)
{
OS_error("taskDeleteSelf(): self task [%d] is free!!!\n", g_runningTask);
return OS_FAIL;
}
#if DUMP_TASK_FSM != 0
/* dump the task fsm. */
OS_ENTER_CRITICAL();
taskFsmDump(g_taskFsm, g_runningTask, g_sysTcb[g_runningTask].state, T_TRIG_REMOVE, (void *)taskDeleteSelf);
OS_LEAVE_CRITICAL();
#endif
OS_ENTER_CRITICAL();
g_runningTcb->state = OS_TASK_REMOVING;
OS_LEAVE_CRITICAL();
OSScheduler();
return OS_SUCCESS;
}
/******************************************************************************
Function : STATUS taskRestart(HTASK task)
Params : task - the task.
:
:
:
Return : OS_SUCCESS or OS_FAIL
Description : This function is used to restart the task. It can be called by
: task itself explicitly, or can be called by another task.
******************************************************************************/
STATUS taskRestart(HTASK task)
{
HSEMA hsema;
/* params check. */
if (task >= MAX_SYS_TASK)
{
OS_error("taskRestart(): task id [%d] out of range!!!\n", task);
return OS_FAIL;
}
if (g_sysTcb[task].state == OS_TASK_FREE)
{
OS_error("taskRestart(): task [%d] is free!!!\n", task);
return OS_FAIL;
}
#if DUMP_TASK_FSM != 0
/* dump the task fsm. */
OS_ENTER_CRITICAL();
taskFsmDump(g_taskFsm, task, g_sysTcb[task].state, T_TRIG_RESTART, (void *)taskRestart);
OS_LEAVE_CRITICAL();
#endif
/* free task's semaphores. */
while(q_enum(g_sysTcb[task].hmutexSemaQ, (HANDLE *)&hsema) == OS_SUCCESS)
{
semGive(hsema);
}
/* rebuild the stack to entry state. */
g_sysTcb[task].pSP = taskStackInit(g_sysTcb[task].pStack, g_sysTcb[task].stackSize,
(void *)g_sysTcb[task].taskEntry,
g_sysTcb[task].pData);
/* add this task to ready task queue. */
OS_ENTER_CRITICAL();
q_add(g_readyTaskQueue, (HANDLE)task, g_sysTcb[task].runningPriority);
OS_LEAVE_CRITICAL();
/* start scheduler. */
OSScheduler();
return OS_SUCCESS;
}
/******************************************************************************
Function : STATUS taskDelay(U32 ticks)
Params : task - the task.
: ticks - the task delay ticks.
:
:
Return : OS_SUCCESS or OS_FAIL
Description : delay a task.
:
******************************************************************************/
STATUS taskDelay(U32 ticks)
{
HTASK task;
/* params check. */
task = g_runningTask;
#if DUMP_TASK_FSM != 0
/* dump the task fsm. */
OS_ENTER_CRITICAL();
taskFsmDump(g_taskFsm, task, g_sysTcb[task].state, T_TRIG_DELAY, (void *)taskDelay);
OS_LEAVE_CRITICAL();
#endif
if (ticks == 0)
{
OS_ENTER_CRITICAL();
g_sysTcb[task].state = OS_TASK_READY;
g_sysTcb[task].delayTicks = 0;
q_add(g_readyTaskQueue, (HANDLE)task, g_runningTcb->runningPriority);
OS_LEAVE_CRITICAL();
}
else
{
/* change task to delay state. */
OS_ENTER_CRITICAL();
g_sysTcb[task].state = OS_TASK_DELAY;
g_sysTcb[task].delayTicks = ticks;
OS_LEAVE_CRITICAL();
}
/* run another task. */
OSScheduler();
return OS_SUCCESS;
}
/******************************************************************************
Function : STATUS taskSuspend (HTASK task)
Params : task - the task.
:
:
:
Return : OS_SUCCESS or OS_FAIL
Description : suspend a task. It can be called by task itself or by other
: task.
******************************************************************************/
STATUS taskSuspend (HTASK task)
{
/* params check. */
if (task >= MAX_SYS_TASK)
{
OS_error("taskSuspend(): task id [%d] out of range!!!\n", task);
return OS_FAIL;
}
if (g_sysTcb[task].state == OS_TASK_FREE)
{
OS_error("taskSuspend(): task [%d] is free!!!\n", task);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -