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

📄 windalib.s

📁 VxWorks BSP框架源代码包含头文件和驱动
💻 S
📖 第 1 页 / 共 3 页
字号:
/* windALib.s - internal VxWorks kernel assembly library *//* Copyright 1996-2002 Wind River Systems, Inc. *//*modification history--------------------01m,16jan02,to   add context switch for _fpStatus01l,17oct01,t_m  convert to FUNC_LABEL:01k,11oct01,jb   Enabling removal of pre-pended underscores for new compilers                 (Diab/Gnu elf)01j,13nov98,cdp  add big-endian support; make Thumb support dependent on		 ARM_THUMB; optimise for no instrumentation.01i,02sep98,cjtc port to windView 2.001h,31jul98,pr   temporarily commentig out WindView code01g,24nov97,cdp  fix ARM7TDMI_T call to workQAdd1 (WindView instrumentation).01f,28oct97,cdp  correct WindView instrumentation code, remove "EOF", tidy.01e,09oct97,cdp  WindView fixes from Paola Rossaro (incorrect extern); tidy up.01d,23sep97,cdp  removed kludges for old Thumb tool-chains.01c,16apr97,cdp  added (Thumb) ARM7TDMI_T support;		 added WindView support.01b,05feb97,cdp  Fix return from windExit().01a,09may96,cdp  written, based (loosely) on 68K version*//*DESCRIPTIONThis module contains internals to the VxWorks kernel.These routines have been coded in assembler because they are eitherspecific to this processor, or they have been optimized for performance.*/#define _ASMLANGUAGE#include "vxWorks.h"#include "private/taskLibP.h"#include "private/workQLibP.h"#include "private/eventP.h"        .data        .globl	FUNC(copyright_wind_river)        .long	FUNC(copyright_wind_river)	/* globals */	.globl	VAR(_fpStatus)	.globl	FUNC(windExit)		/* routine to exit mutual exclusion */	.globl	FUNC(windIntStackSet)	/* interrupt stack set routine */#ifdef	PORTABLE	.globl	FUNC(windLoadContext)	/* needed by portable reschedule () */#else	.globl	FUNC(reschedule)		/* optimized reschedule () routine */#endif	/* PORTABLE */	/* externs */	.extern	FUNC(workQIsEmpty)	.extern	FUNC(workQDoWork)	.extern	FUNC(kernelState)	.extern	FUNC(intCnt)	.extern	FUNC(taskIdCurrent)	.extern	FUNC(readyQHead)	.extern	FUNC(errno)#ifdef	PORTABLE	.extern	FUNC(reschedule)#else	.extern FUNC(kernelIsIdle)	.extern	FUNC(taskSwapTable)	.extern	FUNC(taskSwitchTable)#endif	/* PORTABLE */	.extern	FUNC(exit)#ifdef	WV_INSTRUMENTATION        .extern	FUNC(evtAction)        .extern	FUNC(wvEvtClass)        .extern	FUNC(trgEvtClass)         .extern	FUNC(_func_evtLogT0)        .extern	FUNC(_func_evtLogTSched)        .extern	FUNC(_func_trgCheck)#endif	/* WV_INSTRUMENTATION */#if	(ARM_THUMB)	.extern	FUNC(arm_call_via_r2)	.extern	FUNC(arm_call_via_r12)#endif	/* (ARM_THUMB) */	/* variables */	.data	.balign	4VAR_LABEL(_fpStatus)	.long	0	.text	.balign	4	.code	32/* PC-relative-addressable pointers - LDR Rn,=sym is broken */L$__fpStatus:	.long	VAR(_fpStatus)L$_workQIsEmpty:	.long	FUNC(workQIsEmpty)L$_kernelState:	.long	FUNC(kernelState)	L$_intCnt:	.long	FUNC(intCnt)L$_taskIdCurrent:	.long	FUNC(taskIdCurrent)L$_readyQHead:	.long	FUNC(readyQHead)L$_errno:	.long	FUNC(errno)#if	(ARM_THUMB)L$_workQDoWork:	.long	FUNC(workQDoWork)#endif	/* (ARM_THUMB) */#ifdef	WV_INSTRUMENTATION L$_evtAction:	.long	FUNC(evtAction)L$_wvEvtClass:	.long	FUNC(wvEvtClass) L$_trgEvtClass:	.long	FUNC(trgEvtClass) L$__func_evtLogT0:	.long	FUNC(_func_evtLogT0) L$__func_evtLogTSched:	.long	FUNC(_func_evtLogTSched)L$__func_trgCheck:	.long	FUNC(_func_trgCheck)#endif	/* WV_INSTRUMENTATION */#ifndef	PORTABLEL$_kernelIsIdle:	.long	FUNC(kernelIsIdle)L$_taskSwapTable:	.long	FUNC(taskSwapTable)L$_taskSwitchTable:	.long	FUNC(taskSwitchTable)#endif	/* !PORTABLE *//********************************************************************************* windExitInt - exit kernel routine from interrupt level** windExit branches here if exiting kernel routine from int level* No rescheduling is necessary because the ISR will exit via intExit, and* intExit does the necessary rescheduling.  Before leaving kernel state* the work queue is emptied.** REGISTERS*    Exit: r0 = 0*/windExitInt:	/* save interrupt state and link */	STMFD	sp!, {r4,lr}		/* save v1 and link */	MRS	r4, cpsrwindExitIntLoop:	/*	 * disable interrupts	 * r4 = CPSR	 */	ORR	r0, r4, #I_BIT	MSR	cpsr, r0	/*	 * INTERRUPTS DISABLED	 *	 * see if workQ is empty	 */	LDR	r0, L$_workQIsEmpty	LDR	r0, [r0]	TEQS	r0, #0	BNE	windExitIntNoWork	/* branch if empty */	/*	 * work to do	 * restore interrupt state	 * r4 = previous CPSR	 */	MSR	cpsr, r4	/*	 * INTERRUPTS ENABLED	 *	 * call a C routine to empty the workQ	 */#if	(ARM_THUMB)	LDR	r12, L$_workQDoWork	/* empty workQ (r4 preserved) */	BL	FUNC(arm_call_via_r12)	/* returns in ARM state */#else	BL	FUNC(workQDoWork)		/* empty workQ (r4 preserved) */#endif	/* (ARM_THUMB) */	B	windExitIntLoop	/* NEVER FALL THROUGH */windExitIntNoWork:	/* workQ is empty */#ifdef	WV_INSTRUMENTATION	/* windview instrumentation - BEGIN	 * exit windExit with no dispatch; point 1 in the windExit diagram.	 */	LDR	lr, L$_evtAction	/* is event logging or triggering? */	LDR	lr, [lr]	TEQS	lr, #0	BNE	instrumentDispatch1	/* branch if so */	/* instrumentation currently disabled */resumeDispatch1:	/* windview instrumentation - END */#endif	/* WV_INSTRUMENTATION */	/* exit kernelState */	LDR	lr, L$_kernelState	MOV	r0, #0	STR	r0, [lr]	/*	 * restore interrupt state and return OK	 * r0 = 0	 */	MSR	cpsr, r4	/* INTERRUPTS ENABLED */#if	(ARM_THUMB)	LDMFD	sp!, {r4,lr}	BX	lr#else	LDMFD	sp!, {r4,pc}#endif	/* (ARM_THUMB) *//******************************************************************************/#ifdef	WV_INSTRUMENTATION	/* windview instrumentation - BEGIN	 * exit windExit with no dispatch; point 1 in the windExit diagram.	 */instrumentDispatch1:        LDR	lr, L$_wvEvtClass		/* is instrumentation on? */	LDR	lr, [lr]        AND	lr, lr, #WV_CLASS_1_ON	        TEQS	lr, #WV_CLASS_1_ON		BNE	trgInst1			/* branch if not */	/* 	 * try to determine if the task is running at an inherited priority	 * and log a different event if so	 */	LDR	r12, L$_taskIdCurrent	LDR	r12, [r12]			/* r12 -> TCB */	LDR	r1, [r12, #WIND_TCB_PRIORITY]	LDR	r2, [r12, #WIND_TCB_PRI_NORMAL]	CMPS	r2, r1	MOVHI	r0, #EVENT_WIND_EXIT_NODISPATCH_PI	MOVLS	r0, #EVENT_WIND_EXIT_NODISPATCH	LDR	r12, L$__func_evtLogTSched	/* get address of fn pointer */#if	(ARM_THUMB)	LDR	r12, [r12]			/* get function address */	BL	FUNC(arm_call_via_r12)		/* and call it */#else	MOV	lr, pc				/* call function */	LDR	pc, [r12]#endif	/* (ARM_THUMB) */trgInst1:         LDR	lr, L$_trgEvtClass		/* is triggering on? */	LDR	lr, [lr]        AND	lr, lr,#TRG_CLASS_1_ON	        TEQS	lr, #TRG_CLASS_1_ON		BNE	resumeDispatch1			/* branch if not */	/*	 * There are 8 parameters to the trgCheck function:	 * r0	 <- eventId	 * r1 	 <- index = TRG_CLASS1_INDEX	 * r2 	 <- obj (NULL)	 * r3 	 <- arg1 (NULL - unused)	 * stack <- arg2 (NULL - unused)	 * stack <- arg3 (NULL - unused)	 * stack <- arg4 (NULL - unused)	 * stack <- arg5 (NULL - unused)	 */	MOV	r3, #0				/* NULL parms for stack */	MOV	r2, #0	MOV	r1, #0	MOV	r0, #0	STMFD	sp!, {r0-r3}			/* push stack-based parms */	/* 	 * try to determine if the task is running at an inherited priority	 * and log a different event if so	 */	LDR	r12, L$_taskIdCurrent	LDR	r12, [r12]			/* r12 -> TCB */	LDR	r0, [r12, #WIND_TCB_PRIORITY]	LDR	r1, [r12, #WIND_TCB_PRI_NORMAL]	CMPS	r1, r0	MOVHI	r0, #EVENT_WIND_EXIT_NODISPATCH_PI 	MOVLS	r0, #EVENT_WIND_EXIT_NODISPATCH	/* r0 <- eventId */	MOV   	r1, #TRG_CLASS1_INDEX		/* r1 <- TRG_CLASS1_INDEX */						/* r2 <- NULL (from above) */						/* r3 <- NULL (from above) */	LDR	r12,L$__func_trgCheck 		/* trigCheck routine */#if	(ARM_THUMB)	LDR	r12, [r12]			/* get function address */	BL	FUNC(arm_call_via_r12)		/* and call it */#else	MOV	lr, pc				/* call function */	LDR	pc, [r12]#endif	/* (ARM_THUMB) */	ADD	sp, sp, #16		/* strip 4 parameters from stack */	B	resumeDispatch1	/* windview instrumentation - END */#endif	/* WV_INSTRUMENTATION *//********************************************************************************* checkTaskReady - check that taskIdCurrent is ready to run** This code branched to by windExit when it finds preemption is disabled.* It is possible that even though preemption is disabled, a context switch* must occur.  This situation arises when a task blocks during a preemption* lock.  So this routine checks if taskIdCurrent is ready to run, if not it* branches to save the context of taskIdCurrent, otherwise it falls thru to* check the work queue for any pending work.** REGISTERS*    r0 -> TCB*/checkTaskReady:	LDR	r1, [r0, #WIND_TCB_STATUS]	/* is task ready to run? */	TEQS	r1, #WIND_READY	BNE	saveTaskContext			/* if no, go and reschedule */	/*	 * task is ready to run	 *	 * FALL THROUGH TO checkWorkQ	 *//********************************************************************************* checkWorkQ -  check the work queue for any work to do** This code is branched to by windExit.  Currently taskIdCurrent is highest* priority ready task, but before we can return to it we must check the work* queue.  If there is work we empty it via doWorkPreSave, otherwise we unlock* interrupts, clear r0, and return to taskIdCurrent.** REGISTERS*    r0 scratch*    lr = link*/checkWorkQ:	/* disable interrupts */	MRS	r0, cpsr	ORR	r0, r0, #I_BIT	MSR	cpsr, r0	/* INTERRUPTS DISABLED */	LDR	r0, L$_workQIsEmpty	LDR	r0, [r0]	TEQS	r0, #0			/* empty? */	BEQ	doWorkPreSave		/* branch if not */	/* workQ is empty */#ifdef	WV_INSTRUMENTATION	/* windview instrumentation - BEGIN	 * exit windExit with no dispatch; point 4 in the windExit diagram.	 */	LDR	r0, L$_evtAction	/* is event logging or triggering? */	LDR	r0, [r0]	TEQS	r0, #0	BNE	instrumentDispatch4	/* branch if so */	/* instrumentation currently disabled */resumeDispatch4:	/* windview instrumentation - END */#endif	/* WV_INSTRUMENTATION */	/* release exclusion */	STMFD	sp!, {lr}	LDR	lr, L$_kernelState	MOV	r0, #0	STR	r0, [lr]	/* enable interrupts */	MRS	r0, cpsr	BIC	r0, r0, #I_BIT	MSR	cpsr, r0	/*	 * INTERRUPTS ENABLED

⌨️ 快捷键说明

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