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

📄 kern600.s

📁 各种硬件平台上的us OS移植实例(arm6)
💻 S
📖 第 1 页 / 共 2 页
字号:
    	TTL 	uC/OS ARM kernel routines > kern600.s    	; ---------------------------------------------------------------------    	; This file provides the lo-level machine dependant ARM    	; support for the uC/OS system.    	;    	; $Revision: 0.1 $    	;   $Author: jsmith $    	;     $Date: 941103 $    	;    	; Original author: Geary Chopoff.    	;    	; Copyright (c) 1993-1994, VLSI Technology Inc. All Rights Reserved.    	; ---------------------------------------------------------------------   	; NOTEs:    	;    	; There is a lot of ARM magic in this file to do deal with    	; preserving register state over interrupts and context    	; switches. All of the features are fully documented in the    	; ARM data-sheet though, and most of the complication arises    	; just from the various options depending on the state of the    	; ARM at the instance of the event.    	;   	; All threads are started in USR mode. If a thread needs to    	; execute in a particular processor mode then it should use    	; the Demon SWIs available. This includes the "main"    	; application entry point started from the C-Demon world.    	;       	; The uC/OS ARM system *ONLY* supports threads that conform to    	; the APCS-3 (ARM Procedure Calling Standard version 3). Part    	; of this standard dictates that there is always a FD (Full    	; Descending) stack available in r13, with *NO* information    	; stored beneath it.    	;    	; The uC/OS ARM system *NEEDS* to provide its own IRQ and FIQ    	; vector handlers to deal with the magic of providing clean    	; context switches. To perform a context switch cleanly the    	; interrupt code needs to have access to *ALL* of the    	; processor state at the instance of the    	; interrupt. Unfortunately this limits the coding of the main    	; interrupt handler to assembler since if we use the special    	; __irq compiler feature, and code the handler in C then we    	; will not have access to the initial stack and register    	; contents. There is no frame-pointer support with the __irq    	; option, so it would not be possible to decode the stack    	; frame to recover the required information (plus scanning the    	; frame would be slow). We cannot code the interrupt handler    	; as a normal C function (with call frame support) since IRQ    	; and FIQ require special processing to perform the return,    	; plus they have some private (banked) registers.    	;    	; This ARM6x0 targetted version of uC/OS does *NOT* provide    	; any FIQ support. The standard C-Demon FIQ handler is left    	; intact. If FIQ support is required, then similar processing    	; to the "IRQHandler" code below needs to be provided for FIQ    	; interrupts.    	;    	; Only the following uC/OS routines can safely be called from    	; an ARM uC/OS ISR:    	;    	;   	OSIntEnter  	; performed by the system interrupt handler    	;   	OSIntExit   	; performed by the system interrupt handler    	;   	OSTimeTick  	; to increment the scheduling clock    	;   	IRQMboxPost 	; to post a message to a mailbox    	;    	; The actions of calling a routine *NOT* listed above is    	; undefined, and will probably result in a system crash.     	; ---------------------------------------------------------------------	INCLUDE	modes_h.s	; support for ARM600 modes	INCLUDE	swis_h.s	; support for SWI functions    	INCLUDE	driver_h.s  	; target architecture specific definitions    	; ---------------------------------------------------------------------	IMPORT	OSIntEnter	; void OSIntEnter(void) ;	IMPORT	OSIntExit	; int OSIntExit(void) ;	IMPORT	OSTimeTick	; void OSTimeTick(void) ;	IMPORT	OSTCBCur	; OS_TCB *OSTCBCur ;	IMPORT	OSTCBHighRdy	; OS_TCB *OSTCBHighRdy ;    	IMPORT	IRQvectors  	; IRQHandlerFn IRQvectors[NUMIRQS] ;    	IMPORT	FIQvectors  	; FIQHandlerFn FIQvectors[NUMFIQS] ;    	; ---------------------------------------------------------------------    	EXPORT	IRQHandler  	; non APCS-3 conforming routine    	EXPORT	DummyIRQ    	; IRQHandlerFn DummyIRQ ;    	EXPORT	DummyFIQ    	; FIQHandlerFn DummyFIQ ;	EXPORT	OSStartHighRdy	; void OSStartHighRdy(void) ;	EXPORT	OSCtxSw		; void OSCtxSw(void) ;	EXPORT	InitTask	; unsigned int *InitTask(uint *pstk) ;    	; ---------------------------------------------------------------------    	; The following manifests *ASSUME* the shape of the uC/OS    	; OS_TCB structure. At the moment there is no build- or    	; run-time check that these match the "ucos.h" master    	; definitions.    	    	    	^   	0   ; shape of OS_TCB structureOSTCB_OSTCBStkPtr   	#   	4   ; a pointer to the active stack pointer    	; We are not interested in any other OS_TCB fields for this    	; code so this is not a complete definition of the structure.    	; ---------------------------------------------------------------------    	; The following manifests define the shape of a stored thread    	; context. These contexts are stored on the stack at the    	; instance of a context switch. The manifests are given as    	; offsets from the stack pointer after the context space has    	; been allocated.    	;    	; If we were desperate to shave a few more cycles off the    	; context switch time we could re-order these fields to better    	; match the instruction sequences needed to load and save the    	; context (i.e. to make optimium use of writeback, etc.).    	;    	    	    	^   	0   ; offsets within stacked contextCtx_a1	    	    	#   	4   ;  r0Ctx_a2	    	    	#   	4   ;  r1Ctx_a3	    	    	#   	4   ;  r2Ctx_a4	    	    	#   	4   ;  r3Ctx_v1	    	    	#   	4   ;  r4Ctx_v2	    	    	#   	4   ;  r5Ctx_v3	    	    	#   	4   ;  r6Ctx_v4	    	    	#   	4   ;  r7Ctx_v5	    	    	#   	4   ;  r8Ctx_v6	    	    	#   	4   ;  r9 (possibly the static-base)Ctx_sl	    	    	#   	4   ; r10 stack-limit or v7Ctx_fp	    	    	#   	4   ; r11 frame-pointerCtx_ip	    	    	#   	4   ; r12 temporaryCtx_sp	    	    	#   	4   ; r13 stack-pointerCtx_lr	    	    	#   	4   ; r14 link registerCtx_pc	    	    	#   	4   ; Program Counter of de-scheduled threadCtx_CPSR    	    	#   	4   ; PSR describing de-scheduled threadCtx_SPSR    	    	#   	4   ; Saved PSR (if priviledged mode)Ctx_USR_v5  	    	#   	4   ; USR mode r8 (if required)Ctx_USR_v6  	    	#   	4   ; USR mode r9 (if required)Ctx_USR_sl  	    	#   	4   ; USR mode r10 (if required)Ctx_USR_fp  	    	#   	4   ; USR mode r11 (if required)Ctx_USR_ip  	    	#   	4   ; USR mode r12 (if required)Ctx_USR_sp  	    	#   	4   ; USR mode stack pointer (if required)Ctx_USR_lr  	    	#   	4   ; USR mode link register (if required)Ctx_sizeof  	    	#   	0   ; size of a stacked context    	; ---------------------------------------------------------------------	AREA	|ucos$$kern600|,CODE,READONLY    	; ---------------------------------------------------------------------    	; The following macros provide code to save a context and to    	; startup the highest priority pending task. We use macros to    	; provide multiple in-line versions of this code to gain    	; performance. If size becomes an issue then a single version    	; of each routine could be created, with the macro calls    	; changed to branches to the required single version:    	MACRO$label	SAVECONTEXT$label	; sp = current task stack pointer    	SUB 	sp,sp,#Ctx_sizeof   	; create context structure    	STR 	lr,[sp,#Ctx_pc]	    	; the return address we want    	MOV 	lr,sp	    	    	; take a copy of the context pointer    	STMIA	lr,{a1-ip} 	    	; and stack most of the state    	MRS 	a1,CPSR	    	    	; get the current PSR    	STR 	a1,[sp,#Ctx_CPSR]   	; and store into the context    	    	ANDS 	a1,a1,#SubModeMask    	; check for USR mode task    	BEQ 	%FT01	    	    	; no more work for USR mode task    	MRS 	a2,SPSR	    	    	; get the saved PSR    	STR 	a2,[sp,#Ctx_SPSR]   	; and store it    	TEQ 	a1,#(FIQmode :AND: SubModeMask)	; check for FIQ mode    	ADDEQ 	a2,sp,#Ctx_USR_v5   	; reference the USR register hold slots    	ADDNE 	a2,sp,#Ctx_USR_sp   	; reference the USR register hold slots    	STMEQIA	a2,{v5-lr}^ 	    	; force USR mode transfer    	STMNEIA	a2,{sp-lr}^ 	    	; force USR mode transfer01    	; sp = pointer to newly created context on current task stack    	; All the other registers are now available as work registers:	LDR	a1,=OSTCBCur	    	; point at current TCB	LDR	a2,[a1,#0x00]		; get pointer to context pointer save location	STR	sp,[a2,#0x00]	    	; save sp (context pointer)    	MEND    	MACRO$label	STARTNEXTTASK$label	; This code assumes that all the registers are available for    	; its use with the following exceptions:    	MRS 	a1,CPSR	    	    ; get current PSR    	TST 	a1,#SubModeMask	    ; check for USR mode    	SWIEQ	EnterOS    	    ; get SVC mode for USR thread    	; We execute the rest of the restore context code in a    	; priviledged mode:    	;	LDR	a2,=OSTCBHighRdy    ; reference the highest priority task holder	LDR	a2,[a2]		    ; and get the OS_TCB pointer for the pending task	LDR	a1,=OSTCBCur	    ; point at current context holder location	STR	a2,[a1,#0x00]  	    ; make the new task the current	LDR	a1,[a2,#0x00]	    ; get the context pointer    	;    	; NOTE: If we have interrupts enabled we cannot update the    	; stack-pointer until *AFTER* we have loaded all the context,    	; since we may be interrupted by code that attempts to save a    	; new context under the stack-pointer.    	;    	LDR 	a2,[a1,#Ctx_CPSR]   ; get destination PSR    	ANDS	a3,a2,#SubModeMask  ; check if destination is USR    	BEQ 	%FT01	    	    ; no need to do much if starting USR    	;       	; We know we are starting a priviledged mode:    	MSR 	CPSR,a2	    	    ; switch to destination mode    	TEQ 	a3,#(FIQmode :AND: SubModeMask)	; check if FIQ    	ADDNE	a3,a1,#Ctx_USR_sp   ; reference USR banked registers    	LDMNEIA	a3,{sp-lr}^ 	    ; force USR mode transfer for SVC,IRQ,ABT and UND    	ADDEQ	a3,a1,#Ctx_USR_v5   ; reference USR banked registers    	LDMEQIA	a3,{v5-lr}^ 	    ; force USR mode transfer for FIQ    	; We have now restored the banked USR registers.    	;    	LDR 	a3,[a1,#Ctx_SPSR]   ; recover SPSR for this mode    	MSR 	SPSR,a3	    	    ; and reload it01  	; We branch here if re-starting a USR thread.    	; This next MSR is for the benefit of USR threads being    	; started. If we are starting a privilidged mode we will    	; already be in the correct mode, however this doesn't hurt    	; and makes the code simpler:    	MSR 	CPSR,a2	    	    ; switch to destination mode    	; We are now *DEFINATELY* executing in the destination mode    	; with the desired IRQ and FIQ state.    	MOV 	sp,a1	    	    ; reference the context    	LDMFD	sp,{a1-ip} 	    ; load most of the register state    	LDR 	lr,[sp,#Ctx_pc]     ; recover the desired PC    	; All the other state has now been loaded from the stacked    	; context:    	ADD 	sp,sp,#Ctx_sizeof   ; dump the context allocation    	MOV 	pc,lr	    	    ; and continue with the new task    	MEND    	; ---------------------------------------------------------------------    	; -- interrupt handling -----------------------------------------------    	; ---------------------------------------------------------------------    	; This routine should be attached to the ARM IRQ vector. It    	; provides the lo-level uC/OS interrupt handling, and deals    	; with context switching as a result of the application    	; attached ISR routines.IRQHandler    	; in:	IRQ32 mode; IRQs disabled; FIQs undefined.    	;   	r13 = FD stack    	;   	r14 = (return address + 4)

⌨️ 快捷键说明

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