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

📄 serlock.c

📁 AT91所有开发板的资料 AT91所有开发板的资料
💻 C
📖 第 1 页 / 共 4 页
字号:
/* -*-C-*- * * $Revision: 1.2 $ *   $Author: rivimey $ *     $Date: 1999/03/22 17:47:08 $ * * Copyright (c) 1996-1998 ARM Limited. * All Rights Reserved. * *   Project: ANGEL * *     Title: Implementation of serialiser module */#include "angel.h"#include "devconf.h"#include "logging.h"#include "serlock.h"#include "support.h"#include "arm.h"#include "devdriv.h"#include "stacks.h"#include "serial.h"#include "timerd.h"#include "tasklist.h"#if MINIMAL_ANGEL == 0static List angel_TQI_Free;              /* free angel_TaskQueueItem's */List angel_TQI_Wait;                     /* waiting tasks, not ordered */List angel_TQI_Run;                      /* running tasks, priority ordered */angel_TaskQueueItem *angel_CurrentTask;  /* points at running task, not on any list */static angel_TaskQueueItem *angel_ApplTask;static angel_TaskQueueItem *angel_IdleTask;#if POLLING_SUPPORTEDstatic angel_TaskQueueItem *angel_PollTask;#endifstatic List angel_Stack_Free;            /* free stack regions */unsigned long angel_SWIReturnToApp;      /* if in appl SWI, 0 otherwise */unsigned long angel_SWIDeferredBlock;    /* if in appl SWI, 0 otherwise */unsigned long Angel_Needschedule;        /* if TRUE, enter scheduler at end of current interrupt *//* pool of task descriptors, managed by lists above */angel_TaskQueueItem angel_TQ_Pool[POOLSIZE];/* pool of stack descriptors, managed by lists above. */static angel_StackDesc angel_Stack_Pool[POOLSIZE];/* supervisor stack descriptor -- refers to distinct stack region, not list-managed */static angel_StackDesc angel_SVCStack;/* global reg blocks -- used to save context info until scheduler entered. */angel_RegBlock Angel_GlobalRegBlock[RB_NumRegblocks];/* the externs here are defined in startrom.s */extern unsigned long angel_GhostCount;     /* interrupts */extern unsigned long angel_SWIReturnToApp; /* in appl SWI */extern unsigned long angel_ComplexSWILock; /* in complex SWI */extern void angel_NextTask(void);extern void angel_StartTask(angel_RegBlock *);#if DEBUG#define INC_STAT(x)  (x)++#define DEC_STAT(x)  (x)--#undef DEBUG_TASKS#undef DEBUG_APPLINT#undef DEBUG_SIGNALSstatic unsigned long angel_NumCurrentTasks = 0;static unsigned long angel_NumTasksHWM = 0;extern unsigned long angel_InterruptCount;extern unsigned long angel_DebugStartTaskCount;extern unsigned long angel_DebugQueueTaskCount;extern unsigned long angel_SysCallCount;#else /* not DEBUG */#define INC_STAT(x)#define DEC_STAT(x)#undef DEBUG_TASKS#undef DEBUG_APPLINT#undef DEBUG_SIGNALS#endif#if DEBUGstruct StatInfo intr_stat_info[] ={    "Interrupt Stats:\n"    "  Total Interrupts       %8d\n", &angel_InterruptCount,    "  Ghost Interrupts       %8d\n", &angel_GhostCount,    NULL, NULL};struct StatInfo task_stat_info[] ={    "Task Stats:\n"    "  Total Task Switches    %8d\n", &angel_DebugStartTaskCount,    "  Tasks Interruped       %8d\n", &angel_DebugQueueTaskCount,    "  System Calls           %8d\n", &angel_SysCallCount,    "  Number of tasks (HWM)  %8d\n", &angel_NumTasksHWM,    "\n"    "Current State:\n"    "  Number of tasks        %8d\n", &angel_NumCurrentTasks,    "  Complex SWI Lock       %8d\n", &angel_ComplexSWILock,    "  Current Task           %8x\n", (unsigned long *)&angel_CurrentTask,    NULL, NULL};#endif/**********************************************************************/#if defined( DEBUG_TASKS )void angel_PrintTaskQueue(List *q){    angel_TaskQueueItem *tqi;    for(tqi = Task_FirstNode(q); !Task_AtEndOfList(tqi); )    {        LogInfo(LOG_SERLOCK, ("Task Queue %d: (%08lx) %s\n"                                 "Next = %08lx, Type = %d, State = %d, Priority = %u\n",                                 tqi->index, tqi, (tqi->name) ? tqi->name : "", tqi->n.n.mn_next,                                 tqi->type, tqi->state, tqi->priority));        LogInfo(LOG_SERLOCK, ("Stack Base = %08lx, Limit = %08lx, Entrypoint = %08lx\n",                                 tqi->stack->stackBase, tqi->stack->stackLimit, tqi->entryPoint));        LogInfo(LOG_SERLOCK, ("Signal Wait = %08lx, Signal Bits = %08lx\n",                                 tqi->signalWaiting, tqi->signalReceived));        LogInfo(LOG_SERLOCK, ("      pc = %08lx cpsr = %08lx\n",                                 tqi->rb.pc, tqi->rb.cpsr));        LogInfo(LOG_SERLOCK, ("      r0 = %08lx   r1 = %08lx   r2 = %08lx   r3 = %08lx\n",                                 tqi->rb.r0, tqi->rb.r1, tqi->rb.r2, tqi->rb.r3));	tqi = Task_Succ(tqi);        if (!Task_AtEndOfList(tqi))            LogInfo(LOG_SERLOCK, ("\n"));    }}#else#define angel_PrintTaskQueue(l)#endif#ifdef DEBUG_TASKSstatic void angel_PrintTaskQueueShort(char *s, List *q){    angel_TaskQueueItem *tqi;        LogInfo(LOG_SERLOCK, ("Task Queue: %s: ", s));    if (q == &angel_TQI_Run && (tqi = angel_CurrentTask) != NULL)    {        LogInfo(LOG_SERLOCK, ("*(%d %c %d)", tqi->priority,                              (tqi->state == TS_Blocked) ? 'B' : 'R',                              tqi->index));        tqi = Task_FirstNode(q);        if (!Task_AtEndOfList(tqi))            LogInfo(LOG_SERLOCK, (" -> "));    }    else        tqi = Task_FirstNode(q);        while(!Task_AtEndOfList(tqi) )    {        LogInfo(LOG_SERLOCK, ("(%d %c %d)", tqi->priority,                              (tqi->state == TS_Blocked) ? 'B' : 'R',                              tqi->index));	tqi = Task_Succ(tqi);        if (!Task_AtEndOfList(tqi))            LogInfo(LOG_SERLOCK, (" -> "));    }    LogInfo(LOG_SERLOCK, ("\n"));}#else#define angel_PrintTaskQueueShort(s, l)#endif/**********************************************************************/void Task_Enqueue(List *lp, angel_TaskQueueItem *np){    if (IsListEmpty(lp))    {        AddHead(lp, (MinNode *)np);    }    else    {        angel_TaskQueueItem *fp = (angel_TaskQueueItem *)FirstNode(lp);        angel_TaskQueueItem *bp = (angel_TaskQueueItem *)LastNode(lp);        short pri = np->priority;        if (pri > fp->priority)        {            AddHead(lp, (MinNode*)np);        }        else if (pri <= bp->priority)        {            AddTail(lp, (MinNode*)np);        }        else        {            /* we've checked start & end of list; it must be in the middle! */            while(pri <= fp->priority)            {                fp = (angel_TaskQueueItem*)Succ((MinNode*)fp);            }            InsertBefore((MinNode*)fp, (MinNode*)np);        }    }}/* *        Function:  Angel_AccessApplicationTask * *         Purpose:  This routine looks for the application task  *                   queue item. * *       Arguments:  none * *          Return:  tqi       a pointer to the task queue for the *                             appl task, or NULL if no task found. * *   Pre-conditions: angel_TaskQueueHead initialised. * *  Post-conditions: none */angel_TaskQueueItem *Angel_AccessApplicationTask(void){    return angel_ApplTask;}/* *        Function:  Angel_GetBankedReg * *         Purpose:  Read the register 'regno' for mode 'mode' from *                   register block 'rb'. * *       Arguments:  rb    a pointer to the RegBlock to be updated. *                   regno the number of the register to read *                   mode  the CPU mode (as CPSR) * *                   Coding for 'regno': 13 => r13, 14 ->r14, 15 -> SPSR * *   Pre-conditions: None * *  Post-conditions: None */   extern unsigned char ContextLookuptable[3][16];unsigned Angel_GetBankedReg(angel_RegBlock *rb, unsigned int mode, int regno){    unsigned char rboffset = ContextLookuptable[regno - 13][mode & 0xf];    unsigned char *rbptr = (unsigned char *)rb + rboffset;    return *((unsigned int *)rbptr);}/* *        Function:  Angel_AdrBankedReg * *         Purpose:  Read the address of register 'regno' for mode 'mode' *                   in register block 'rb'. * *       Arguments:  rb    a pointer to the RegBlock to be updated. *                   regno the number of the register to read *                   mode  the CPU mode (as CPSR) * *                   Coding for 'regno': 13 => r13, 14 ->r14, 15 -> SPSR * *   Pre-conditions: None * *  Post-conditions: None */unsigned *Angel_AdrBankedReg(angel_RegBlock *rb, unsigned int mode, int regno){    unsigned char rboffset = ContextLookuptable[regno - 13][mode & 0xf];    unsigned char *rbptr = (unsigned char *)rb + rboffset;    return ((unsigned *)rbptr);}/* *        Function:  angel_QueueTask * *         Purpose:  To copy a regblock context into the task queue item, used *                   when saving a task context for later execution. *                    *                   The routine modifies the run state; if the task was running *                   it patently isn't anymore, and the state is set to runnable. *                   As this must not happen if state was blocked, the initial *                   state must be verified as Running first. *                    *       Arguments:  regblock - the regblock from which to take the processor *                              context. *                   tqi      - the tqi into which the context must be saved * *          Return:  none. *                    *  Pre-conditions:  the context in regblock must be the context for the task *                   referenced in tqi. * * Post-conditions:  the TQI is up-to-date w.r.t. it's task. * */voidangel_QueueTask(angel_RegBlock * regblock,                angel_TaskQueueItem *tqi){    /* LogInfo(LOG_SERLOCK, ("QueueTask: rb %x, tq %x\n", regblock, tqi )); */        __rt_memcpy((void *)&(tqi->rb), (const void *)regblock,                sizeof(angel_RegBlock));    #if DEBUG != 0    Angel_DebugLog(regblock, tqi, 2) ;#endif    /* if this task was running, it isn't any longer. Mark it so. */    if (tqi->state == TS_Running)    {        tqi->state = TS_Runnable;    }}/**********************************************************************//* *        Function:  angel_FindTask * *         Purpose:  This routine looks for a task on the task queue *                   with the given type. * *       Arguments:  type      the type of task being searched for * *          Return:  tqi       a pointer to the task queue for the *                             required task, or NULL if no task found. * *   Pre-conditions: angel_TaskQueueHead initialised. * *  Post-conditions: none */angel_TaskQueueItem *angel_FindTask(List *q, angel_TaskType type){    angel_TaskQueueItem *tqi;    /* Find a task with the required type, not marked as new */    tqi = Task_FirstNode(q);    while (!Task_AtEndOfList(tqi))    {        if (tqi->type == type)        {            return tqi;        }        tqi = Task_Succ(tqi);    }    return NULL;}/* *        Function:  angel_AccessQueuedRegBlock * *         Purpose:  This routine looks for a task on the task queue *                   with the given type. * *       Arguments:  type      the type of task being searched for * *          Return:  rb        a pointer to the regblock for the *                             required task, or NULL if no task found. * *   Pre-conditions: angel_TaskQueueHead initialised. * *  Post-conditions: none */angel_RegBlock *angel_AccessQueuedRegBlock(angel_TaskType type){    angel_TaskQueueItem *t;        /* Find a task with the requested priority */    t = angel_FindTask(&angel_TQI_Run, type);    if (t == NULL)        t = angel_FindTask(&angel_TQI_Wait, type);#if DEBUG    if (t == NULL)    {        LogWarning(LOG_SERLOCK, ( "Could not find application task.\n"));        return NULL;    }#endif    return &(t->rb);}/* *        Function:  Angel_BlockApplication * *         Purpose:  Block or unblock the application task; that is *                   either allow or prevent it from executing any *                   further. If Angel is currently executing a SWI *                   on behalf of the application, the SWI is allowed *                   to complete, but the application is not resumed. * *       Arguments:  value     TRUE to block, FALSE to unblock appl

⌨️ 快捷键说明

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