📄 os_cpu_a.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 + -