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

📄 serlock.c

📁 AT91所有开发板的资料 AT91所有开发板的资料
💻 C
📖 第 1 页 / 共 4 页
字号:
}/* *        Function:  angel_SerialiseTaskCore * *         Purpose:  To queue a new task for the scheduler. This calls NewTask *                   to create a new SVC mode task and if possible, executes the *                   it (it may not be possible due to a current SVC task in *                   progress. * *       Arguments:   *                   interrupted_regblock- a regblock pointer to the context *                                         for the task which was interrupted *                    *                   desired_regblock    - a regblock pointer containing the *                                         PC and R0 for the new task *                                          * *   Pre-conditions: This function must be called from SVC mode with the *                   SVC stack set up for use.  On entry IRQ's and *                   FIQ's will be disabled.  It must only ever be *                   called from the assembler veneer code in *                   Angel_SerialiseTask * *  Post-conditions: An SVC task will be executing. */void angel_SerialiseTaskCore(int yielded, unsigned pc, void *state,                        angel_RegBlock *interrupted_regblock){    angel_TaskQueueItem *tqi;    IGNORE(yielded);        /* LogInfo(LOG_SERLOCK, ("SerialiseTaskCore: drb %x, irb %x, "                          "old pc %8X, new pc %8X\n",                          desired_regblock, interrupted_regblock,                          interrupted_regblock->pc, desired_regblock->pc)); */#ifdef DEBUG_APPLINT    if (angel_CurrentTask->type == TP_Application)        LogInfo(LOG_SERLOCK, ("Interrupting Application, PC = %08lx, CPSR = %08lx\n",                                  interrupted_regblock->pc, interrupted_regblock->cpsr));#endif    ASSERT(((Angel_GetCPSR() & 0xf) != 0), ("SerialiseTaskCore: in USR mode\n"));    /*     * first off, we need a tqi for this new task. Create one from     * the info in desired_regblock     */    tqi = Angel_NewTask(TS_Runnable, TP_AngelWantLock, pc, (void*)state);#if DEBUG    tqi->name = "Handler";#endif        /*     * interrupted_regblock represents the state of the current task,     * which might be the one we continue with. If we are already running     * a task with WantLock priority, then we just continue with it.     * If not, then use interrupted_regblock to update the memory context     * for the interrupted task and enter the scheduler, which will pick     * the current highest-priority task and run it.     */    ASSERT((angel_CurrentTask != NULL), ("SerialiseTaskCore: current task is NULL\n"));        if (angel_CurrentTask->type == TP_AngelWantLock)        angel_StartTask(interrupted_regblock);    else    {        angel_QueueTask(interrupted_regblock, angel_CurrentTask);        angel_SelectNextTask();    }}/* *        Function:  angel_IdleLoop * *         Purpose:  The idle loop just marks time. It runs (in user mode) *                   when the serialiser finds no other task can run. * *                   The task starts out with the Angel interrupt(s) enabled, *                   and the non-Angel interrupt (if any) disabled. The *                   state of the non-Angel interrupt can change if the *                   serialiser "pokes" the CPSR when a interrupts happen, *                   which it would do if it was "following" the application *                   interrupt state. * *                   The ifdef's surround a code chunk which will flash the *                   LED managed by the LED_DEVICE at approximately 1s *                   intervals (on a PIE) when Angel is idling, and slower *                   when it is performing "real" work. If heartbeats are *                   disabled and an application which doesn't use *                   semihosting is running, the led will stop flashing. *  *                   THIS ROUTINE NEVER RETURNS. *  *       Arguments:  none. * *          Return:  none. *                    *  Pre-conditions:  Devices initialised. * * Post-conditions:  Device poll carried out; interrupts serviced. * */static void angel_IdleLoop(void){    #ifdef IDLE_FLASH_LEDS#ifndef FLASH_LED_LOOP_COUNT /* this is a magic number which works ok on PIE */#define FLASH_LED_LOOP_COUNT 0x00040000#endif    static int c = 0, s = 1;#endif    while(TRUE)    {#ifdef IDLE_FLASH_LEDS        if (++c > FLASH_LED_LOOP_COUNT )        {            s = ! s;            c = 0;            angel_DeviceControl((DeviceID)DI_LED_DEVICE, (DeviceControl)DC_SET_LED, (void*)s);        }#endif    }}/* *        Function:  angel_PollLoop * *         Purpose:  This routine calls the device poll code for each configured *                   polling device, enabling devices which can't themselves generate *                   an interrupt to gain control of the processor from an application. *                    *                   The code claims a timer`, requesting the timer code to send a given *                   signal every 100ms; on receipt of such a signal, the poll is *                   performed and the task goes back to sleep * *       Arguments:  none. * *          Return:  none. *                    *  Pre-conditions:  Devices initialised. * * Post-conditions:  Device poll carried out; interrupts serviced. * */#if TIMER_SUPPORTED && POLLING_SUPPORTEDstatic void angel_PollLoop(void){    /* set up a signal to happen every 10 ms */    int t = Timer_NewTimer(20, TF_SIGNALME | TF_RELOAD,                           (TimerCallback)Angel_TaskID(), SIGBIT_POLL);        LogInfo(LOG_SERLOCK, ("PollLoop: Using timer %d\n", t));    while(TRUE)    {        Angel_Wait(SIGBIT_POLL);        /* LogInfo(LOG_SERLOCK, ("PollLoop: poll devices\n")); */                angel_DeviceYield();    }}#endif/* *        Function:  Angel_YieldCore * *         Purpose:  The core of Angel_Yield. This just calls the device Yield *                   routine which should poll any defined devices and return. *                   The main point of this routine outside of a poll is that *                   it is called with interrupts enabled, and thus any devices *                   with interrupts pending will be serviced as well. * *       Arguments:  none. * *          Return:  none. *                    *  Pre-conditions:  Devices initialised. * * Post-conditions:  Device poll carried out; interrupts serviced. * */void Angel_YieldCore(void){    angel_DeviceYield();}/* *       Function:  angel_SelectNextask * *        Purpose:  To select the first available task in the highest *                  priority queue which is not empty, and to effect it *                  by calling angel_StartTask. * *      Arguments:  None. * *  Pre-conditions: This routine must be called in SVC, with Angel interrupts *                  disabled. * *         Effect:  The queue is scanned in descending order *                  of priority. The first non blocked item in the  *                  queue is removed, and then effected. *                  If there is no task then go into an idle loop. */void angel_SelectNextTask(void){    register angel_TaskQueueItem *tqi;    ASSERT(((Angel_GetCPSR() & 0xf) != 0), ("SelectNextTask: in USR mode\n"));    /*     * This flag is used to say we need to get to the scheduler... now we're     * here, reset it.     */    Angel_Needschedule = 0;    /*     * push the current task back onto the task list, in priority order     */    if (angel_CurrentTask)    {        Task_Enqueue(&angel_TQI_Run, angel_CurrentTask);    }        angel_PrintTaskQueueShort("SNT", &angel_TQI_Run);        /*     * Get the current highest priority task.     */    tqi = Task_RemHead(&angel_TQI_Run);        /*     * if task in stupid state, complain     */    ASSERT((tqi->state == TS_Runnable ), ("Task in invalid state\n"));    /* Otherwise this is the highest priority task so execute it ! */#ifdef DEBUG_TASKS/*     LogInfo(LOG_SERLOCK, ("SelectNextTask: Select %d, pc 0x%lx, " *//*                           "usr (lr 0x%lx, sp 0x%lx) " *//*                           "svc (lr 0x%lx, sp 0x%lx) " *//*                           "type %d, pri %d\n", *//*                           tqi->index, tqi->rb.pc, *//*                           tqi->rb.r14usr, tqi->rb.r13usr, *//*                           tqi->rb.r14svc, tqi->rb.r13svc, *//*                           tqi->type, tqi->priority)); */        LogInfo(LOG_SERLOCK, ("SelectNextTask: Select %d, pc 0x%lx\n", tqi->index, tqi->rb.pc));#endif        angel_CurrentTask = tqi;    tqi->state = TS_Running;    #ifdef DEBUG_APPLINT    if (angel_CurrentTask->type == TP_Application)        LogInfo(LOG_SERLOCK, ("Resuming Application, PC = %08lx, CPSR = %08lx\n",                              tqi->rb.pc, tqi->rb.cpsr));#endif        angel_StartTask(&(tqi->rb));    /*NOTREACHED*/        /*     * Should never get here... (the idle task should always be runnable)     */    LogFatalError(LOG_SERLOCK, ("SelectNextTask: No task to run!"));}/* *       Function:  angel_InitialiseOneOff * *        Purpose:  To initialise the scheduler and create an application *                  context which is linked onto the task queue, although *                  it is blocked from actually starting. It also sets the *                  scheduler in 'initialisaion' mode. This is one way of *                  setting a task running in Angel...  * *      Arguments:  None. * *  Pre-conditions: This routine must be called in SVC, with the I-bit *                  and F-bit set. * */void angel_InitialiseOneOff(void){    int i;    unsigned base, stackBase;    unsigned stackLimit;    angel_TaskQueueItem *tqi;    LogInfo(LOG_SERLOCK, ( "angel_InitialiseOneOff entered\n"));    NewList(&angel_TQI_Free);    NewList(&angel_TQI_Wait);    NewList(&angel_TQI_Run);    NewList(&angel_Stack_Free);    Angel_Needschedule = 0;        /* stackBase is the highest address used by the descending stack */    base = Angel_StackBase;        stackBase = base + Angel_AngelStackOffset;    stackLimit = base + Angel_AngelStackLimitOffset;    angel_SVCStack.stackBase = base + Angel_SVCStackOffset;    angel_SVCStack.stackLimit = base + Angel_SVCStackLimitOffset;    angel_CurrentTask = NULL;        for (i = 0; i < POOLSIZE; i++)    {        /* set up TQI's; n_type is the task ID... */        angel_TQ_Pool[i].index = i;        angel_TQ_Pool[i].priority = 0;        angel_TQ_Pool[i].name = 0;        angel_TQ_Pool[i].type = TP_IdleLoop;        angel_TQ_Pool[i].state = TS_Undefined;        AddTail(&angel_TQI_Free, (MinNode*)&angel_TQ_Pool[i]);        /* ... and stacks */        angel_Stack_Pool[i].stackBase = stackBase;#if DEBUG        angel_Stack_Pool[i].HWM = stackBase;#endif        angel_Stack_Pool[i].stackLimit = stackBase - Angel_AngelStackFreeSpace;        AddTail(&angel_Stack_Free, (MinNode*)&angel_Stack_Pool[i]);                stackBase -= Angel_AngelStackFreeSpace;        if (stackBase < stackLimit)        {            LogError(LOG_SERLOCK, ("Not enough stack: %d: stackBase = %p, stackLimit = %p\n",                                   i, stackBase, stackLimit));            break;        }    }    LogInfo(LOG_SERLOCK, ("Set up tasks and stacks:\n %d Tasks\n Total %6d (%dKb)\n Wasted %d\n",                          i, Angel_CombinedAngelStackSize,                          Angel_CombinedAngelStackSize / 1024,                          stackBase - stackLimit));        /* The idle loop: this is needed! */    tqi = Angel_NewTask(TS_Runnable, TP_IdleLoop, (unsigned)angel_IdleLoop, 0);    if (tqi == NULL) /* sorry, can't do it! */    {        LogFatalError(LOG_SERLOCK,                      ("angel_InitialiseOneOff: CANNOT ALLOCATE IDLE TASK!\n"));    }    tqi->name = "Idle";    angel_IdleTask = tqi;#if POLLING_SUPPORTED    /* The poll loop */    tqi = Angel_NewTask(TS_Runnable, TP_PollLoop, (unsigned)angel_PollLoop, 0);    if (tqi == NULL) /* sorry, can't do it! */    {        LogFatalError(LOG_SERLOCK,                      ("angel_InitialiseOneOff: CANNOT ALLOCATE POLL TASK!\n"));    }    tqi->name = "Poll";    angel_PollTask = tqi;#endif        /* The application: always allocate one. */    tqi = Angel_NewTask(TS_Blocked, TP_Application, 0x8000, 0);    if (tqi == NULL) /* sorry, can't do it! */    {        LogFatalError(LOG_SERLOCK,                      ("angel_InitialiseOneOff: CANNOT ALLOCATE APPL TASK!\n"));    }    tqi->signalWaiting = 1;    tqi->state = TS_Blocked;    tqi->name = "Application";    angel_ApplTask = tqi;}/* *       Function:  angel_InitialiseTaskFinished * *        Purpose:  To signal that Angel initialisation has completed, *                  and the application task can be run. This is only *                  used in minimal angel systems, where no debugger *                  will step in and Execute the application. * *      Arguments:  None. * *  Pre-conditions: angel_InitialiseOneOff must have been called, and *                  no other task run since. * */void Angel_InitialiseTaskFinished(void){    LogInfo(LOG_SERLOCK, ( "Angel_InitialiseTaskFinished\n"));}#endif /* NOT MINIMAL_ANGEL *//* EOF serlock.c */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -