📄 os_cpu_a.dsp
字号:
{*
*********************************************************************************************************
* uC/OS-II
* The Real-Time Kernel
* ADSP-21xx Specific Code version 1.0
*
* File : OS_CPU_A.DSP
* By : Jaap de Jong (jdj@nedap.nl)
* Nedap Retail Support
* Parallelweg 2d
* Postbox 102
* 7140 AC Groenlo
* Netherlands
* Based on 'ADSP-21065L SHARC Specific Code version 1.0' by Bertrand Hurst, Francois Veuve, Cedric Bornand
*********************************************************************************************************
*}
.module _os_cpu_a_;
{ Functions defined hereunder }
.global OSStartHighRdy_;
.global OSCtxSw_;
.global OSIntCtxSw_;
.global OSTickISR_;
.global ___lib_tmri_ctrl; { takes care of placing the timerinterruptvector }
{ Functions defined in other files }
.external OSTaskSwHook_;
.external OSTimeTick_;
.external OSIntExit_;
{ Variables defined in other files }
.external OSRunning_;
.external OSTCBHighRdy_;
.external OSTCBCur_;
.external OSPrioHighRdy_;
.external OSPrioCur_;
.external OSIntNesting_;
{
g21 register usage (see ctools.pdf) -------------> uCosII implementation
=================================== =====================
Reg Value Modification Rules Stack Comment
=== ===== ================== ===== =======
AF User Defined None 7 indirect
AR User Defined None 1
ASTAT Program Control None 6 indirect
AX0 ? ? 2
AX1 ? ? 3
AY0 ? ? 4
AY1 User Defined None 5
I0 ? ? 39 indirect
I1 User Defined None 40 indirect
I2 User Defined Temporary use (-mreserved) 41 indirect
I3 User Defined Temporary use (-mreserved) 42 indirect
I4 stack pointer Stack management --
I5 ? ? 43 indirect
I6 User Defined None 44 indirect
I7 ? ? 45 indirect
IMASK Program Control None -- global use
L0 0 Temporary use 46 indirect
L1 0 Temporary use 47 indirect
L2 0 User Defined Temporary use (-mreserved) 48 indirect
L3 0 User Defined Temporary use (-mreserved) 49 indirect
L4 0 Do Not Modify --
L5 0 Temporary use 50 indirect
L6 0 Temporary use 51 indirect
L7 0 Temporary use 52 indirect
M0 ? ? 53 indirect
M1 1 Do Not Modify 54 indirect
M2 0 Temporary use 55 indirect
M3 User Defined None 56 indirect
M4 frame pointer Stack management 57 indirect
M5 User Defined None 58 indirect
M6 0 Temporary use 59 indirect
M7 ? ? 60 indirect
MF User Defined None 28 special
MR0 User Defined None 25
MR1 User Defined None 26
MR2 User Defined None 27
MSTAT Program Control None -- global use
MX0 ? ? 29
MX1 ? ? 30
MY0 ? ? 31
MY1 User Defined None 32
PC Program Control None 8..24 special
PX User Defined None 33 indirect
SB User Defined None 34 indirect
SE User Defined None 35
SI User Defined None 36
SR0 User Defined None 37
SR1 User Defined None 38
Secondary registers Do Not Use -- NOT supported!
}
{ Temporary vars }
.var/dm save_i4;
.var/dm save_m4;
{*
*********************************************************************************************************
* STORE REGISTERS
*
* Description : Store (almost) all registers.
* Arguments : none
* Note(s) : Macro
* Possible enhancements:
* a) store secondary registers
* b) check on sstat bits 2 (Count Stack Empty) & 6 (Loop Stack Empty)
* for both enhancements change restore_registers and OSTaskStkInit too!
*********************************************************************************************************
*}
.macro store_registers;
.local store_sts;
.local store_sts_done;
.local store_pc;
dm(save_m4) = m4;
m4 = -1;
dm(i4, m4) = ar;
dm(i4, m4) = ax0;
dm(i4, m4) = ax1;
dm(i4, m4) = ay0;
dm(i4, m4) = ay1;
ar = astat; dm(i4, m4) = ar;
ar = pass af; dm(i4, m4) = ar;
af = pass 0;
ay0 = 0x01;
store_pc:
ax0 = toppcstack; dm(i4, m4) = ax0;
af = af + 1;
ax0 = sstat;
ar = ax0 and ay0;
if eq jump store_pc;
ar = pass af; dm(i4, m4) = ar;
dm(i4, m4) = mr0;
dm(i4, m4) = mr1;
dm(i4, m4) = mr2;
ay0 = mstat; ena m_mode; ar = 1; mr = ar * mf (UU); dm(i4, m4) = mr1; mstat = ay0; { Phew! }
dm(i4, m4) = mx0;
dm(i4, m4) = mx1;
dm(i4, m4) = my0;
dm(i4, m4) = my1;
ar = px; dm(i4, m4) = ar;
ar = sb; dm(i4, m4) = ar;
dm(i4, m4) = se;
dm(i4, m4) = si;
dm(i4, m4) = sr0;
dm(i4, m4) = sr1;
ar = i0; dm(i4, m4) = ar;
ar = i1; dm(i4, m4) = ar;
ar = i2; dm(i4, m4) = ar;
ar = i3; dm(i4, m4) = ar;
ar = i5; dm(i4, m4) = ar;
ar = i6; dm(i4, m4) = ar;
ar = i7; dm(i4, m4) = ar;
ar = l0; dm(i4, m4) = ar;
ar = l1; dm(i4, m4) = ar;
ar = l2; dm(i4, m4) = ar;
ar = l3; dm(i4, m4) = ar;
ar = l5; dm(i4, m4) = ar;
ar = l6; dm(i4, m4) = ar;
ar = l7; dm(i4, m4) = ar;
ar = m0; dm(i4, m4) = ar;
ar = m1; dm(i4, m4) = ar;
ar = m2; dm(i4, m4) = ar;
ar = m3; dm(i4, m4) = ar;
ar = dm(save_m4); dm(i4, m4) = ar;
ar = m5; dm(i4, m4) = ar;
ar = m6; dm(i4, m4) = ar;
ar = m7; dm(i4, m4) = ar;
.endmacro;
{*
*********************************************************************************************************
* RESTORE REGISTERS
*
* Description : Restore (almost) all registers.
* Arguments : none
* Note(s) : Local function
*********************************************************************************************************
*}
restore_registers:
m4 = 1;
modify(i4, m4);
ar = dm(i4, m4); m7 = ar;
ar = dm(i4, m4); m6 = ar;
ar = dm(i4, m4); m5 = ar;
ar = dm(i4, m4); dm(save_m4) = ar;
ar = dm(i4, m4); m3 = ar;
ar = dm(i4, m4); m2 = ar;
ar = dm(i4, m4); m1 = ar;
ar = dm(i4, m4); m0 = ar;
ar = dm(i4, m4); l7 = ar;
ar = dm(i4, m4); l6 = ar;
ar = dm(i4, m4); l5 = ar;
ar = dm(i4, m4); l3 = ar;
ar = dm(i4, m4); l2 = ar;
ar = dm(i4, m4); l1 = ar;
ar = dm(i4, m4); l0 = ar;
ar = dm(i4, m4); i7 = ar;
ar = dm(i4, m4); i6 = ar;
ar = dm(i4, m4); i5 = ar;
ar = dm(i4, m4); i3 = ar;
ar = dm(i4, m4); i2 = ar;
ar = dm(i4, m4); i1 = ar;
ar = dm(i4, m4); i0 = ar;
sr1 = dm(i4, m4);
sr0 = dm(i4, m4);
si = dm(i4, m4);
se = dm(i4, m4);
ar = dm(i4, m4); sb = ar;
ar = dm(i4, m4); px = ar;
my1 = dm(i4, m4);
my0 = dm(i4, m4);
mx1 = dm(i4, m4);
mx0 = dm(i4, m4);
mr1 = dm(i4, m4); mf = mr;
mr2 = dm(i4, m4);
mr1 = dm(i4, m4);
mr0 = dm(i4, m4);
ar = dm(i4, m4); af = pass ar;
restore_pc:
ax0 = dm(i4, m4); toppcstack = ax0;
af = af - 1;
if ne jump restore_pc;
ar = dm(i4, m4); af = pass ar;
ar = dm(i4, m4); astat = ar;
ay1 = dm(i4, m4);
ay0 = dm(i4, m4);
ax1 = dm(i4, m4);
ax0 = dm(i4, m4);
m4 = 0;
ar = dm(i4, m4);
m4 = dm(save_m4);
rts;
{*
*********************************************************************************************************
* START HIGHEST PRIORITY TASK READY-TO-RUN
*
* Description : This function is called by OSStart() to start the highest priority task that was created
* by your application before calling OSStart().
* Arguments : none
* Note(s) : OSStartHighRdy() MUST:
* a) Call OSTaskSwHook() then,
* b) Set OSRunning to TRUE,
* c) Switch to the highest priority task.
*********************************************************************************************************
*}
OSStartHighRdy_:
{ Remove returnaddress from call to OSStartHighRdy() }
ar = toppcstack;
{ call captain Hook }
call OSTaskSwHook_;
{ Starts multitasking }
ar = 1;
dm(OSRunning_) = ar;
{ Updates OSTCBCur }
i4 = dm(OSTCBHighRdy_);
dm(OSTCBCur_) = i4;
{ Takes next tasks stack pointer }
ar = dm(i4, m4); { any m4..m7 will do }
i4 = ar;
jump restore_registers;
{*
*********************************************************************************************************
* TASK LEVEL CONTEXT SWITCH
*
* Description : This function is called when a task makes a higher priority task ready-to-run.
* Arguments : none
* Note(s) : This function is simply called from OSSched() via OS_TASK_SW().
* Upon entry,
* OSTCBCur points to the OS_TCB of the task to suspend
* OSTCBHighRdy points to the OS_TCB of the task to resume
*********************************************************************************************************
*}
OSCtxSw_:
store_registers;
{ Saves the current tasks stack pointer }
ar = i4;
i1 = dm(OSTCBCur_);
dm(i1, m1) = ar; { any m0..m3 will do }
{ call captain Hook }
call OSTaskSwHook_;
{ Updates OSTCBCur and OSPrioCur }
i4 = dm(OSTCBHighRdy_);
dm(OSTCBCur_) = i4;
ar = dm(OSPrioHighRdy_);
dm(OSPrioCur_) = ar;
{ Takes next tasks stack pointer }
ar = dm(i4, m4); { any m4..m7 will do }
i4 = ar;
jump restore_registers;
{*
*********************************************************************************************************
* INTERRUPT LEVEL CONTEXT SWITCH
*
* Description : This function is called by OSIntExit() to perform a context switch to a task that has
* been made ready-to-run by an ISR.
* Arguments : none
* Note(s) : Upon entry,
* OSTCBCur points to the OS_TCB of the task to suspend
* OSTCBHighRdy points to the OS_TCB of the task to resume
*********************************************************************************************************
*}
OSIntCtxSw_:
{ Remove returnaddress from call to OSIntCtxSw() from the stack }
ar = toppcstack;
{ Saves the current tasks stack pointer }
ar = dm(save_i4); { Restore saved stackpointer }
i1 = dm(OSTCBCur_);
dm(i1, m1) = ar; { any m0..m3 will do }
{ call captain Hook }
call OSTaskSwHook_;
{ Updates OSTCBCur and OSPrioCur }
i4 = dm(OSTCBHighRdy_);
dm(OSTCBCur_) = i4;
ar = dm(OSPrioHighRdy_);
dm(OSPrioCur_) = ar;
{ Takes next tasks stack pointer }
ar = dm(i4, m4); { any m4..m7 will do }
i4 = ar;
jump restore_registers;
{*
*********************************************************************************************************
* SYSTEM TICK ISR
*
* Description : This function is the ISR used to notify uC/OS that a system tick has occurred.
* Arguments : none
* Note(s) : If there is a higher priority task ready, call OSIntCtxSw
* If not, restores the current task
*********************************************************************************************************
*}
___lib_tmri_ctrl: { g21-entry for timerinterrupts }
OSTickISR_:
pop sts; { Remove status (imask, astat & mstat) from stack }
store_registers;
ar = i4; { Save stackpointer }
dm(save_i4) = ar;
ay0 = dm(OSIntNesting_);
ar = ay0 + 1;
dm(OSIntNesting_) = ar;
call OSTimeTick_; { Notify uC/OS-II that a tick has occured }
call OSIntExit_; { Notify uC/OS-II about end of ISR }
jump restore_registers;
.endmod;
{********************************** End of file *********************************************************}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -