⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 core.c

📁 还是arm7操作源码
💻 C
📖 第 1 页 / 共 4 页
字号:
    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 + -