📄 os_cpu_asm.s.bak
字号:
/*
*********************************************************************************************************
* uC/OS-II
* The Real-Time Kernel
*
* O/S specific functions for
* Analog Devices
* Blackfin ADSP-BF533
*
* File : OS_CPU_ASM.C
* By : Ron Territo ron@territocomputerservices.com
*********************************************************************************************************
Copyright...
This code is placed in the public domain, and can be distributed freely with no restrictions provided that the heading
of each source module file is not modified to remove the credit to the original author.
Disclaimer...
This program code is provided "as is". There is no warranty, either expressed or implied as to its fitness for use in
any application. It is provided only as an example of porting the MicroC/OS operating system to the Blackfin processor.
Its use is strictly at the risk of the user. The author will not be liable for any damages direct or consequential related
to the use of this software including, but not limited to loss of profit.
*/
#include "os_cfg.h";
.import "uCOS-II_V2.70\source\ucos_ii.h";
/*
*****************************************************************************
*
* Global variables
*
*****************************************************************************
*/
.extern _GlobalIrqMask;
.extern _CpuIrqOff;
.extern _CpuIrqOn;
.extern _CpuSaveContext;
.extern _CpuRestoreContext;
.extern _CpuRegisterEventHandler;
.extern _CpuEnableEvent;
.extern _OSTaskSwHook;
.extern struct OS_TCB _OSTCBCur;
.extern struct OS_TCB _OSTCBHighRdy;
.extern _OSPrioCur;
.extern _OSPrioHighRdy;
.extern _OSRunning;
.section program;
/*
*********************************************************************************************************
* INITIALIZE A TASK'S STACK初始化任务栈
*
* Description: This function is called by either OSTaskCreate() or OSTaskCreateExt() to initialize the
* stack frame of the task being created. This function is highly processor specific.
*
* Arguments : task is a pointer to the task code
*
* pdata is a pointer to a user supplied data area that will be passed to the task
* when the task first executes.
*
* ptos is a pointer to the top of stack. It is assumed that 'ptos' points to
* a 'free' entry on the task stack. If OS_STK_GROWTH is set to 1 then
* 'ptos' will contain the HIGHEST valid address of the stack. Similarly, if
* OS_STK_GROWTH is set to 0, the 'ptos' will contains the LOWEST valid address
* of the stack.
*
* opt specifies options that can be used to alter the behavior of OSTaskStkInit().
* (see uCOS_II.H for OS_TASK_OPT_???).
*
* Returns : Always returns the location of the new top-of-stack' once the processor registers have
* been placed on the stack in the proper order.
*********************************************************************************************************
OSTaskStkInit(void (*task)(void *pd), void *pdata, OS_STK *ptos, INT16U opt)
*/
.global _OSTaskStkInit;
_OSTaskStkInit:
[ --sp ] = rets; // save return address
[ --sp ] = r0; // save parameters
[ --sp ] = r1;
[ --sp ] = r2;
call _CpuIrqOff; // enter critical section
r2 = [ sp++ ]; // restore parameters
r1 = [ sp++ ]; // restore parameters
r0 = [ sp++ ]; // restore parameters
[ --sp ] = fp; // save old frame pointer
fp = sp; // save current sp in fp
sp = r2; // set sp to "ptos" ( arg 3 is in r2 )
r3.H = 0xBAD; // set r3 to pattern
r3.L = 0xF00D;
[ --sp ] = r3; // arg 3 = 0
[ --sp ] = r3; // arg 2 = 0
[ --sp ] = r1; // arg 1 = "pdata" ( arg 2 is in r1 )
[ --sp ] = r3;
[ --sp ] = r0; // save task start as return address "pd" ( arg 1 is in r0 )
r0 = [ fp ]; // get old fp
[ --sp ] = r0; // put it on stack
[ --sp ] = astat; // put astat on stack
[ --sp ] = r0; // save rets
r0 = r1; // pass "pdata" as arg 1 ( in r0 )
call _CpuSaveContext; // save complete register file
r0 = sp; // return value is new stack top
sp = fp; // restore prior sp
fp = [sp++]; // restore prior fp
call _CpuIrqOn; // exit critical section
rets = [sp++]; // restore return address
rts; // return
_OSTaskStkInit.end:
/*
*********************************************************************************************************
* O/S Start High Ready Task
*
* Description: This function is called to start the highest ready task
*
*
* Arguments : none
*
*********************************************************************************************************
*/
.global _OSStartHighRdy;
_OSStartHighRdy:
.if OS_TASK_SW_HOOK_EN == 1;
/* Do the task switch hook function*/
call _OSTaskSwHook;
.endif;
/* Set OSRunning = true */
p1.L = _OSRunning;
p1.H = _OSRunning;
r1 = 1;
[ p1 ] = r1;
/* Get the SP for the highest ready task得到将要恢复运行任务的堆栈指针 */
p1.L = _OSTCBHighRdy; // get a pointer to the TCB
p1.H = _OSTCBHighRdy;
p2 = [ p1 ];
sp = [ p2 + OFFSETOF(OS_TCB,OSTCBStkPtr)]; // load the Stack for this task
/* Restore all task's registers还原所有堆栈寄存器 */
call _CpuRestoreContext; // restore register file
rets = [ sp++ ];
astat = [ sp++ ];
fp = [ sp++ ];
/* "Return" to the new task */
rets = [ sp++ ];
rts;
_OSStartHighRdy.end:
/*
*********************************************************************************************************
* O/S CPU Context Switch
*
* Description: This function is called to switch the context of the current running task
*
*
* Arguments : none
*
*********************************************************************************************************
*/
.global _OSCtxSw;
_OSCtxSw:
/* Save everything for current task */
[ --sp ] = reti; // save address of interrupted task
[ --sp ] = fp; // save frame pointer
[ --sp ] = astat; // save astat
[ --sp ] = rets;
call _CpuSaveContext; // save all registers
/* then save the SP in the TCB */
p1.L = _OSTCBCur; // get a pointer to the TCB stack pointer save area
p1.H = _OSTCBCur;
p2 = [ p1 ]; // get the TCB address
[ p2 + OFFSETOF(OS_TCB,OSTCBStkPtr)] = sp; // save the Stack for this task
.if OS_TASK_SW_HOOK_EN == 1;
/* Do the task switch hook function*/
call _OSTaskSwHook;
.endif;
/* Get a new task Priority */
p1.L = _OSPrioHighRdy;
p1.H = _OSPrioHighRdy;
r1 = B [ p1 ](Z);
/* Make it the current priority */
p1.L = _OSPrioCur;
p1.H = _OSPrioCur;
B [ p1 ] = r1;
/* Get a new ready task */
p1.L = _OSTCBHighRdy;
p1.H = _OSTCBHighRdy;
p2 = [ p1 ];
/* Make it the current task */
p1.L = _OSTCBCur;
p1.H = _OSTCBCur;
[ p1 ] = p2;
/* load the stack pointer for the new task */
sp = [ p2 + OFFSETOF(OS_TCB,OSTCBStkPtr) ];
/* Restore everything for new task */
call _CpuRestoreContext; // restore register file
rets = [ sp++ ]; // restore system registers
astat = [ sp++ ];
fp = [ sp++ ];
reti = [ sp++ ];
rti;
_OSCtxSw.end:
/*
*********************************************************************************************************
* O/S CPU Interrupt Context Switch
*
* Description: This function is called to switch the context of the current running task
* from within an interrupt handler
*
*
* Arguments : none
*
*********************************************************************************************************
*/
.global _OSIntCtxSw;
_OSIntCtxSw:
p1.L = _OSPrioHighRdy;
p1.H = _OSPrioHighRdy;
r1 = B [ p1 ](Z);
/* Make it the current priority */
p1.L = _OSPrioCur;
p1.H = _OSPrioCur;
B [ p1 ] = r1;
/* Get a new ready task */
p1.L = _OSTCBHighRdy;
p1.H = _OSTCBHighRdy;
p2 = [ p1 ];
/* Make it the current task */
p1.L = _OSTCBCur;
p1.H = _OSTCBCur;
[ p1 ] = p2;
/* load the stack pointer for the new task */
sp = [ p2 + OFFSETOF(OS_TCB,OSTCBStkPtr) ];
/* Restore everything for new task */
call _CpuRestoreContext; // restore register file
rets = [ sp++ ]; // restore sys regs
astat = [ sp++ ];
fp = [ sp++ ];
reti = [ sp++ ];
[ --sp ] = r0; // restore interrupt mask
[ --sp ] = p1;
p1.H = __TimerSaveMask;
p1.L = __TimerSaveMask;
r0 = [ p1 ];
sti r0;
p1 = [ sp++ ];
r0 = [ sp++ ];
rti;
_OSIntCtxSw.end:
/*
*********************************************************************************************************
* O/S CPU Initialization
*
* Description: This function is called to initialize the CPU for the O/S. This function
* is not explicitly defined in the uC/OS-II documentation, but is necessary
* nevertheless.
*
*
* Arguments : none
*
*********************************************************************************************************
*/
.global _OsCpuInit;
_OsCpuInit:
// Register an exception handler for OS Context Switch
[ --sp ] = rets; // save return address
r0 = 14; // IRQ number 14
r1.H = _OSCtxSw; // address of trap handler
r1.L = _OSCtxSw;
call _CpuRegisterEventHandler;
r0 = 0x4000 (Z); // enable Trap14
call _CpuEnableEvent;
rets = [ sp++ ];
rts;
_OsCpuInit.end:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -