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

📄 os_cpu_a.s

📁 移植ucos-ii到arm7tdmi核
💻 S
字号:
;//********************************************************************************************************
;//                                               uC/OS-II
;//                                         The Real-Time Kernel
;//
;//                        (c) Copyright 1992-1998, Jean J. Labrosse, Plantation, FL
;//                                          All Rights Reserved
;//
;//
;//                                           ARM Specific code
;//                                                                              
;//
;// File : OS_CPU_A.ASM
;// By   : Jean J. Labrosse
;//********************************************************************************************************
	
	AREA	|SUBR|,CODE,READONLY 
            EXPORT 	OSTickISR
            EXPORT 	OSStartHighRdy
            EXPORT 	OS_TASK_SW
            EXPORT 	OSIntCtxSw

            IMPORT 	OSIntExit
            IMPORT	OSIntEnter
            IMPORT  OSTimeTick
            IMPORT  OSTaskSwHook
            
            IMPORT	OSIntNesting
            IMPORT  OSPrioHighRdy
            IMPORT  OSPrioCur
            IMPORT  OSRunning
            IMPORT  OSTCBCur
            IMPORT  OSTCBHighRdy
            
            IMPORT  I_ISPC
            IMPORT  BIT_TIMER0
                     
            IMPORT	SYSMODE
          	IMPORT  SVCMODE
          	IMPORT  IRQMODE
	          


;//*********************************************************************************************************
;//                                          START MULTITASKING
;//                                       void OSStartHighRdy(void)
;//
;// The stack frame is assumed to look as follows:
;//
;// OSTCBHighRdy->OSTCBStkPtr --> 	PC                               (Low memory)
;//									LR
;//                               	R12
;//                               	R11
;//                               	R10
;//                               	R9
;//                               	R8
;//                               	R7
;//                               	R6
;//								  	R5
;//								  	R4
;//								  	R3
;//								  	R2
;//								  	R1
;//								  	R0	(unsigned int)pdata
;//                               	CPSR								(High memory)               
;// Note :   OSStartHighRdy() MUST:
;//           a) Call OSTaskSwHook() then,
;//           b) Set OSRunning to TRUE,
;//           c) Switch to the highest priority task.
;//*********************************************************************************************************

OSStartHighRdy
	MSR	CPSR_c,#SYSMODE 						;//enter system mode, and disable interrupt
	
	BL	OSTaskSwHook
	  
    LDR R6,=OSTCBHighRdy						      
    LDR	R6,[R6]	
    LDR	R4,[R6]									;//now R4=OSTCBHighRdy->OSTCBStkPtr
    
TaskStart
    LDR R7,=OSRunning							;//OSRunning = TRUE
    MOV R8,#1
    STRB R8,[R7]   
    
    
    ADD SP,R4,#56								;//restore LR of task
    LDR LR,[SP] 	
	
	MSR	CPSR_c,#SVCMODE 						;//Switch to SVC mode , and ready to start the highest priority task    
  
    MOV SP,R4									;//SP = OSTCBHighRdy->OSTCBStkPtr; 
    LDMFD SP!,{R4}
    MSR   SPSR_cxsf,R4     						
   	LDMFD SP!,{R0-R12,LR,PC}^					;//start task			
    
           			 
            
            
           		


;//*********************************************************************************************************
;//                                PERFORM A CONTEXT SWITCH (From task level)
;//                                           void OSCtxSw(void)
;//
;// Note(s): 1) Upon entry, 
;//             OSTCBCur     points to the OS_TCB of the task to suspend
;//             OSTCBHighRdy points to the OS_TCB of the task to resume
;//
;//          2) now,system has already entered into SVC mode, and the contexts of task to be suspend have stored in
;//				SVC stack,the SVC stack frame looks as follows:
;//				notes:SPSR_SVC=CPSR_task;		  
;//												
;//												LR                             	(High memory)
;//                               				R12
;//								  				R3
;//								  				R2
;//								  				R1
;//								  	SP_svc-->	R0	(unsigned int)pdata 		(Low memory)
;//  									  						                 				
;//
;//          3) The stack frame of the task to resume looks as follows:
;// 
;//												PC                             	(High memory)
;//												LR
;//                               				R12
;//                               				R11
;//                               				R10
;//                               				R9
;//                               				R8
;//                               				R7
;//                               				R6
;//								  				R5
;//								 				R4
;//								  				R3
;//								  				R2
;//								  				R1
;//								  				R0	(unsigned int)pdata
;//  			OSTCBHighRdy->OSTCBStkPtr -->   CPSR						   (Low memory)               				
;//*********************************************************************************************************
OS_TASK_SW 
		;//Store the context of the task to suspend	
		
		LDR		R2,[SP,#20]										;//get PC
		LDR		R12,[SP,#16]									;//get R12
		MRS		R0,CPSR
		
		MSR		CPSR_c,#SYSMODE
		MOV		R1,LR
		STMFD	SP!,{R1-R2}										;//store PC,LR,R12-R4
		STMFD	SP!,{R4-R12}
		
		MSR		CPSR_c,R0										;//Return previous mode
		LDMFD	SP!,{R4-R7}
		MRS		R3,SPSR										
		ADD		SP,SP,#8										;//pop PC and R12
		
		MSR		CPSR_c,#SYSMODE
		STMFD   SP!,{R4-R7}										;//store PC,LR,R3-R0
		STMFD	SP!,{R3}										;//Store CPSR
		
		LDR		R1,=OSTCBCur									;//OSTCBCur->OSTCBStkPtr = Stack pointer
		LDR		R1,[R1]
		STR		SP,[R1] 
		;//Now all of the contexts of task to suspend have stored in task stack		
		
		BL		OSTaskSwHook
		
		
		LDR		R4,=OSTCBHighRdy								;//OSTCBCur=OSTCBHighRdy
		LDR		R4,[R4]
		LDR     R6,=OSTCBCur
		STR		R4,[R6] 										
		LDR		R4,[R4]											;//now R4=OSTCBHighRdy->OSTCBStkPtr

		   
		LDR     R7,=OSPrioHighRdy								;//OSPrioCur=OSPrioHighRdy
		LDRB	R7,[R7]											;//note: OSPrioHighRdy and OSPrioCur are stored with 8bits
		LDR		R8,=OSPrioCur									
		STRB    R7,[R8] 
		
		B       TaskStart		

		
		
		
		
	
                  
;//*********************************************************************************************************
;//                                PERFORM A CONTEXT SWITCH (From an ISR)
;//                                        void OSIntCtxSw(void)
;//
;// Note(s): 1) Upon entry, 
;//             OSTCBCur     points to the OS_TCB of the task to suspend
;//             OSTCBHighRdy points to the OS_TCB of the task to resume
;//
;//          2) The contexts of each register in IRQ mode looks as follows:
;//
;//												LR	(the return address of task to suspend, i.e. PC)	(High memory)													
;//												R12
;//								  				R3
;//								  				R2
;//								  				R1
;//								  				R0	(unsigned int)pdata									(Low memory)								
;//
;//
;//								The CPSR value of task to suspend store in SPSR_irq 
;//								The return address of OSIntExit() store in LR(R14_irq)
;//
;//          3) The stack frame of the task to resume looks as follows:
;// 
;//   											PC
;//												LR														(High memory)
;//                               				R12
;//                               				R11
;//                               				R10
;//                               				R9
;//                               				R8
;//                               				R7
;//                               				R6
;//								  				R5
;//								 				R4
;//								  				R3
;//								  				R2
;//								  				R1
;//								  				R0	(unsigned int)pdata
;//OSTCBHighRdy->OSTCBStkPtr -->                CPSR  													(Low memory)    
;//*********************************************************************************************************
 
OSIntCtxSw 
				
		B  OS_TASK_SW  
		
		
		



;//*********************************************************************************************************
;// the following  C-like pseudo-code describe  the operation being performed in the code below
;//
;//	void OSTickISR(void)
;// {
;// 	Store the value of register;
;//   	Call OSIntEnter(), or OSIntNesting+1;
;//    	Call OSTimeTick(); 
;//    	Call OSIntExit();
;//    	Restore the value of register;
;//    	RIT;
;//	}
;// 
;//Notes:Call OSIntEnter() or OSIntNesting+1,Call OSIntExit(),Restore the value of register,and RIT are handled 
;//in file InitTarget.s, So Call OSTimeTick() is the only work to do in OSTickISR().
;//*********************************************************************************************************

OSTickISR 																						
	
		;//end of interrupt, and clear the pending bit of interrupt
		;//the following code is Closely linked to the real CPU 
		LDR		R0,=I_ISPC										;//I_ISPC
		LDR		R1,=BIT_TIMER0									;//Clear the pending bit of the timer0 
		STR		R1,[R0]
		
		BL      OSTimeTick
		
		END	
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		
		           

⌨️ 快捷键说明

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