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

📄 os_cpu_a.asm

📁 c的源码
💻 ASM
字号:
/*
**********************************************************************************************
*                                                uC/OS-II
*                                          The Real-Time Kernel
*                              ADSP-21065L SHARC Specific Code version 1.1
*
* File : OS_CPU_A.ASM
* By   : Bertrand Hurst, Francois Veuve, Cedric Bornand (dspos@engineer.com)
*        CETT - MIS
*        Rte de Galilee 15
*        1400 Yverdon
*        Switzerland
**********************************************************************************************
*/
#include <asm_sprt.h>
#include <def21065l.h>
#include "os_cfg.h"

.SEGMENT/DM seg_dmda;
.var temp;
.ENDSEG;

.SEGMENT/PM seg_pmco;

/* Functions defined hereunder */
.global _TimerInit;
.global _OSStartHighRdy;
.global _OSCtxSw;
.global _OSIntCtxSw;
.global _OSTickISR;

/* Functions and variables defined in other files */
#if OS_CPU_HOOKS_EN
.extern _OSTaskSwHook;
#endif

.extern _OSRunning;
.extern _OSTCBHighRdy;
.extern _OSTCBur;
.extern _OSPrioCur;
.extern _OSPrioHighRdy;

.extern _OSIntEnter;
.extern _OSTimeTick;
.extern _OSIntExit;

/*****************************************************************
	Interrupt vector for timer ticks
*****************************************************************/
_TickVect:
	jump (_OSTickISR) (db);
	bit clr mode1 0x1000;
	nop;
	nop;

/*****************************************************************
	Initializes the timer and the interrupts
*****************************************************************/
_TimerInit:

	leaf_entry;

	/* Copy the timer ticks' interrupt vector */	
	px = pm(_TickVect);
	pm(0x805c) = px;
	px = pm(_TickVect+1);
	pm(0x805d) = px;
	px = pm(_TickVect+2);
	pm(0x805e) = px;
	px = pm(_TickVect+3);
	pm(0x805f) = px;

	/* Initializes the timer 0 */
	r0 = 60000000 / OS_TICKS_PER_SEC;  /* Selects the time between ticks for a 60 MHz SHARC */
	dm(TPERIOD0) = r0;			
	r0 = 0x0;
	dm(TCOUNT0)  = r0;
	bit set mode2 PWMOUT0;

	/* Selects low priority interrupts for both timers */
	bit clr mode2 INT_HI0;
	bit clr mode2 INT_HI1;

	/* Enables interrupts */
	bit set imask TMZLI;		
	bit set MODE1 IRPTEN;

	/* Enables timer 0 */
	bit set mode2 TIMEN0;

	leaf_exit;

/*****************************************************************
	Starts the highest priority ready task
	Called only one time by OSStart
*****************************************************************/
_OSStartHighRdy:

	entry;

#if OS_CPU_HOOKS_EN
	ccall(_OSTaskSwHook);
#endif

	/* Disables circular buffer for stack pointers */
	b6 = 0;
	l6 = 0;
	b7 = 0;
	l7 = 0;

	/* Looks for the next task's stack pointer */
	i0 = dm(_OSTCBHighRdy);
	i7 = dm(0,i0);

	/* Starts multitasking */
	jump pop_reg (db);
	r0 = 1;
	dm(_OSRunning)=r0;

/****************************************************************
	Saves the current task's context
	Restores the highest priority ready task's context
	Called by OSSched et OSTimeTick
****************************************************************/
_OSCtxSw:

	entry;
	/* Modifies the pushed PC to resume correctly the task's execution */
	dm(temp) = i12;
	modify(i7,m6);
	i12 = dm(i7,m5);
	modify(i12,m14);
	dm(i7,m5) = i12;
	call push_reg (db);
	modify(i7,m7);
	i12 = dm(temp);

	/* Saves the current task's stack pointer */
   	i0 = dm(_OSTCBCur);
	r0 = i7;
	dm(0,i0)=r0;

#if OS_CPU_HOOKS_EN
	ccall(_OSTaskSwHook);
#endif

	/* Updates OSTCBCur and OSPrioCur */
	i0 = dm(_OSTCBHighRdy);
	dm(_OSTCBCur)=i0;

   	i0 = dm(_OSPrioHighRdy);
	dm(_OSPrioCur)=i0;

	/* Takes next task's stack pointer */
	jump pop_reg (db);
	i0 = dm(_OSTCBHighRdy);
	i7 = dm(0,i0);

/****************************************************************
	Restores the highest priority task after an interrupt
	Called by OSIntExit
****************************************************************/
_OSIntCtxSw:

	entry;
	/* Clears from the stack the return addresses for OSIntExit and OSIntCtxSw calls */
	i12 = i6;
	i6 = pm(i12,m13);

	i12 = i6;
	i7 = i12;
	i6 = pm(i12,m13);

	/* Saves the current task's stack pointer */
	i0 = dm(_OSTCBCur);
	r0 = i7;
	dm(i0,0x0)=r0;

#if OS_CPU_HOOKS_EN
	ccall(_OSTaskSwHook);
#endif

	/* Updates OSTCBCur and OSTCBPrioCur */
	i0 = dm(_OSTCBHighRdy);
	dm(_OSTCBCur)=i0;

   	i0 = dm(_OSPrioHighRdy);
	dm(_OSPrioCur)=i0;

	/* Takes next task's stack pointer */
	jump pop_reg (db);
	i0 = dm(_OSTCBHighRdy);
	i7 = dm(0,i0);

