微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > 在MC68HC908GP32上移植μC/OS-II

在MC68HC908GP32上移植μC/OS-II

时间:09-12 来源:互联网 点击:

OSCtxSw()是一个任务级的任务切换函数(在任务中调用,区别于在中断程序中调用的OSIntCtxSw())。在GP32上实现,可通过执行一条软中断指令SWI来实现任务切换。软中断向量指向OSCtxSw()。在 μC/OS-II中,如果任务调用了某个函数,而该函数的执行结果可能造成系统任务新调度(例如试图唤醒一个优先级更高的任务),则在函数的末尾会调用 OSSched();如果OSSched()将查找当前就绪的优先级最高的任务,若不是当前任务,则判断是否需要进行任务调度,并找到该任务控制块 OS_TCB的地址,将该地址拷贝到变量OSTCBHighRdy中,然后通过宏OS_TASK_SW()执行软中断进行任务切换。在此过程中,变量 OSTCBCur始终包含一个指向当前运行任务OS_TCB的指针。OSCtxSw()的汇编代码如下:

Void OSCtxSw(void)

{asm

{pshh //保存X寄存器

tsx

pshx

pshh

dx OSTCBCur //载入当前任务的TCB指针

pshx

ldx OSTCBCur:1 //载入TCB的第二个字节

pulh

pula

sta 0,x //保存当前堆栈指针

pula

sta 1,x

jsr OSTaskSwHook //调用用户定义的接口函数

lda OSPrioHighRdy //设置OSPrioCur=OSPrioHighRdy

sta OSPrioCur

pshx

ldx OSTCBHighRdy:1

stx OSTCBCur:1

pulh

lda 0,x //载入堆栈指针

psha

ldx,1,x

pulh

txs

pulh //恢复索引寄存器内容

rti //中断返回,切换任务

}}

(4)OSTickISR()函数

在μC/OS-II中,当调用OSStart()启动多任务环境后,时钟中断的使用是非常重要的。在时钟中断程序中负责处理所有与定时相关的工作,如任务的延时、等待操作等等。在时钟中断中将查询处于等待状态的任务,判断是否延时结束,否则将重新进行任务调度。

为GP32编写的函数OSTickISR()的代码如下:

void OSTickISR()void{

asm{

pshh

LDA T1SC

BCLR 7,T1SC //允许中断嵌套

}

OsintEnter(); /*标志进入中断*/

OSTimeTick(); /*调用时钟节拍函数*/

OSlntExit(); /*标志退出中断*/

Asm{

Pulh

Rti

}}

和μC/OS-II中的其他中断服务程序一样,OSTickISR()首先在被中断任务堆栈中保存CPU寄存器的值,然后调用OSIntEnter()。μC/OS-II要求在中断服务程序开头调用OSIntEnter(),其作用是将记录中断嵌套层数的全局变量OSIntNesting加1。如果不调用OSIntEnter(),直接将OSIntNesting加1也是允许的。随后,OSTickISR()调用OSTimeTick(),检查所有处于延时等待状态的任务,判断是否有延时结束就绪的任务。在OSTickISR()的最后调用OSIntExit(),如果在中断中(或其他嵌套的中断)有更高优先级的任务就绪,并且当前中断为中断嵌套的最后一层,OSIntExit() 将进行任务调度。注意:如果进行了任务调度,OSIntExit()将不同志返回调用者,而是用新任务的堆栈中的寄存器数值恢复CPU现场,然后用 IRET实现任务切换。如果当有中断不是中断嵌套的最后一层,或中断中没有改变任务的就绪状态,OSIntExit()将返回调用者 OSTickISR(),最后OSTickISR()返回被中断的任务。

4.OS_CPU08.C文件

μC/OS-II的移植需要用户在OS_CPU08.C中定义6个函数:

OSTaskStkInit()

OSTaskCreateHook()

OSTaskDelHook()

OSTaskSwHook()

OSTaskStatHook()

OSTimeTickHook()

实际需要定义的只有OSTaskStkInit()函数,其他5个函数需要声明,但不一定有实际内容。这5个函数都是用户定义,所以OS_CPU08.C中只有定义,没有给出代码。如果用户需要使用这些函数,请将文件OS_CFG.H中的#define constant OS_CPU_HOOKS_EN设为1,设为0表示不使用这些函数。

OSTaskStkInit()函数由任务创建函数 OSTaskCreate()或OSTaskCreateExt()调用,用来初始化任务的堆栈。初始状态的堆栈模拟发生一次中断后的堆栈结构,按照中断后的进栈次序预留各个寄存器存储空间;而中断返回地址指向任务代码的起始地址。当调用OSTaskCreate()或OSTaskCreateExt()创建一个新任务时,需要传递的参数是:任务代码的起始地址、参数指针(pdata)、任务堆栈顶端的地址、任务的优先级。 OSTaskCreateExt()还需要一些其他参数,但与OSTaskStkinit()没有关系。OSTaskStkInit()只需要以上提到的 3个参数(task、pdata和ptos)。堆栈初始化工作结束后,OSTaskStkInit()返回新的堆栈栈顶指针,OSTaskCreate()OSTaskCreateExt()将指针保存在任务的OS_TCB中。

Void*OSTaskStklint(void(*task)(void*pd),void*pdata,void*ptos,INT16U opt)

{

INT16U *stk;

stk=(INT16U*)ptos; /*保存堆栈指针*/

*--stk=(INT16U)(task); /保存程序计数器内容*/

*--stk=(INT16U)(0x00); /初始化X和A寄存器内容*/

--stk=(INT16U)(0x00); /*初始化CCR和H寄存器*/

return((void*)stk);

}

其余的几个函数:OSTas

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top