📄 serlock.h
字号:
/* -*-C-*- * * $Revision: 1.2 $ * $Author: rivimey $ * $Date: 1999/03/22 12:50:56 $ * * Copyright (c) 1996 Advanced RISC Machines Limited. * All Rights Reserved. * * Project: ANGEL * * Title: Definitions for the serial kernel of Angel. * */#ifndef angel_serlock_h#define angel_serlock_h#ifdef TARGET# include "angel.h"#else# include "host.h"#endif#include "list.h"/****************************************************************************//* * POOLSIZE: the maximum number of tasks supported. * * some ports may need to increase (or even decrease) this value, depending * on the number of tasks used by their drivers. */#ifndef POOLSIZE#define POOLSIZE 10#endif/* * This define should be set in devconf: if undefined here, assume we're * not polling */#ifndef POLLING_SUPPORTED#define POLLING_SUPPORTED 0#endif/* * This definition is central to the way in which the serial core of Angel * keeps track of interrupted and schedulable states. * * The following structure is capable of holding the complete set of * registers, sufficient to resume an instruction stream in exactly the same * state as it was in when it was interrupted (or interrupted itself). The .r * field holds the nominal registers r0 to r15 (= pc), while the .cpsr and * .spsr fields hold the Current Program Status register and the Saved * Program Status Register respectively. * * The identity of banked registers is implied by the mode held in the .cpsr * field. * * Note: This structure is duplicated in assembler terms in taskmacs.s. The * code assumes this order. * */typedef struct{ unsigned r0, pc; unsigned spsrfiq, r8fiq, r9fiq, r10fiq, r11fiq, r12fiq, r13fiq, r14fiq; unsigned spsrirq, r13irq, r14irq; unsigned spsrsvc, r13svc, r14svc; unsigned spsrabt, r13abt, r14abt; unsigned spsrund, r13und, r14und; unsigned cpsr; unsigned r1, r2, r3, r4, r5, r6, r7; unsigned r8usr, r9usr, r10usr, r11usr, r12usr, r13usr, r14usr;} angel_RegBlock;typedef enum angel_TaskType{ TP_IdleLoop = 0, TP_AngelInit, TP_Application, TP_AngelCallBack, TP_ApplCallBack, /* not used */ TP_PollLoop, TP_AngelWantLock} angel_TaskType;/* --------------------------------------------------------------------- * Angel Interrupt Usage * --------------------- * * These two mask definitions are used by Angel to manipulate the * interrupt mask bits in the CPSR. Note: there *are* cases when it is * valid for Angel to modify both bits, irrespective of these * definitions. These are: * * a. On initial boot, when initialising the system. Angel cannot cope * with interrupts at this stage, and the devices and interrupt * system are not necessarily configured properly yet. * * b. ??When Angel_EnterSVC is called. The user has asked for interrupts * to be masked; Angel doesn't assume only Angel's interrupts are * relevant. TBD Is this correct? Should it include the SWI or * just the function call? * * c. When performing a register dump following an exception, where if * another exception occurred required data might be lost. * * d. When disabling interrupts prior to entering Deadloop. There's no * point in DeadLoop if it can be interrupted. * * Typically, these places use the constant InterruptMask. * * * The definitions: * * AngelInterruptMask is the bits to set in order to disable, or * which can be cleared to enable, interrupts * in Angel * * NotAngelInterruptMask is the bits to set in order to disable, * or which can be cleared to enable, * interrupts in the application. * *//* see also comments in taskmacs.s. */#if (HANDLE_INTERRUPTS_ON_FIQ == 1)#if (HANDLE_INTERRUPTS_ON_IRQ == 1)#define AngelInterruptMask IRQDisable + FIQDisable#define NotAngelInterruptMask 0#else#define AngelInterruptMask FIQDisable#define NotAngelInterruptMask IRQDisable#endif #else#if (HANDLE_INTERRUPTS_ON_IRQ == 1)#define AngelInterruptMask IRQDisable#define NotAngelInterruptMask FIQDisable#else#error "Angel needs an interrupt source!"#endif#endiftypedef enum angel_TaskState{ TS_Undefined, /* TQI does not contain a valid task */ TS_Defined, /* TQI allocated but has never been started */ TS_Runnable, /* Task is runnable, but not running at the moment */ TS_Running, /* Task is in CPU and running (ints, etc excepted) */ TS_Blocked /* Task is not runnable; blocked by signalWaiting */} angel_TaskState;/* * descriptor for a task stack. Tasks don't always use the same stack * region, hence we must allocate TQI and Stack independently. */typedef struct angel_StackDesc{ MinNode n; /* where is the task's stack? stackBase > stackLimit in FD stack */ unsigned stackBase; unsigned stackLimit;#if DEBUG unsigned HWM;#endif } angel_StackDesc;/* * Angel's Task Queue Item (process control block in other language). */typedef struct angel_TaskQueueItem{ Node n; /* links */ /* index of this tqi into the TQ_Pool array */ int index; /* if known -- otherwise NULL */ char *name; angel_StackDesc *stack; /* where did we start. Don't believe it for the application tho */ unsigned entryPoint; /* if this is non-zero, the task is not runnable. */ angel_TaskState state; /* bits this task is currently waiting on. If nonzero task is blocked. */ unsigned signalWaiting; /* bits that have been signalled since the last wait. */ unsigned signalReceived; /* type of task. Esp used for finding the application */ angel_TaskType type; /* task priority. more positive for higher execution priority */ unsigned priority; /* The task's context. Not up-to-date in the case of a complex SWI, * or obviously when the task is running. */ angel_RegBlock rb; } angel_TaskQueueItem;#define TP_MaxEnum (TP_AngelWantLock)/****************************************************************************//* * The following items are the (globally accessible) register blocks * used by interrupt handlers, the undefined instruction handler and * the SWI handler. They are used to hold an interrupted_regblock * (element 0) and a desired_regblock (element 1) to be used by * SerialiseTask. */#define RB_Interrupted 0#define RB_SWI 1#define RB_UNDEF 2#define RB_ABORT 3#define RB_Yield 4#if DEBUG == 1# define RB_Fatal 5# define RB_NumRegblocks 6#else# define RB_NumRegblocks 5#endif/* This is no longer used; it is here only because the makelo files refer to it. */#define RB_Desired 0xBADextern angel_RegBlock Angel_GlobalRegBlock[RB_NumRegblocks];/* * The Task priority is initialised by reference to the task type, but * is subsequently independent of it. This macro is used to convert * a task type into a task priority; multiplication by 4 is fast and good * enough to leave a few priority levels free. */#define TaskPriorityOf(type) (((unsigned)type) * 4)/* * Return the Task ID of the given task. */#define Angel_TaskIDOf(task) (task->index)/* * Return the Task ID of the current (calling) task. This is the way * that Angel_Signal() identifies the task to be signalled. */#define Angel_TaskID() Angel_TaskIDOf(angel_CurrentTask)/* * Return the interrupted PC value. This must be used within an interrupt * service routine; it means nothing outside of that context (including * a SerialiseTask chained from an ISR). The address is the address of the * next instruction which will be executed. */#define Angel_InterruptedPC() (Angel_GlobalRegBlock[RB_Interrupted].pc)/* * Convenience function to call a serialised task from an ISR. * Pass the task function and an optional arg (zero if not used). * See the docs on Angel_SerialiseTask for more info. */#define Angel_SerialiseISR(routine, data) Angel_SerialiseTask( 0, routine, data, empty_stack, \ &Angel_GlobalRegBlock[RB_Interrupted])/* * Convenience function to Serialise a call to Angel_Yield from an ISR. * See the docs on Angel_SerialiseTask and Angel_YieldCore for more info. */#define Angel_SerialiseYieldFromISR() Angel_SerialiseTask( 0, (angel_SerialisedFn)Angel_YieldCore, \ NULL, empty_stack, &Angel_GlobalRegBlock[RB_Interrupted])/* * These two macros are used in various places to indicate the nature * of the call to EnterSVC/ExitToUSR. In most places, Angel uses them * not to get into SVC mode, but to disable interrupts around a critical * section. */#define Angel_EnterCriticalSection() Angel_EnterSVC()#define Angel_LeaveCriticalSection() Angel_ExitToUSR()#define Angel_AccessApplicationRegBlock() angel_AccessQueuedRegBlock(TP_Application)#ifdef __ARMCC_VERSION/* * Inline assembler routines used by the C code to access the CPSR register. * They must be ifdef'd because this file is processed by other compilers when * generating the makelo executable. */__inline unsigned Angel_GetCPSR(void){ unsigned val; __asm { MRS val, CPSR } return val;}__inline void Angel_SetCPSR(unsigned val){ __asm { MSR CPSR_cf, val }}__inline int Angel_Exchange(int *sem, int value){ unsigned old; __asm { SWP old, value, [sem] } return old;}#elseint Angel_Exchange(int *sem, int value);unsigned Angel_GetCPSR(void);void Angel_SetCPSR(unsigned val);#endif/****************************************************************************/typedef void (*angel_SerialisedFn)(void *);void Angel_SerialiseTask(bool called_by_yield, angel_SerialisedFn fn, void *state, unsigned empty_stack, angel_RegBlock *regblock);typedef void (*angel_CallbackFn)(void *a1, void *a2, void *a3, void *a4);angel_TaskQueueItem *Angel_QueueCallback(angel_CallbackFn fn, angel_TaskType type, void *a1, void *a2, void *a3, void *a4);void Angel_DeferredBlockCore(void);void Angel_BlockApplication(int value);int Angel_IsApplicationBlocked(void);int Angel_IsApplicationRunning(void);/* angel_RegBlock *Angel_AccessApplicationRegBlock(void); */angel_TaskQueueItem *Angel_AccessApplicationTask(void);angel_RegBlock *angel_AccessQueuedRegBlock(angel_TaskType);angel_TaskQueueItem *angel_FindTask(List *q, angel_TaskType type);void Angel_Yield(void);extern void Angel_YieldCore(void);void Angel_EnterSVC(void);void Angel_ExitToUSR(void);unsigned int Angel_DisableInterruptsFromSVC(void);unsigned int Angel_EnableInterruptsFromSVC(void);void Angel_RestoreInterruptsFromSVC(unsigned int state);void angel_InitialiseOneOff(void);void Angel_InitialiseTaskFinished(void);void angel_SaveTask(angel_RegBlock *rb);unsigned int Angel_GetBankedReg(angel_RegBlock *rb, unsigned mode, int regno);unsigned int* Angel_AdrBankedReg(angel_RegBlock *rb, unsigned mode, int regno);extern void Angel_DebugLog(angel_RegBlock *r, angel_TaskQueueItem *t, int id);extern void angel_DeleteTask(angel_TaskQueueItem *oldtask);angel_TaskQueueItem *Angel_NewTask(angel_TaskState st, angel_TaskType pri, unsigned fn, void *a1);void angel_BlockAndSchedule(angel_RegBlock *rb, angel_TaskQueueItem *tqi);extern void angel_SelectNextTask(void);int Angel_Signal(unsigned task, unsigned signals);unsigned Angel_Wait(unsigned signals);void angel_ExitSWI(void);void angel_EnterSWI(void);unsigned Angel_GetCPSR(void);void angel_WaitCore(angel_RegBlock *r, angel_TaskQueueItem *t);void angel_SetPriority(angel_TaskQueueItem *oldtask, unsigned priority);void Angel_SetupExceptionRegisters(angel_TaskQueueItem * tqi);void angel_EnqueueTask(angel_TaskQueueItem *my_tqi);void angel_QueueTask(angel_RegBlock * regblock, angel_TaskQueueItem *tqi);extern void angel_SelectNextTask(void);extern void angel_SerialiseTaskCore(int, unsigned, void *, angel_RegBlock *);#if DEBUGvoid angel_PrintTaskQueue(List*);#endifextern angel_TaskQueueItem angel_TQ_Pool[POOLSIZE];extern angel_RegBlock Angel_GlobalRegBlock[RB_NumRegblocks];extern unsigned long angel_SWIReturnToApp; /* if in appl SWI, 0 otherwise */extern unsigned long angel_SWIDeferredBlock; /* if in appl SWI, 0 otherwise */extern unsigned long Angel_Needschedule;extern angel_TaskQueueItem *angel_TaskQueueHead;extern angel_TaskQueueItem *angel_CurrentTask;extern List angel_TQI_Wait; extern List angel_TQI_Run;/* Signal bit used for signalling read and write callbacks to task */#define SIGBIT_PAUSE 0x1 /* (application) stop-start */#define SIGBIT_READCB 0x2 /* channel read callback */#define SIGBIT_WRITECB 0x4 /* channel write callback */#define SIGBIT_THRSTOP 0x8 /* thread stopped ack received */#define SIGBIT_POLL 0x10 /* poll task timer */#define SIGBIT_DELAY 0x20 /* delay timer */#endif /* ndef angel_serlock_h *//* EOF serlock.h */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -