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

📄 os_cpu_a.asm

📁 基于51单片机来实现UCOS用一个串口来看到实现阶段
💻 ASM
字号:
NAME	OS_CPU_A
;//----------------------------------------------------------------
;用于C函数调用的汇编代码
?PR?OSStartHighRdy?OS_CPU_A        SEGMENT CODE 
?PR?OSCtxSw?OS_CPU_A               SEGMENT CODE 
?PR?OSIntCtxSw?OS_CPU_A            SEGMENT CODE 
?PR?OSTickISR?OS_CPU_A             SEGMENT CODE 
;//----------------------------------------------------------------
;?PR?_EXTERN_0_ISR_?OS_CPU_A        SEGMENT CODE 
;?PR?_EXTERN_1_ISR_?OS_CPU_A        SEGMENT CODE 
;?PR?_TIME_1_ISR_?OS_CPU_A          SEGMENT CODE 
 ?PR?_SERY_ISR_?OS_CPU_A            SEGMENT CODE 
;//----------------------------------------------------------------
;汇编调用外部C函数和变量       
		EXTRN	IDATA (OSTCBCur)
		EXTRN	IDATA (OSTCBHighRdy)
		EXTRN	IDATA (OSRunning)
		EXTRN	IDATA (OSPrioCur)
		EXTRN	IDATA (OSPrioHighRdy)
		;//--------------------------------------------------------
		EXTRN	CODE (OSTimeTick)
		EXTRN	CODE (_?OSTaskSwHook)
		EXTRN	CODE (OSIntExit)
		;EXTRN	CODE (OSTCBSWHook)
		EXTRN	CODE (OSIntEnter)
		;EXTRN	CODE (TickTime)
		;//--------------------------------------------------------
		;EXTRN	CODE (ExternInt0)
		;EXTRN	CODE (ExternInt1)
		;EXTRN	CODE (Time1Int)
		 EXTRN	CODE (SeryInt)
		;//--------------------------------------------------------
		;PUBLIC  Extern_0_ISR 
		;PUBLIC  Extern_1_ISR
		;PUBLIC  Time_1_ISR
		 PUBLIC  Sery_ISR
		;//--------------------------------------------------------
		;EXTRN	CODE (OSTickISRHook)
		;//--------------------------------------------------------
		PUBLIC	OSTickISR
		PUBLIC	OSIntCtxSw
		PUBLIC	OSCtxSw
		PUBLIC	OSStartHighRdy
		;//--------------------------------------------------------
?STACK SEGMENT IDATA
RSEG ?STACK
OSStack:
DS 40H
OSStkStart IDATA OSStack-1
;//----------------------------------------------------------------
PushAll MACRO
              PUSH   PSW		
		PUSH   ACC
		PUSH   B
		PUSH   DPL
		PUSH   DPH

		MOV    A,R0
		PUSH   ACC
		MOV    A,R1
		PUSH   ACC
		MOV    A,R2
		PUSH   ACC
		MOV    A,R3
		PUSH   ACC
		MOV    A,R4
		PUSH   ACC
		MOV    A,R5
		PUSH   ACC
		MOV    A,R6
		PUSH   ACC
		MOV    A,R7
		PUSH   ACC
		ENDM
;//----------------------------------------------------------------       
;//----------------------------------------------------------------
PopAll  MACRO
              POP   ACC
		MOV   R7,A
		POP   ACC
		MOV   R6,A
		POP   ACC
		MOV   R5,A
		POP   ACC
		MOV   R4,A
		POP   ACC
		MOV   R3,A
		POP   ACC
		MOV   R2,A
		POP   ACC
		MOV   R1,A
		POP   ACC
		MOV   R0,A

		POP   DPL
		POP   DPH
		POP   B
		POP   ACC
		POP   PSW
		ENDM 
;//----------------------------------------------------------------
RSEG  ?PR?OSStartHighRdy?OS_CPU_A	   //起始调度程序
OSStartHighRdy:						   
	   USING	0					   //多任务建立,当前TCB已指向最高优先级任务
	                                   //只需恢复堆栈即可

                                       //所有的最高优先级就绪任务从此处恢复堆栈到系统栈
OSCtxSw_in:
        MOV   R0,#LOW  (OSTCBCur)	  

        INC   R0
        MOV   DPH,@R0
        INC   R0
        MOV   DPL,@R0				    //进入调度后取得当前任务TCB指针转装入DPTR
		        
    	INC   DPTR
        MOVX  A, @DPTR
    	MOV   R1,A
	    INC   DPTR
   	    MOVX  A, @DPTR
	    MOV   R0,A
	    MOV   DPH, R1
	    MOV   DPL, R0				    //取得当前任务的堆栈底指针装入DPTR
	
	    MOVX  A, @DPTR
	    MOV   R5,A						//取得当前堆栈长度(有用)来自于用户堆栈

	    MOV  R0,#OSStkStart				//取得当前系统堆栈的更低一个地址放入R0
        
restore_stack:

        INC  DPTR
        INC  R0
        MOVX A,@DPTR
        MOV  @R0,A
        DJNZ R5,restore_stack			//将当前任务堆栈拷贝到系统堆栈
    				
        MOV  SP,R0					    //恢复堆栈系统堆栈指针SP	
    
        ;OSRunning=TRUE
        MOV  R0,#LOW (OSRunning)
        MOV  @R0,#01
    									
        POPALL							//出栈寄存器数据恢复
        SETB EA                         //开中断
        RETI						    //任务地址恢复


;//----------------------------------------------------------------	

;//----------------------------------------------------------------
RSEG  ?PR?OSCtxSw?OS_CPU_A					//任务切换程序 

                                            //当前任务的保护堆栈从这里开始
OSCtxSw:
        PushAll								//当前任务的寄存器入系统栈
OSIntCtxSw_in:		
        MOV  A,SP
        CLR  C							    
        SUBB A,#OSStkStart
        MOV  R5,A      						//获得当前系统栈的长度装入R5
    
        ;OSTCBCur ===> DPTR 
        MOV  R0,#LOW (OSTCBCur) 
        INC  R0
        MOV  DPH,@R0    
        INC  R0
        MOV  DPL,@R0						 //获得当前任务的TCB指针装入DPTR
    
        ;OSTCBCur->OSTCBStkPtr ===> DPTR 
        INC  DPTR        
        MOVX A,@DPTR     
        MOV  R0,A
        INC  DPTR
        MOVX A,@DPTR
        MOV  R1,A
        MOV  DPH,R0
        MOV  DPL,R1							 //获得当前任务堆栈的指针装入DPTR
        
     
        MOV  A,R5							 //将系统堆栈长度(也即为当前任务栈长度)装入当前任务栈指针所指处
        MOVX @DPTR,A                         //(任务栈指针永远指向这个位置)用于装栈大小
    
        MOV  R0,#OSStkStart  				 //取得当前系统堆栈的更低一个地址放入R0
save_stack:
    
        INC  DPTR
        INC  R0
        MOV  A,@R0
        MOVX @DPTR,A
        DJNZ R5,save_stack					 //将系统栈拷贝到当前任务栈

        LCALL _?OSTaskSwHook					 //最高优先级任务代替当前任务成为当前任务
        LJMP  OSCtxSw_in
;//------------------------------------------
	
;//----------------------------------------------------------------

;//----------------------------------------------------------------
RSEG  ?PR?OSIntCtxSw?OS_CPU_A				 //中断返回时的任务调度
OSIntCtxSw:
	
		CLR     EA
		MOV	A, SP
		CLR	C
		SUBB	A, #4
		MOV	SP,A							 //由于之前调用了OSIntExit(),OSIntCtxSw()过程
										     //多压入堆栈,所以系统堆栈指针SP-4	
		LJMP    OSIntCtxSw_in				 //中断结束保护堆栈
;//----------------------------------------------------------------

;//----------------------------------------------------------------
CSEG	AT	0000BH						    //定时器中断处理程序
	LJMP	OSTickISR
RSEG  ?PR?OSTickISR?OS_CPU_A
OSTickISR:
        USING 0

        PushAll							    //保存当前任务寄存器到系统堆栈
	    CLR    TR0   
        MOV    TH0,#70H
        MOV    TL0,#00H
        SETB   TR0

        LCALL  OSIntEnter
        LCALL  OSTimeTick
        LCALL  OSIntExit	                //比较当前任务的优先级与最高优先级
		                                    //如果相等退出系统直接出栈,(由下面继续的代码完成)
											//任务继续运行
											//如果不等调再用OSIntCtxSw,所以SP-4
        PopAll
        RETI 
;//----------------------------------------------------------------

;//---------------------------------------------------------------- 

;CSEG	AT	00003H
;	LJMP	Extern_0_ISR
;      RSEG    ?PR?_EXTERN_0_ISR_?OS_CPU_A 
;Extern_0_ISR:
;	USING   0
;	PushAll
;	LCALL   OSIntEnter
;	LCALL   ExternInt0
;      LCALL   OSIntExit
;	PopAll
;	RETI
;//---------------------------------------------------------------- 
;//---------------------------------------------------------------- 
;CSEG	AT	00013H
;	LJMP	Extern_1_ISR
;	RSEG    ?PR?_EXTERN_1_ISR_?OS_CPU_A 
;Extern_1_ISR:
;	USING   0
;	PushAll
;	LCALL   OSIntEnter
;	LCALL   ExternInt1
;	LCALL   OSIntExit
;	PopAll
;	RETI
;//----------------------------------------------------------------
;//---------------------------------------------------------------- 
;CSEG	AT	0001BH
;	LJMP	Time_1_ISR
;	RSEG    ?PR?_TIME_1_ISR_?OS_CPU_A 
;Time_1_ISR:
;	USING   0
;	PushAll
;	LCALL   OSIntEnter
;	LCALL   Time1Int
;	LCALL   OSIntExit
;	PopAll
;	RETI
;//----------------------------------------------------------------
;//---------------------------------------------------------------- 
 CSEG	AT	00023H
 	LJMP	Sery_ISR
 	RSEG    ?PR?_SERY_ISR_?OS_CPU_A 
 Sery_ISR:
 	USING   0
 	PushAll
	LCALL   OSIntEnter
 	LCALL   SeryInt
  	LCALL   OSIntExit
 	PopAll
 	RETI
;//----------------------------------------------------------------
;//---------------------------------------------------------------- 
        END
        
        

⌨️ 快捷键说明

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