说明:

本文主要讲针对STM32的UCOSIII3.03版本的文件与内核分析。此文只是对UCOSIII粗略的讲解,希望读者在读完后能对UCOSIII系统整体多些认识,细节方面还请读者参考相关书籍,如《嵌入式实时操作系统ucosiii》。介于作者水平有限,若有错误,请及时批评指正。

一.UCOSIII文件组成

UCOSIII文件主要由配置文件、应用程序文件、OS系统文件、OS与CPU相关文件、LIB库文件五部分组成,其中配置文件(cpu_cfg.h、lib_cfg.h、os_cfg.h、os_cfg_app.h)和应用程序文件由用户自己定义,文中不做介绍,LIB库文件由通用函数的源文件,文中也不做介绍。

(1) OS与CPU相关文件

文件架构分为两个部分,如下图:

(2) OS系统文件

文件架构如下图:

二.系统时钟节拍

系统时钟节拍是实现延时的最小单元。可以是一些有周期的信号,在STM32中使用systick作为系统时钟节拍。

三.任务的调度与切换

任务的调度与切换分两种:由调度器(OSSch())触发和由中断触发(OSIntExit()),具体流程图如下:

四.UCOSIII临界与任务切换过程

在UCOSIII中临界段有两种:关中断、调度器上锁,定义的临界段不同任务切换过程也有所不同。仅以系统节拍中断为例。

(1) 关中断(OS_CFG_ISR_POST_DEFERRED_EN(OS_CFG.H)=0)

关中断的方式任务切换如下图:

(2) 调度器上锁(OS_CFG_ISR_POST_DEFERRED_EN(OS_CFG.H)=1)

通过调度器上锁的方式会自动添加中断服务管理任务(OS_IntQtask(),OS_Int.c)(又名中断队列处理任务),且其任务优先级最高,在有信号或消息发布后任务切换总是运行该任务,然后自我悬挂,切换到低优先级任务。

五.UCOSIII信号量

信号量的作用机制:当信号量的结构体(OS_sem)中有一项数据OS_SEM_CTR(实际为char或int型)大于零时,OSsempend()直接运行通过,不产生任务调度与切换;当OS_SEM_CTR为零时,OSsempend()不能运行通过,将产生任务调度与切换,等待其他任务调用OSsempost()(使OS_SEM_CTR++,当OS_SEM_CTR大于0时引发任务调度)。

信号量在UCOSIII中主要有两个用途,一、资源的管理;二、任务同步。两者的不同在于创建信号量时对OS_SEM_CTR赋初值是否为零。OS_SEM_CTR为零时可以实现任务的同步,非零时可以实现对共享资源的管理。

六.UCOSIII消息队列

消息队列是为了实现任务之间的通信,其采用引用传递(指针)的方式。消息队列的数据结构为OS_Q,其中有一项数据为OS_MSG_Q,OS_MSG_Q中指向一个以OS_MSG为单元的链表,具体结构如下:

消息队列的作用原理和信号量差不多,当调用OSQpend()时消息队列中有消息,则直接运行通过,若没有则等待。当调用OSQpost()时,会向消息队列中增加消息,调度未锁时引发调度。

七.任务信号量和任务消息队列

内嵌在任务控制块(TCB)中独立存在,作用机制和信号量消息队列相同。