![Rank: 8](images/default/star_level3.gif) ![Rank: 8](images/default/star_level3.gif)
- UID
- 872238
|
![](http://images.eccn.com/silabs/silicon_chip_980x60_202203.jpg)
void OSTaskStkInit()
{OS_STK*stk;
stk=(void *)ptos;
opt=opt;
*stk--=fINT32U)pdata;//用户数据区
*stk--=fINT32U)(task);//RETI寄存器
*stk--=fINT32U)ptos;//FP寄存器
(由于需要入栈的寄存器数量比较多,限于篇幅,在此省略其中多数)
*stk--=fINT32U)0; //SEQSq、AT寄存器
*stk--=fINT32U)0;//ASTAT寄存器
retum((void*)stk);}
任务建立时调用该函数对新建任务的堆栈进行初始化,初始化后的堆栈结构如图3所示。
4.3编写OS_CPU_A.ASM文件
μC/OS-II移植的最后还需要用户编写4个重要的汇编函数,包括OSStartHighRdy()、OSCtxSw()、OSIntCtxSw()及OSTickISR()。分别介绍如下:
4.3.1 OSStartltighRdy()函数
该函数由OSStart()调用,用以运行优先级最高的就绪任务,其运行过程:调用用户定义的OS-TaskSwHook()数→获取任务堆栈指针→置位全局
变量0SRunning 出栈CPU寄存器 中断返回。在Adsp-BF531中的实现如下:
_OSStartHighRdy:
call_OSTaskSwHook;
p0.1=_OSTCBHighRdy;
p0.h=_0STCBHighRdy;
pl=[p0];
ssync;
sp=[p1];
p0.1=_OSRunning;
p0.h=_OSRunning;
r0=TRUE;
[p0]=r0;
ASTAT=[sp++];
SEQSTAT=[sp++];
FP =[sp++];
RETI=[sp++;
rti;
4.3.2 OSCtxSw()函数
实时操作系统内任务级的切换是通过处理器的软中断实现的,并且软中断服务例程的向量地址必须指向OSCtxSw()函数,因此该函数的汇编程序代码如下:
_OSCtxSw:
[--sp]=RETI;
[--sp]=FP;
[--sp]=SEQTAT;
[--sp]=ASTAT;
p0.1=_OSTCBCur;
p0.h=_OSTCBCur;
pl=[p0];
ssync;
[pl]=sp;
call_OSTaskSwHook;
p0.1 =_OSPrioHighRdy;
p0.h=_OSPrioHighRdy;
r0=[p0];
p0.1=_0SPrioCur;
p0.h=_OSPrioCur;
[p0]=r0;
p0.1=_OSTCBHighRdy;
p0.h=_OSTCBHighRdy;
pl=[p0];
rO=[p0];
ssync;
sp=[p1];
p0.1=_OSTCBCur;
p0.h=_OSTCBCur;
[p0]:r0; 、
ASTAT=[sp++];
SEQSTAT=[sp++];
FP:[SP++];
RETI=[sp++];
rti;
4.3.3 OSIntCtxSw()函数
OSIntCtxSw()用于实现中断级任务切换,由于该函数在中断服务程序中调用,因此在函数代码中不需要寄存器入栈,但堆栈结构中还包含了一些用户不需要的函数调用返回地址,因此该函数必须在最初清理堆栈(调整堆栈指针的位置),其汇编程序代码如下:
_OSIntCtxSw:
p0=20;
sp=sp+p0;
p0.1=_OSTCBCur;
p0.h=_OSTCBCur;
pl=[p0];
ssync;
[p1]=sp;
call_OSTaskSwHook;
p0.1=_OSPrioHighRdy;
p0.h=_OSPrioHighRdy;
r0=[p0];
p0.1=_OSPrioCur;
p0.h=_OSPfioCur;
[po]=10;
p0.1=_OSTCBHighRdy;
p0.h=_OSTCBHighRdy;
pl=[p0];
r0=[p0];
ssync;
sp=[p1];
p0.1=_OSTCBCur;
p0.h=_0STCBCur;
[po】=r0;
ASTAT=[sp++];
SEQSTAT=[sp++];
FP =[sp++];
RETI=[sp++];
rti;
4.3.4 OSTicklSR()函数 |
|