📄 core.c
字号:
if ((g_cpuIntDepth == 0)&&(g_OSRunning == OS_PHASE_SCHEDULING))
{
enable_irq();
}
}
/******************************************************************************
Function : void OSStartScheduler(void)
Params : N/A
:
:
:
Return : N/A
Description : bring the system to multi-task mode.
:
******************************************************************************/
void OSStartScheduler()
{
/* no task is running now. */
g_runningTask = NULL_TASK;
g_runningTcb = NULL;
g_newTask = NULL_TASK;
g_newTcb = NULL;
/* run the first ready task(should be tick task.)*/
if (q_enum(g_readyTaskQueue, (HANDLE *)&g_runningTask)== OS_FAIL)
{
OS_error("OSStartScheduler(): no ready task when system starting up!!!\n");
return;
}
taskFsmDump(g_taskFsm, g_runningTask, OS_TASK_READY, T_TRIG_FIRST_RUN, NULL);
g_runningTcb = &g_sysTcb[g_runningTask];
g_runningTcb->state = OS_TASK_RUNNING;
/* enter multi-task mode. */
g_OSRunning = OS_PHASE_SCHEDULING;
enable_watchdog();
OSRunTask();
}
/******************************************************************************
Function : void OSScheduler()
Params : N/A
:
:
:
Return : N/A
Description : the main scheduler for RockOS.
:
******************************************************************************/
void OSScheduler()
{
HTASK newTask;
/* check system running state and CPU interrupt nest depth. */
if ((g_cpuIntDepth > 0)||(g_OSRunning != OS_PHASE_SCHEDULING))
{
return;
}
/* run the next highest priority task. */
OS_ENTER_CRITICAL();
if (q_head(g_readyTaskQueue, (HANDLE *)&newTask) == OS_SUCCESS)
{
if ((g_sysTcb[newTask].runningPriority < g_runningTcb->runningPriority)
||(g_runningTcb->state != OS_TASK_RUNNING))
{
/* delete this task from ready queue. */
q_enum(g_readyTaskQueue, NULL);
/* set a trigger to old task. */
if (g_runningTcb->state == OS_TASK_RUNNING)
{
taskSetTrigger(g_runningTask, T_TRIG_DEPRIVED, NULL);
}
/* switch task context. */
g_newTask = newTask;
g_newTcb = &g_sysTcb[newTask];
g_newTcb->state = OS_TASK_RUNNING;
if (g_newTcb->bDeprived == OS_TRUE)
{
taskFsmDump(g_taskFsm, g_newTask, OS_TASK_READY, T_TRIG_RESUME, NULL);
g_newTcb->bDeprived = OS_FALSE;
}
else if (g_newTcb->bFirstRun == OS_TRUE)
{
taskFsmDump(g_taskFsm, g_newTask, OS_TASK_READY, T_TRIG_FIRST_RUN, NULL);
g_newTcb->bFirstRun = OS_FALSE;
}
OSSwTask();
}
}
OS_LEAVE_CRITICAL();
}
/******************************************************************************
Function : void OSTickCore(U32 ticks)
Params : ticks - the timer ticks passing
:
:
:
Return : N/A
Description : This is the tick task handler for core.
:
******************************************************************************/
void OSTickCore(U32 ticks)
{
HTASK task;
HSEMA hsema;
HQUEUE hsemaq;
HMSGQ hmsgq;
HMSG hmsg;
U32 head;
/* update tasks' state. */
for (task = 0; task < MAX_SYS_TASK; task++)
{
switch(g_sysTcb[task].state)
{
case OS_TASK_DELAY:
if (g_sysTcb[task].delayTicks != OS_WAIT_FOR_EVER)
{
if (g_sysTcb[task].delayTicks <= ticks)
{
g_sysTcb[task].delayTicks = 0;
taskSetTrigger(task, T_TRIG_DELAY_TMO, NULL);
}
else
{
g_sysTcb[task].delayTicks -= ticks;
}
}
break;
case OS_TASK_PEND_ON_SEMA:
if (g_sysTcb[task].delayTicks != OS_WAIT_FOR_EVER)
{
if (g_sysTcb[task].delayTicks <= ticks)
{
/* remove it from the semaphore's pend task queue. */
hsema = (HSEMA)g_sysTcb[task].hPend;
if (hsema < MAX_SYS_SEMA)
{
q_del(g_semaCB[hsema].pendTaskQ, (HANDLE)task);
}
g_sysTcb[task].delayTicks = 0;
taskSetTrigger(task, T_TRIG_DELAY_TMO, NULL);
}
else
{
g_sysTcb[task].delayTicks -= ticks;
}
}
break;
case OS_TASK_PEND_ON_MSGQ_R:
if (g_sysTcb[task].delayTicks != OS_WAIT_FOR_EVER)
{
if (g_sysTcb[task].delayTicks <= ticks)
{
g_sysTcb[task].delayTicks = 0;
taskSetTrigger(task, T_TRIG_DELAY_TMO, NULL);
}
else
{
g_sysTcb[task].delayTicks -= ticks;
}
}
break;
case OS_TASK_PEND_ON_MSGQ_S:
if (g_sysTcb[task].delayTicks != OS_WAIT_FOR_EVER)
{
if (g_sysTcb[task].delayTicks <= ticks)
{
/* remove it from the msg queue's pend task queue. */
hmsgq = (HMSGQ)g_sysTcb[task].hPend;
if (g_msgQCB[hmsgq].pendTaskQ < MAX_SYS_MSGQ)
{
q_del(g_msgQCB[hmsgq].pendTaskQ, (HANDLE)task);
}
g_sysTcb[task].delayTicks = 0;
taskSetTrigger(task, T_TRIG_DELAY_TMO, NULL);
}
else
{
g_sysTcb[task].delayTicks -= ticks;
}
}
break;
case OS_TASK_SUSPEND:
if ((g_sysTcb[task].suspendState == OS_TASK_DELAY)
||(g_sysTcb[task].suspendState == OS_TASK_PEND_ON_SEMA)
||(g_sysTcb[task].suspendState == OS_TASK_PEND_ON_MSGQ_R)
||(g_sysTcb[task].suspendState == OS_TASK_PEND_ON_MSGQ_S))
{
if (g_sysTcb[task].delayTicks != OS_WAIT_FOR_EVER)
{
if (g_sysTcb[task].delayTicks <= ticks)
{
taskSetTrigger(task, T_TRIG_DELAY_TMO, NULL);
}
else
{
g_sysTcb[task].delayTicks -= ticks;
}
}
}
break;
case OS_TASK_REMOVING:
/* free task's semaphores and release the queue. */
if (g_sysTcb[task].hmutexSemaQ != NULL_QUEUE)
{
hsemaq = g_sysTcb[task].hmutexSemaQ;
while(q_enum(hsemaq, (HANDLE *)&hsema) == OS_SUCCESS)
{
semGive(hsema);
}
/* now release the queue. */
q_destroy(hsemaq);
}
/* clear all msg packet in task's msg queue and free msg queue. */
if (g_sysTcb[task].hMsgQ != NULL_MSGQ)
{
hmsgq = g_sysTcb[task].hMsgQ;
while(g_msgQCB[hmsgq].current != 0)
{
head = g_msgQCB[hmsgq].head;
hmsg = g_msgQCB[hmsgq].pBuffer[head];
g_msgQCB[hmsgq].head = (head+1)%g_msgQCB[hmsgq].total;
g_msgQCB[hmsgq].current--;
msgFree(hmsg);
}
/* free task's msg queue now. */
q_destroy(g_sysTcb[task].hMsgQ);
}
/* free task's stack. */
memFree(g_sysTcb[task].pStack);
/* free the TCB. */
memset (&g_sysTcb[task], 0, sizeof(TCB));
g_sysTcb[task].state = OS_TASK_FREE;
break;
default:
break;
}
}
}
/******************************************************************************
Function : void taskFsmDump ()
Params : hFsm - should be g_taskFsm
: hInst - the task
: oldState - the task's old state
: event - the task's fsm trig
: action - the action for (oldState-event)
Return : N/A
Description : dump function for task fsm.
: PLS DON'T CALL OS_error() and OS_printf() in this function.
******************************************************************************/
void taskFsmDump (HFSM hFsm, HANDLE hInst, U16 oldState, U16 event, void *action)
{
#if DUMP_TASK_FSM != 0
char szstring[1024];
if ((hFsm != g_taskFsm)||(hInst >= MAX_SYS_TASK))
{
return;
}
if ((oldState >= OS_TASK_STATE_MAX)||(event >= T_TRIG_MAX))
{
return;
}
if (hInst >= 3)
{
memset(&szstring[0], 0, 1024);
sprintf (&szstring[0], "[Task %d:%s] : [%d:%s] + [%d:%s] = [0x%08x:%s]\n",
hInst, taskName((HTASK)hInst),
oldState, &g_taskState[oldState].name[0],
event, &g_taskEvent[event].name[0],
(U32)action, getTaskActionName(action));
BSP_putstring(szstring);
}
#endif
}
/******************************************************************************
Function : char * getTaskActionName (void * p)
Params : p - the function entry
:
:
:
Return : the function name.
Description : called by taskFsmDump(), to get the task fsm's action name.
:
******************************************************************************/
char * getTaskActionName (void * p)
{
U32 next;
U32 head, tail;
char * pname;
/* the next statements are a devide search algrithm. */
head = 0;
tail = sizeof(g_taskAction)/sizeof(FSM_NAME_TBL) - 1;
pname = NULL;
while (head <= tail)
{
next = (head + tail)/2;
if ((U32)p == g_taskAction[next].value)
{
pname = &g_taskAction[next].name[0];
break;
}
else if ((U32)p < g_taskAction[next].value)
{
tail = next - 1;
}
else if ((U32)p > g_taskAction[next].value)
{
head = next + 1;
}
}
return pname;
}
/******************************************************************************
Function : void taskSetTrigger(HTASK task, U16 trigger, void * p)
Params : task - the task
: trigger - the trigger for this task
: p - the trigger's params if need.
:
Return : N/A
Description : to notify the OS scheduler some trigger is raised for task.
:
******************************************************************************/
void taskSetTrigger(HTASK task, U16 trigger, void * p)
{
if (task >= MAX_SYS_TASK)
{
OS_error ("taskSetTrigger(): task [%d] out of range!!!\n", task);
return;
}
if (trigger >= T_TRIG_MAX)
{
OS_error ("taskSetTrigger(): trigger [%d] is invlaid!!!\n", trigger);
return ;
}
fsmSetTrig(g_taskFsm, (HANDLE)task, trigger, p);
}
/******************************************************************************
Function : U16 getTaskState(HANDLE handle)
Params : handle - the task.
:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -