马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?注册
x
首先,讲一下uC/OS-II的工作原理:
uC/OS-II采用的是可剥夺型实时多任务内核。可剥夺型的实时内核在任何时候都运行就绪了的最高优先级的任务。 uC/os-II的任务调度是完全基于任务优先级的抢占式调度,也就是最高优先级的任务一旦处于就绪状态,则立即抢占正在运行的低优先级任务的处理器资源。为了简化系统设计,uC/OS-II规定所有任务的优先级不同,因为任务的优先级也同时唯一标志了该任务本身。 1) 高优先级的任务因为需要某种临界资源,主动请求挂起,让出处理器,此时将调度就绪状态的低优先级任务获得执行,这种调度也称为任务级的上下文切换。 2) 高优先级的任务因为时钟节拍到来,在时钟中断的处理程序中,内核发现高优先级任务获得了执行条件(如休眠的时钟到时),则在中断态直接切换到高优先级任务执行。这种调度也称为中断级的上下文切换。 这两种调度方式在uC/OS-II的执行过程中非常普遍,一般来说前者发生在系统服务中,后者发生在时钟中断的服务程序中。 调度工作的内容可以分为两部分:最高优先级任务的寻找和任务切换。其最高优先级任务的寻找是通 过建立就绪任务表来实现的。uC/OS中的每一个任务都有独立的堆栈空间,并有一个称为任务控制块TCB(TaskControl Block)的数据结构,其中第一个成员变量就是保存的任务堆栈指针。任务调度模块首先用变量OSTCBHighRdy记录当前最高级就绪任务的TCB 地址,然后调用OS_TASK_SW()函数来进行任务切换。
任务的状态图如图3-1。在任一时刻,任务的状态一定是这五种状态之一。
休眠态指任务驻留在程序空间之中,还没有交给uC/OS-II管理。把任务交给uC/OS-II是通过调用下述两个函数:OSTaskCreate()或OSTaskCreateExt()。当任务一旦建立,这个任务就进入就绪态准备运行。任务的建立可以是在多任务运行开始之前,也可以动态地被一个运行着的任务建立。如果一个任务是被另一个任务建立的,而这个任务的优先级高于建立它的那个任务,则这个刚刚建立的任务将立即得到CPU的控制权。一个任务可以通过调用OSTaskDel()返回到休眠态,或通过调用该函数让另一个任务进入休眠态。
file:///C:/DOCUME%7E1/ADMINI%7E1/LOCALS%7E1/Temp/msohtml1/01/clip_image001.giffile:///C:/DOCUME%7E1/ADMINI%7E1/LOCALS%7E1/Temp/msohtml1/01/clip_image002.giffile:///C:/DOCUME%7E1/ADMINI%7E1/LOCALS%7E1/Temp/msohtml1/01/clip_image003.giffile:///C:/DOCUME%7E1/ADMINI%7E1/LOCALS%7E1/Temp/msohtml1/01/clip_image004.giffile:///C:/DOCUME%7E1/ADMINI%7E1/LOCALS%7E1/Temp/msohtml1/01/clip_image005.gif
调用OSStart()可以启动多个任务。OSStart()函数运行进入就绪态的优先级最高的任务。只有当所有优先级高于它的任务转为等待状态,或者是被删除了,就绪的任务才能进入运行态。
正在运行的任务可通过调用两个函数将自身延迟一段时间,这两个函数是OSTimeDly()或OSTimeDlyHMSM()。这个任务于是进入等待状态,等待这段时间过去,下一个优先级最高的、并进入了就绪态的任务立刻被赋予了CPU的控制权。等待的时间过去以后,系统服务函数OSTimeTick()使延迟了的任务进入就绪态。
正在运行的任务期待某一事件的发生时也要等待,方法是调用以下3个函数之一:OSSemPend(),OSMboxPend()或OSQPend()。调用后任务进入了等待状态。当任务因等待事件被挂起,下一个优先级最高的任务立即得到了CPU的控制权。当事件发生了,被挂起的任务进入就绪态。事件发生的报告可能来自另一个任务,也可能来自中断服务子程序。
正在运行的任务是可以被中断的,除非该任务关中断,或者uC/OS-II关中断。被中断了的任务就进入了中断服务子程序。响应中断是,正在执行的任务被挂起,中断服务子程序控制了CPU的使用权。中断服务子程序可能会报告一个或多个事件的发生,而使一个或多个任务进入就绪态。在这种情况下,从中断服务子程序返回之前,uC/OS-II要判定,被中断的任务是否还是就绪态任务中优先级最高的。如果中断服务子程序使一个优先级更高的任务进入了就绪态,则新进入就绪态的这个优先级更高的任务将得以运行,否则原来被中断的任务还会继续运行。
当所有的任务都处于等待事件发生或等待延迟时间结束的状态时,uC/OS-II执行空闲任务,执行OSTaskIdle()函数。
临界段
同其它内核一样,mC/OS-II为了处理临界段代码,必须关中断,处理完毕后,再开中断。微处理器一般都有关中断/开中断的指令。mC/OS-II定义了2个宏来关中断和开中断:
q
OS_ENTER_CRITICAL()
q
OS_EXIT_CRITICAL()
这2个宏的定义取决于具体的微处理器,故可在OS_CPU.H中找到相应定义。
下面讲一下:移植uC/OS-II对处理器的要求及移植基本方法移植就是使一个操作系统内核能在某个微处理器或微控制器上运行。要使uC/OS-II正常运行,处理器必须满足以下要求:
w
1.处理器的C编译器能产生可重入代码。
w
2.用C语言就可以打开和关闭中断。
w
3.处理器支持中断,并且能产生定时中断。
w
4.处理器支持能够容纳一定量数据的硬件堆栈。
w
5.处理器有将堆栈指针和其他CPU寄存器读出和存储到堆栈或内存中的指令。
在处理器和编译器满足了uC/OS-II的要求,并且有了必要的工具时移植uC/OS-II的工作,需要做的工作有以下几个内容:
ª
用#define设置一个常量的值(OS_CPU.H)。
ª
声明10个数据类型(OS_CPU.H)。
ª
用#define声明三个宏(OS_CPU.H)。
ª
用C语言编写六个简单的函数(OS_CPU_C.C)。
ª
编写四个汇编语言函数(OS_CPU_A.ASM)。
在OS_CPU.H中用宏定义堆栈增长方向,声明uC/OS-II系统程序中的10个数据类型。另外声明进入临界区和退出临界区的两个宏,再加上用宏定义任务切换对应的汇编指令。
在OS_CPU_C.C中用C语言编写6个C函数:
ª
OSTaskStkInit()
ª
OSTaskCreateHook()
ª
OSTaskDelHook()
ª
OSTaskSwHook()
ª
OSTaskStatHook()
ª
OSTimeTickHook()
在OS_CPU_A.ASM中编写4个汇编函数:
ª
OSStartHighRdy()
ª
OSCtxSw()
ª
OSIntCtxSw()
ª
OSTickISR()
uC/OS-II的系统架构如下:file:///C:/DOCUME%7E1/ADMINI%7E1/LOCALS%7E1/Temp/msohtml1/05/clip_image002.gif
|