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

📄 serlock.c

📁 AT91所有开发板的资料 AT91所有开发板的资料
💻 C
📖 第 1 页 / 共 4 页
字号:
 * *          Return:  none. * *   Pre-conditions: angel_TaskQueueHead initialised. * *  Post-conditions: none */void Angel_BlockApplication(int value){    angel_TaskQueueItem *tqi;    if (angel_SWIReturnToApp)    {        LogInfo(LOG_SERLOCK, ( "angel_BlockApplication - (deferred) set to %d.\n", value));        angel_SWIDeferredBlock = 1;    }    else    {        Angel_EnterCriticalSection();                tqi = angel_ApplTask;                ASSERT((tqi != angel_CurrentTask),               ("Angel_BlockApplication: tqi cannot be current task\n"));                if ((value == 0) &&             (tqi->state == TS_Blocked))        {            LogInfo(LOG_SERLOCK, ( "angel_BlockApplication - set to %d (was blocked)\n", value));                    tqi->signalWaiting = 1;            tqi->state = TS_Runnable;            Task_Remove(tqi);            Task_Enqueue(&angel_TQI_Run, tqi);        }        else if ((value == 1) &&                 (tqi->state == TS_Runnable))        {            LogInfo(LOG_SERLOCK, ( "angel_BlockApplication - set to %d (was run)\n", value));                    tqi->signalWaiting = 0;            Task_Remove(tqi);            tqi->state = TS_Blocked;            Task_Enqueue(&angel_TQI_Wait, tqi);        }        else        {            /* else task is already in correct state --             * either blocked and value == 1, or runnable and value == 0             */            LogInfo(LOG_SERLOCK, ( "angel_BlockApplication - set to %d (ignored)\n", value));        }        Angel_LeaveCriticalSection();    }}/* *        Function:  Angel_IsApplicationBlocked * *         Purpose:  Return whether the application task is blocked. Being *                   blocked is indicated by two things: a deferred block *                   caused by BlockApplication called during an appl SWI, *                   and a 'real' block, indicated by the task having status *                   TS_Blocked. * *       Arguments:  value     TRUE if blocked, FALSE otherwise * *          Return:  none. * *   Pre-conditions: angel_TaskQueueHead initialised. * *  Post-conditions: none */int Angel_IsApplicationBlocked(void){    int blocked;    if (angel_SWIDeferredBlock)        blocked = 1;    else    {        blocked = (angel_ApplTask->state == TS_Blocked);    }    LogInfo(LOG_SERLOCK, ("angel_IsApplicationBlocked - returns %d.\n", blocked));        return blocked;}/* *        Function:  angel_SetPriority * *         Purpose:  To change the scheduler priority of a task on the task *                   queue. As the priority is implicit in the position in the *                   task list it is not possible to just poke the priority *                   value in the TQI; the task must be requeued as well. *                    *                   The task is located in the task queue, which ensures it has *                   been initialised and to find the next higher priority task. *                   'olstask' is then removed from the list, the priority in *                   its TQI modifined, and the task enqueue routine called to *                   place it in the correct place. * *                   This routine will not cause a task switch to 'oldtask' *                   if it is made higher priority than the current task, nor *                   can it cause the current task to be suspended if it is *                   set to a lower priority than another runnable task. * *       Arguments:  oldtask - the task whose priority is to be changed *                   priority - the new task priority * *          Return:  none. * *  Pre-conditions:  Serialiser initialised; the task pointed to by 'oldtask' *                   must have previously been added with Angel_NewTask; the *                   routine must be called with interrupts disabled. * *          Effect:  'oldtask' is requeued to reflect the assigned priority. * * Post-conditions: * */void angel_SetPriority(angel_TaskQueueItem *oldtask, unsigned priority){    register List *lp;        ASSERT(((Angel_GetCPSR() & 0xf) != 0), ("angel_SetPriority: in USR mode\n"));    oldtask->priority = priority;    /* if not changing current task re-enqueue it */    if (oldtask != angel_CurrentTask)    {        Task_Remove(oldtask);                if (oldtask->state == TS_Blocked)            lp = &angel_TQI_Wait;        else            lp = &angel_TQI_Run;        Task_Enqueue(lp, oldtask);    }}/* *        Function:  angel_EnterSWI * *         Purpose:  Routine called when an Angel Complex SWI is entered. *                   Used to perform some housekeeping, including raising *                   the priority of the application task to that of Angel *                   callbacks. This is necessary so that an incoming packet *                   cannot interrupt the processing of a SWI; if this were *                   allowed, deadlock could occur if the incoming packet *                   needed to send a reply while the SWI request packet was *                   still being processed. * *                   To enable Angel to tell that Angel is executing code on *                   behalf of the application task, the flag SWIReturnToApp *                   is set. This is used in the SWI return code and within the *                   BlockApplication routine. * *       Arguments:  none. * *          Return:  none. * *  Pre-conditions:  Must be called with interrupts disabled (because SetPriority *                   must be). angel_CurrentTask must point to an Application task * * Post-conditions:  The application task temporarily has a higher priority; *                   the Application-is-executing-SWI flag is set. * */void angel_EnterSWI(void){#if DEBUG    if (angel_CurrentTask->type != TP_Application)    {        LogFatalError(LOG_SERLOCK,                      ("Complex SWI called from within Angel: stack use conflict\n"));    }#endif    angel_SetPriority(angel_CurrentTask, TaskPriorityOf(TP_AngelCallBack));    angel_SWIReturnToApp = 1;}/* *        Function:  angel_ExitSWI * *         Purpose:  Undo the effects of angel_EnterSWI. Return the application *                   to it's normal priority and reset the in-swi flag. This routine *                   is called by return-from-complex-SWI routine. * *       Arguments:  none. * *          Return:  none. * *  Pre-conditions:  Must be called with interrupts disabled (because SetPriority *                   must be). angel_CurrentTask must point to an Application task *                   angel_SWIReturnToApp should be set. * * Post-conditions:  The application task priority is returned to normal; the in-swi *                   flag is reset. * */void angel_ExitSWI(void){    ASSERT(((Angel_GetCPSR() & 0xf) != 0), ("angel_ExitSWI: in USR mode\n"));    ASSERT((angel_SWIReturnToApp == 1),           ("System Call Return with no Call -- what happened?\n"));    angel_SetPriority(angel_CurrentTask, TaskPriorityOf(TP_Application));    angel_SWIReturnToApp = 0;}/* *        Function:  Angel_QueueCallback * *         Purpose:  The external API for the NewTask function, called by routines *                   within Angel wishing to create callback tasks. * *       Arguments:  fn     - the function to call *                   type   - the task type (e.g. TP_AngelCallback) to create *                   a1.. a4 - (up to) 4 parameters for the new task. * *          Return:  none. *                    *  Pre-conditions:  The serialiser must have been initialised. * * Post-conditions:  The new task will have been added to the task queue as a *                   runnable task, unless there was no TQI or stack available for *                   it. * */angel_TaskQueueItem *Angel_QueueCallback(angel_CallbackFn fn, angel_TaskType type,                    void *a1, void *a2, void *a3, void *a4){    angel_TaskQueueItem *tqi;    Angel_EnterSVC();    tqi = Angel_NewTask(TS_Runnable, type, (unsigned)fn, a1);    tqi->rb.r1 = (unsigned)a2;    tqi->rb.r2 = (unsigned)a3;    tqi->rb.r3 = (unsigned)a4;    Angel_ExitToUSR();    return tqi;}/* *        Function:  angel_SetupExceptionRegisters * *         Purpose:   *                    * *       Arguments:   *                    * *          Return:  none. *                    *  Pre-conditions:  The serialiser must have been initialised. * * Post-conditions:   *                    * */void Angel_SetupExceptionRegisters(angel_TaskQueueItem * tqi){    register unsigned base = Angel_StackBase;        tqi->rb.r14fiq = 0;    tqi->rb.r14irq = 0;    tqi->rb.r14und = 0;    tqi->rb.r14abt = 0;        /* set up the new task's exception registers. */    tqi->rb.r13fiq = base + Angel_FIQStackOffset;    tqi->rb.r13irq = base + Angel_IRQStackOffset;    tqi->rb.r13und = base + Angel_UNDStackOffset;    tqi->rb.r13abt = base + Angel_ABTStackOffset;}/* *        Function:  Angel_NewTask * *         Purpose:  To create a new task context. This is the only way to create *                   a new task, and may be executed in USR or Supervisor mode. The *                   new task will not be executed immediately, but will be queued *                   according to it's priority and may be executed as soon as  *                   SelectNextTask is run again. * *                   The new task context's mode will depend on it's type: all tasks *                   other than AngelWantLock are given a USR mode context, with a *                   stack allocated in the AngelAngelStack area; AngelWantLock tasks *                   (which are only created by SerialiseTaskCore) are run in SVC mode *                   with a statically allocated SVC stack. * *                   The processor registers pc, r0 - r3 are set using the arguments *                   'fn' and 'a1'-'a4' respectively; lr is set to angel_NextTask, which *                   will kill the task and enter the scheduler on it's exit. The *                   sp of the exception modes is set to their stack top, and their lr *                   registers to a routine which will cause a fatal error (the LR should *                   be overwritten on entry to the handler by the processor; therefore, *                   if the value written here the program has already gone wrong. *                    *                   The SVC stack is set up for USR mode tasks, but not vice versa; *                   the SVC task is not expected to use or need r13usr to be set. (The *                   reverse is also true, but SVC sp can be set up easily). * *       Arguments:  fn     - the function to call *                   type   - the task type (e.g. TP_AngelCallback) to create *                   a1     - the first parameter for the new task. * *          Return:  a pointer to the TQI allocated to the task or NULL if task not *                   initialised (an error). *                    *  Pre-conditions:  The serialiser, and exception subsystems must have been set up. * * Post-conditions:  The new task added to the task queue, or NULL returned. * */angel_TaskQueueItem * Angel_NewTask(angel_TaskState state, angel_TaskType type, unsigned fn, void *a1){    unsigned int cpsr;    angel_TaskQueueItem *tqi;    ASSERT(((Angel_GetCPSR() & 0xf) != 0), ("NewTask: in USR mode\n"));    /* enter critical section */    cpsr = Angel_DisableInterruptsFromSVC();        tqi = Task_RemHead(&angel_TQI_Free);    if (tqi == NULL)    {#if DEBUG        LogFatalError(LOG_SERLOCK, ("Angel_NewTask: Cannot create new task.\n"));#endif        Angel_RestoreInterruptsFromSVC(cpsr);        return NULL;    }#if DEBUG == 1    INC_STAT(angel_NumCurrentTasks);    if (angel_NumTasksHWM < angel_NumCurrentTasks)        angel_NumTasksHWM = angel_NumCurrentTasks;#endif                /* Set up the type and priority */    tqi->type = type;        /* the initial task priority is determined by the type */    tqi->priority = TaskPriorityOf(type);    tqi->name = 0;    tqi->signalReceived = 0;    tqi->signalWaiting = 0;    tqi->stack = 0;        if (type == TP_AngelWantLock)    {        tqi->stack = &angel_SVCStack;    }    else    {        tqi->stack = Stack_RemHead(&angel_Stack_Free);        if (tqi->stack == NULL) /* sorry, can't do it! */        {            DEC_STAT(angel_NumCurrentTasks);            Task_Remove(tqi);            tqi->state = TS_Undefined;            Task_AddTail(&angel_TQI_Free, tqi);	    Angel_RestoreInterruptsFromSVC(cpsr);            LogFatalError(LOG_SERLOCK, ("Angel_NewTask: Cannot allocate new stack.\n"));            return NULL;        }    }#if DEBUG    tqi->stack->HWM = tqi->stack->stackBase;#endif    Angel_RestoreInterruptsFromSVC(cpsr);        /* set up the registers we want for this call */    tqi->rb.r0 = (unsigned)a1;    tqi->rb.pc = (unsigned)fn;#if DEBUG        tqi->entryPoint = (unsigned)fn;#endif        /* set up the new task's exception registers. */    Angel_SetupExceptionRegisters(tqi);    if (type == TP_AngelWantLock)    {        tqi->rb.r13svc = tqi->stack->stackBase;                /* copy the state of the non-Angel interrupt bit to the new task */        tqi->rb.cpsr = SVCmode | (cpsr & NotAngelInterruptMask);        tqi->rb.r14svc = (unsigned)angel_NextTask;        #ifdef R10_IS_SL        /* The stack limit is not used in standard Angel: this code is here to`         * show where and how to set up SL.         */        tqi->rb.r10usr = tqi->stack->stackLimit;#endif    }    else    {

⌨️ 快捷键说明

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