/****************************************************************
	Interrupt routine called each clock tick
	If there is a higher priority task ready, call OSIntCtxSw
	If not, restores the current task
****************************************************************/
_OSTickISR:
	
	/* Pushes on the stack the PC value stored in PCSTK */
	dm(temp) = i12;
	i12 = i7;
	pm(i12,m13)=i6;
	i6 = i12;
	modify(i12,m15);
	i7 = i12;
	dm(i7,m7)=pcstk;
	pop pcstk;
	i12 = dm(temp);

	call push_reg;

	/* Calls OSIntEnter() */
	/* ccall(_OSIntEnter); */

	/* The following instructions replaces the call to OSIntEnter() */
	r2 = dm(_OSIntNesting);
	r1 = r2 + 1;
	dm(_OSIntNesting) = r1;

	ccall(_OSTimeTick);
	ccall(_OSIntExit);

	jump pop_reg;

/****************************************************************
	Save registers 
****************************************************************/
push_reg:
	dm(i7,m7)=r0;
	dm(i7,m7)=r1;
	dm(i7,m7)=r2;
	dm(i7,m7)=r3;
	dm(i7,m7)=r4;
	dm(i7,m7)=r5;
	dm(i7,m7)=r6;
	dm(i7,m7)=r7;
	dm(i7,m7)=r8;
	dm(i7,m7)=r9;
	dm(i7,m7)=r10;
	dm(i7,m7)=r11;
	dm(i7,m7)=r12;
	dm(i7,m7)=r13;
	dm(i7,m7)=r14;
	dm(i7,m7)=r15;
	dm(i7,m7)=i8;
	dm(i7,m7)=i9;
	dm(i7,m7)=i10;
	dm(i7,m7)=i11;
	dm(i7,m7)=i12;
	dm(i7,m7)=i13;
	dm(i7,m7)=i14;
	dm(i7,m7)=i15;
	dm(i7,m7)=m8;
	dm(i7,m7)=m9;
	dm(i7,m7)=m10;
	dm(i7,m7)=m11;
	dm(i7,m7)=m12;
	i15=i7;
	pm(i15,m15)=i0;
	pm(i15,m15)=i1;
	pm(i15,m15)=i2;
	pm(i15,m15)=i3;
	pm(i15,m15)=i4;
	pm(i15,m15)=i5;
	pm(i15,m15)=m0;
	pm(i15,m15)=m1;
	pm(i15,m15)=m2;
	pm(i15,m15)=m3;
	r0=MR0F, pm(i15,m15)=m4;
	i7=i15;
	r0=MR1F, dm(i7,m7)=r0;
	r0=MR2F, dm(i7,m7)=r0;
 	r0=MR0B, dm(i7,m7)=r0;
	r0=MR1B, dm(i7,m7)=r0;
	r0=MR2B, dm(i7,m7)=r0;
  	dm(i7,m7)=r0;
	dm(i7,m7)=ustat1;
	rts (db);
	dm(i7,m7)=ustat2;
	dm(i7,m7)=astat;

/****************************************************************
	Restore registers 
	Does not restore the FLAGS0-3 bits in ASTAT 
****************************************************************/
pop_reg:
	modify (i7,1);
	r1=0xff83ffff;
	r2=not r1, r0=dm(i7,m6);
	r3=astat;
	r4=r1 and r0, r8=dm(i7,m6);
	r5=r2 and r3, r9=dm(i7,m6);
	r0=r4 or r5, r10=dm(i7,m6);
	astat = r0;
	ustat2=r8;
	ustat1=r9;
	MR2B = r10, r0=dm(i7,m6);
	MR1B = r0, r0=dm(i7,m6);
	MR0B = r0, r0=dm(i7,m6);
	MR2F = r0, r0=dm(i7,m6);
	MR1F = r0, r0=dm(i7,m6);
	i15=i7;
	MR0F = r0, m4=pm(i15,m14);
	m3=pm(i15,m14);
	m2=pm(i15,m14);
	m1=pm(i15,m14);
	m0=pm(i15,m14);
	i5=pm(i15,m14);
	i4=pm(i15,m14);
	i3=pm(i15,m14);
	i2=pm(i15,m14);
	i1=pm(i15,m14);
	i0=pm(i15,m14);
	i7=i15;
	m12=dm(i7,m6);
	m11=dm(i7,m6);
	m10=dm(i7,m6);
	m9=dm(i7,m6);
	m8=dm(i7,m6);
	i15=dm(i7,m6);
	i14=dm(i7,m6);
	i13=dm(i7,m6);
	i12=dm(i7,m6);
	i11=dm(i7,m6);
	i10=dm(i7,m6);
	i9=dm(i7,m6);
	i8=dm(i7,m6);
	r15=dm(i7,m6);
	r14=dm(i7,m6);
	r13=dm(i7,m6);
	r12=dm(i7,m6);
	r11=dm(i7,m6);
	r10=dm(i7,m6);
	r9=dm(i7,m6);
	r8=dm(i7,m6);
	r7=dm(i7,m6);
	r6=dm(i7,m6);
	r5=dm(i7,m6);
	r4=dm(i7,m6);
	r3=dm(i7,m6);
	r2=dm(i7,m6);
	r1=dm(i7,m6);
	r0=dm(i7,m6);
	/* Acts like an interrupt return */
	push pcstk;
	pcstk = dm(i7,m6);
	dm(temp) = i12;
	i12 = i7;
	i6 = pm(i12,m13);
	rti (db);
	i12 = dm(temp);
	bit set mode1 0x1000;

.ENDSEG;

/**************************************** End of file ***************************************/

⌨️ 快捷键说明

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