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

在MOTOROLA A68K系列MCU上移植μC/OS-II

时间:03-07 来源:互联网 点击:

该函数由OSStart()函数调用,功能是运行优先级最高的就绪态任务。在调用OSStart() 之前,用户必须先调用OSInit(),并且已经至少创建了一个任务。为启动任务,OSStartHighRdy()首先找到当前就绪的优先级最高的任务,OSTCBHighRdy中保存有优先级最高任务的任务控制块(TCB)的地址,并从任务的任务控制块中找到指向堆栈的指针,然后运行指令 MOVEM.L(A7)+,A0-A6/D0-D7,从堆栈中弹出全部寄存器的内容,运行RTE中断返回。由于任务创建时堆栈的结构就是按中断捕捞堆栈结构初始化的,执行RET指令后就切换到了新任务。有关μC/OS- II的任务切换机制,请参考系列计座(3).
OSStartHighRdy的汇编代码如下:
_OSStarHighRdy
MOVE.L(_OSTCBHighRdy),A1
;获取最高优先级就绪任务的TCB地址
MOVE.L A1,(_OSTCBCur)
MOVE.L (A1),A7 ;取得堆栈指针
MOVEM.L (A7)+,A0-A6/D0-D7
RTE ;中断返回,切换任务

(2)OSCtxSw( )函数

OSCtxSw( )是一个任务级的任务切换函数(在任务中调用,区别于在中断程序中调用的OSIntCtxSw(),在MC68K系统上,通过执行一条软中断指令来实现任务切换。软中断向量指向函数,而该函数的执行结构可能造成系统任务重新调度(例如,试图唤醒一个优先级更高的任务),则在函数的末尾会调用OSSched (),OSSched()将查找当前就绪的优先级最高的任务。如果不是当前任务,则判断是否需要进行任务调度,再找到该任务控制块OS_TCB的地址,并将该地址拷贝到变量OSTCBHighRdy中,然后通过宠OS_TASK_SW()执行软中断,进行任务切换。在此过程中,变量OSTCBCur始终包含一个指向当前运行任务OS_TCB的指针。OSCtxSw()的汇编代码如下:
_OSCtxSw
MOVEM.L A0-A6/D0-D7,-(A7) ;存储当前任务环境
MOVE.L (_OSTCBCur),A1 ;保存当前任务TCB指针
MOVE.L A7,(A1)
MOVE.L (_OSTCBHighRdy),A1 ;获取最高优先级就绪任务的TCB地址
MOVE.L A1,(_OSTCBCur) ;将就绪任务设置为当前运行任务
MOVE.L (A1),A7 ;取得新任务的堆栈指针
MOVEM.L (A7)+,A0-A6/D0-D7 ;
RTE ;中断返回,切换任务

(3)OSIntCtxSw()函数

在μC/OS -II中,由于中断的产生可能会引起任务切换,在中断服务程序的最后会调用OSICntExit()函数检查任务就绪状态。如果需要进行任务切换,将调用 OSIntCtxSw(),所以,OSIntCtxSw()又称为中断级的任务切换函数。由于在调用OSIntCtxSw()之前已经发生了中断, OSIntCtxSw()默认CPU寄存器已经保存在被中断任务的堆栈了。OSIntCtxSw()的代码与OSCtxSw()的大部分相同,不同之处是:第一,由于中断已经发生,此处不需要再保存CPU寄存器;第二,OSIntCtxSw()需要调整堆栈指针,去掉堆栈中一些不需要的内容,以使堆栈中包含任务的运行环境。
_OSIntCtxSw
ADDA #10,A7 ;忽略掉由于函数嵌套调
;用而压入堆栈的内容
MOVE.L (_CSTCBCur),A1 ;在TCB中保存当前
;任务的堆栈指针
MOVE.L A7,(A1)
MOVE.L (_OSTCBHighRdy),A1
;获取最高优先级就绪任务的TCB地址
MOVE.L A1,(_OSTCBCur) ;将就绪任务设备为当前
;运行任务
MOVE.L (A1),A7 ;取得堆栈指针
MOVEM.L (A7)+,A0-A6/D0-D7 ;
RTE ;中断返回,切换任务

(4)OSTickISR()函数

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

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

4.OS_CPU32.C文件

μC/OS-II的移值需要用户在OS_CP

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

网站地图

Top