📄 os_cpu_c.c
字号:
//------------- 2006-12-20 19:06 添加
void * OSTaskStkInit( void ( * task )(void * pd),
void * ppdata,void * ptos,
INT16U opt
) reentrant
{
OS_STK * stk;
ppdata = ppdata;
opt = opt; // opt没用到,防止警告
stk = (OS_STK *)ptos; // 用户堆栈最低有效地址
*stk++ = 15; // 用户堆栈长度
*stk++ = (INT16U)task & 0xff; // 任务地址低8位
*stk++ = (INT16U)task >> 8; // 任务地址高8位
*stk++ = 0x00; // PSW
*stk++ = 0x0A; // ACC
*stk++ = 0x0B; // B
*stk++ = 0x00; // DPL
*stk++ = 0x00; // DPH
*stk++ = 0x00; // R0
/*R3、R2、R1用于传递任务参数ppdata,其中R3代表存储器类型,R2为高字节偏移,R1为低字节偏移
通过分析Keil汇编,了解到任务的void ppdata参数恰好是用R3、R2、R1传递,不是通过虚拟堆栈*/
*stk++ = (INT16U)ppdata & 0xff; // R1
*stk++ = (INT16U)ppdata >> 8; // R2
*stk++ = 0x01; // R3
*stk++ = 0x04; // R4
*stk++ = 0x05; // R5
*stk++ = 0x06; // R6
*stk++ = 0x07; // R7
//不用保存SP,任务切换时根据用户堆栈长度计算得出
*stk++ = (INT16U)(ptos + MaxStkSize) >> 8; //堆栈映像指针高8位
*stk++ = (INT16U)(ptos + MaxStkSize) & 0xff; //堆栈映像指针低8位
return ((void *)ptos);
}
void InitTime0(void) reentrant
{
TMOD = TMOD & 0xf0;
TMOD = TMOD | 0x01; // 模式1(16位定时器),仅受TR0控制
TH0 = 0x70; // 定义Tick = 50 次/秒
TL0 = 0x00;
//ET0 = 1; // 允许T0中断,此时EAV=0(缺省值),中断还不会发生,满足在OSStart()前不产生中断的要求
TR0 = 1;
}
/*$PAGE*/
/*
*********************************************************************************************************
* INITIALIZE A TASK'S STACK FOR FLOATING POINT EMULATION
*
* Description: This function MUST be called BEFORE calling either OSTaskCreate() or OSTaskCreateExt() in
* order to initialize the task's stack to allow the task to use the Borland floating-point
* emulation. The returned pointer MUST be used in the task creation call.
*
* Ex.: OS_STK TaskStk[1000];
*
*
* void main (void)
* {
* OS_STK *ptos;
* OS_STK *pbos;
* INT32U size;
*
*
* OSInit();
* .
* .
* ptos = &TaskStk[999];
* pbos = &TaskStk[0];
* psize = 1000;
* OSTaskStkInit_FPE_x86(&ptos, &pbos, &size);
* OSTaskCreate(Task, (void *)0, ptos, 10);
* .
* .
* OSStart();
* }
*
* Arguments : pptos is the pointer to the task's top-of-stack pointer which would be passed to
* OSTaskCreate() or OSTaskCreateExt().
*
* ppbos is the pointer to the new bottom of stack pointer which would be passed to
* OSTaskCreateExt().
*
* psize is a pointer to the size of the stack (in number of stack elements). You
* MUST allocate sufficient stack space to leave at least 384 bytes for the
* floating-point emulation.
*
* Returns : The new size of the stack once memory is allocated to the floating-point emulation.
*
* Note(s) : 1) _SS is a Borland 'pseudo-register' and returns the contents of the Stack Segment (SS)
* 2) The pointer to the top-of-stack (pptos) will be modified so that it points to the new
* top-of-stack.
* 3) The pointer to the bottom-of-stack (ppbos) will be modified so that it points to the new
* bottom-of-stack.
* 4) The new size of the stack is adjusted to reflect the fact that memory was reserved on
* the stack for the floating-point emulation.
*********************************************************************************************************
*/
/*$PAGE*/
void OSTaskStkInit_FPE_x86 (OS_STK **pptos, OS_STK **ppbos, INT32U *psize)
{
INT32U lin_tos; /* 'Linear' version of top-of-stack address */
INT32U lin_bos; /* 'Linear' version of bottom-of-stack address */
INT16U seg;
INT16U off;
INT32U bytes;
seg = FP_SEG(*pptos); /* Decompose top-of-stack pointer into seg:off */
off = FP_OFF(*pptos);
lin_tos = ((INT32U)seg << 4) + (INT32U)off; /* Convert seg:off to linear address */
bytes = *psize * sizeof(OS_STK); /* Determine how many bytes for the stack */
lin_bos = (lin_tos - bytes + 15) & 0xFFFFFFF0L; /* Ensure paragraph alignment for BOS */
seg = (INT16U)(lin_bos >> 4); /* Get new 'normalized' segment */
*ppbos = (OS_STK *)MK_FP(seg, 0x0000); /* Create 'normalized' BOS pointer */
memcpy(*ppbos, MK_FP(_SS, 0), 384); /* Copy FP emulation memory to task's stack */
bytes = bytes - 16; /* Loose 16 bytes because of alignment */
*pptos = (OS_STK *)MK_FP(seg, (INT16U)bytes); /* Determine new top-of-stack */
*ppbos = (OS_STK *)MK_FP(seg, 384); /* Determine new bottom-of-stack */
bytes = bytes - 384;
*psize = bytes / sizeof(OS_STK); /* Determine new stack size */
}
/*$PAGE*/
/*
*********************************************************************************************************
* TASK SWITCH HOOK
*
* Description: This function is called when a task switch is performed. This allows you to perform other
* operations during a context switch.
*
* Arguments : none
*
* Note(s) : 1) Interrupts are disabled during this call.
* 2) It is assumed that the global pointer 'OSTCBHighRdy' points to the TCB of the task that
* will be 'switched in' (i.e. the highest priority task) and, 'OSTCBCur' points to the
* task being switched out (i.e. the preempted task).
*********************************************************************************************************
*/
#if OS_CPU_HOOKS_EN > 0
void OSTaskSwHook (void)
{
}
#endif
/*
*********************************************************************************************************
* OSTCBInit() HOOK
*
* Description: This function is called by OS_TCBInit() after setting up most of the TCB.
*
* Arguments : ptcb is a pointer to the TCB of the task being created.
*
* Note(s) : 1) Interrupts may or may not be ENABLED during this call.
*********************************************************************************************************
*/
#if OS_CPU_HOOKS_EN > 0 && OS_VERSION > 203
void OSTCBInitHook (OS_TCB *ptcb)
{
ptcb = ptcb; /* Prevent Compiler warning */
}
#endif
/*
*********************************************************************************************************
* TICK HOOK
*
* Description: This function is called every tick.
*
* Arguments : none
*
* Note(s) : 1) Interrupts may or may not be ENABLED during this call.
*********************************************************************************************************
*/
#if OS_CPU_HOOKS_EN > 0
void OSTimeTickHook (void)
{
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -