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

📄 os_cpu_a.asm

📁 UCOS-II在凌阳61单片机上的移植 代码还附带三个测试例子
💻 ASM
字号:
.include  hardware.inc
.EXTERNAL _OSTaskSwHook;
.EXTERNAL _OSIntEnter
.EXTERNAL _OSTimeTick
.EXTERNAL _OSIntExit
.EXTERNAL _OSTCBCur
.EXTERNAL _OSTCBHighRdy
.EXTERNAL _OSRunning
.EXTERNAL _OSPrioHighRdy
.EXTERNAL _OSPrioCur
.EXTERNAL _OSIntNesting
.EXTERNAL _InterruptC

.CODE 
.PUBLIC _OSStartHighRdy
_OSStartHighRdy:
		CALL  _OSTaskSwHook
		
		R1=0x0001            //将系统运行标志置1,表示系统开始运行,可以进行任务调度
		[_OSRunning]=R1
		
		R1=[_OSTCBCur]       //取得当前可以运行的任务的TCB块首地址
		SP=[R1]              //在TCB块的首地址(第一项)中存放的是该任务的堆栈地址
		POP R1 FROM [SP]
		[_InterruptC]=R1      //弹出该任务的中断开关次数标志
		POP R1,R5 FROM [SP]
		RETI


.PUBLIC _OSCtxSw
_OSCtxSw:
		PUSH R1,R5 TO [SP]            //调用子程序时会自动将PC,SR压入栈中,不需要再保存 
		R1=[_InterruptC]
		PUSH R1 TO [SP]               //压入该任务的中断开关次数标志 
		
		//保存即将挂起任务的堆栈地址
		R2=[_OSTCBCur]                //取得当前任务(即将挂起的任务)的TCB首地址      
		[R2]=SP                       //在TCB的第一项(首地址)中保存堆栈地址
		CALL _OSTaskSwHook
		
		//OSUCBCur=OSTCBHighRdy
		R1=_OSTCBCur                  //取得 OSTCBCur的地址
		R2=[_OSTCBHighRdy]            //取得 OSTCBHighRdy所指向的TCB的首地址
		[R1]=R2                       //将优先级最高的就绪态任务的TCB的首地址赋予 OSTCBCur
		
		//OSPrioCur=OSPrioHighRdy
		R1=[_OSPrioHighRdy]            
		[_OSPrioCur]=R1
		
		//切换至新的任务堆栈
		R1=[_OSTCBHighRdy]            //取得将要运行的任务的TCB块的首地址(其中放置了该任务的堆栈地址)
		SP=[R1]
		POP R1 FROM [SP]
		[_InterruptC]=R1               //弹出将要运行的任务的中断开关次数
		CMP R1,0                      //查看是否需要开中断
		JNE KAI                       //如果任务原先是关中断下被挂起,则直接返回
		INT IRQ                       //否则开中断返回
KAI:	POP R1,R5 FROM [SP]           
		RETI

		
.PUBLIC _OSIntCtxSw
_OSIntCtxSw:                          //将发生任务切换,将要挂起的任务的所有的寄存器包括堆栈地址已经保存
		CALL _OSTaskSwHook

		//OSUCBCur=OSTCBHighRdy
		R1=_OSTCBCur                   
		R2=[_OSTCBHighRdy]
		[R1]=R2
		
		//OSPrioCur=OSPrioHighRdy
		R1=[_OSPrioHighRdy]            
		[_OSPrioCur]=R1
		
		//切换至新的任务堆栈
		R1=[_OSTCBHighRdy]             
		SP=[R1]
		
		POP R1 FROM [SP]             //弹出将要运行任务的中断开关次数标志
		[_InterruptC]=R1
		CMP R1,0                      //查看是否需要关中断
		JE KAI1                       //如果任务原先是关中断下被挂起
		IRQ OFF                       //则关中断返回
KAI1:	POP R1,R5 FROM [SP]
		RETI


.PUBLIC _InitSystem
_InitSystem:
		INT OFF
		PUSH R1,R5 to [SP]
		R1 = 0xFFFF 				//设定IOB口为同相输出口;
		[P_IOB_Attrib] = R1 
		[P_IOB_Dir] = R1 
		[P_IOB_Data] = R1 
		
		//R1=0xFFFF
		[P_TimeBase_Setup]=R1       //设置64Hz TMB1
		
		R1 = 0x0002			        //开中断IRQ6_TMB1,64Hz
		[P_INT_Ctrl] = R1 
		[P_INT_Ctrl_New] = R1
		
		INT	IRQ                     //开中断并返回
		POP R1,R5 from [SP] 		
		RETF

.public _display
_display:
		PUSH R1,R5 to [SP]
		R1=SP+8
		R1=[R1]
		[P_IOB_Data]=R1
		POP R1,R5 from [SP]
		RETF		
			
.TEXT
.PUBLIC _IRQ6
_IRQ6:
		PUSH R1,R5 TO [SP]
		R1=0x0002
		[P_INT_Clear]=R1   //清中断标志
		
		CALL _Clear_Dog    //清看门狗
    	
		R1=[_OSIntNesting]   //中断嵌套标志加1
		R1+=1
		[_OSIntNesting]=R1
		
		CMP R1,1            
		JNE TCB             //如果没有发生嵌套中断
		R1=[_InterruptC]     //保存中断开关次数标志
		PUSH R1 TO [SP]
		R2=[_OSTCBCur]      //则保存当前堆栈地址
		[R2]=SP
		
TCB:	CALL _OSTimeTick
		CALL _OSIntExit
		
		R1=[_OSIntNesting]
		CMP R1,0
		JNE TCB1            //不等于0则表示为中断嵌套返回
		POP R1 FROM [SP]    //如果能执行到此,则说明不需要进行任务切换,也就无需进行开关中断处理
		[_InterruptC]=R1    //但需要弹出中断计数器以调整堆栈指针到正确位置
TCB1:	POP  R1,R5 FROM [SP]
		RETI


.PUBLIC _Clear_Dog
_Clear_Dog:
 		R1 = 0x0001;
    	[P_Watchdog_Clear] = R1    //清看门狗
    	RETF		

⌨️ 快捷键说明

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