UC/OS-II功能介绍、要点记录

通过不断地学习和实验UC/OS-II,终于在五一前在ARM平台上实现了多任务的创建、调度运行、挂起,任务间信号量、互斥型信号量、邮箱、消息队列和事件标识组方式下的通信机制,接下来则继续学习UC/OS-II的移植方法,在此趁五一假期之际,我将UC/OS-II的特点用自己通俗的语言介绍一下,希望能让大家在没接触UC/OS-II的情况下大概明白UC/OS-II的用处和特点,共同学习和进步,为学习UC/OS-II的同学提供有用的资料。另外,如有错误和不当之处,还请指正和发表您的心得体会。

谢谢!

一.有关UC/OS-II实时系统

1)UC/OS-II的名称

嵌入式实时操作系统UC/OS-II中文意为“微控制器操作系统版本2”,

它是一个完整的、可移植、固化、裁剪的占先式可剥夺型实时多任务内核。

2)UC/OS-II的用处

UC/OS-II多任务管理意在使多个需要处理器处理的事务在同时间段内同

步完成,通过充分利用处理器的处理资源,使处理器的处理效率到达更大

限度,UC/OS-II最多可实现同步管理64个任务

3)UC/OS-II多任务管理思想

用日常的例子打比方,比如处理器要完成一段程序就好比我们将做一顿饭,传统的方法是流水线式(单线程),如图Pic1.1:

Pic1.1

可见总用时位各过程的总和,我们可以想象得出这样的做法是很浪费时间的,我们任何人都不会这么去做,采用UC/OS-II多任务管理思想则可以将此事务按照另一种方式完成,如图Pic1.2中的多线程方式,由图比较可以看出,整个事务在t5时刻完成,当菜炒好时饭也做好不久,这样的方法使总用时减少了,分析原因,可以知道是我们在等饭做好的时候没有光等,而是开始洗菜,炒菜去了。同样的方式下,如果在等任何一件事务完成的过程中去做其他事情我们的做事效率是不是更快了呢,答案当然是肯定的。UC/OS-II支持最多同时64个任务的管理。

Pic1.2

二.UC/OS-II实时系统中有关概念介绍

1)任务        也叫线程,是一个简单的无限循环的程序,它是由一个大的

事务分割成多个小事务块后得来的,这些小事务块在时间上不冲  突,即可以同时进行,而在运行所有小事务块过程中,依然和运行  完整大事务的效果相同。UC/OS-II中每个任务有自己的特定信息块  (TCB)和独有的优先级级别,处理器通过这些信息管理这些任务,  在多个任务上调度运行、挂起任务等操作。

需要注意的是因为处理器在管理多任务过程中,任何时刻都有

且只能有一个任务在运行,故其它任务就出现了不同的状态,在

UC/OS-II中任务有五种状态,如下:

1.睡眠状态任务 2.就绪状态任务

3.运行状态任务 4.等待状态任务 5.被中断状态任务

任务还可以按图Pic1.2理解,其中的任务就包括

Task_1: 洗米 Task_2 :烧饭 Task_3: 洗菜 Task_4: 炒菜


状态


t0~t1


t1~t2


t2~t3


t3~t4


t4~t5


Task_1


运行态


·睡眠态


·睡眠态


·睡眠态


·睡眠态


Task_2


·睡眠态


运行态


等待态


等待态


·睡眠态


Task_3


·睡眠态


·睡眠态


运行态


·睡眠态


·睡眠态


Task_4


·睡眠态


·睡眠态


·睡眠态


运行态


运行态

表中加“·”符号的表示任务最可能处于的状态

2)调度         (schedulers),它是内核的主要职责,就是决定该轮到那个任

务运行了,UC/OS-II依据任务的优先级别执行调度工作

任务的调度(切换)过程

因为uc/os-ii总是运行进入就绪状态的最高优先级的任务。所以, 确定哪个任务优先级最高,下面该哪个任务运行,这个工作就是由 调度器(scheduler)来完成的。

UC/OS-II中有产生调度有两种方式,任务级的调度和中断级调度。任务级的调度是由函数OSSched()完成的,而中断级的调度是由函数OSIntExt()完成。对于OSSched(),它内部调用的是OS_TASK_SW()完成实际的调度(人为模仿一次中断);OSIntExt()内部调用的是OSCtxSw()实现调度。

任务切换其实很简单,由如下2步完成:(1)将被挂起任务的处 理器寄存器推入自己的任务堆栈。(2)然后将进入就绪状态的最高 优先级的任务的寄存器值从堆栈中恢复到寄存器中。

图Pic1.2中t2时刻即产生任务级调度过程

3)任务控制块(OS_TBC) 任务状态存放于OS-TBC数据结构中;保存了任 务的状态、优先级、断点数据等,当任务得到CPU使用权后,任务 控制块能确保任务能从被中断点那一点丝毫不差地继续执行。

每个任务都有自己的OS_TBC控制块,OS_TBC的数量由 OS_MAX_TASK决定,任务数量少,当然OS_TBC占用RAM的空 间就少。

任务一旦建立,任务控制块OS_TBC将被赋值。

所有的任务控制块OS_TBC都是放在任务控制块列表数组 OSTCBTbl[]中。在ucos-ii初始化时,所有任务控制块OS_TBC都被链表连接成单向空任务链表。

注意:UC/OS-II每创建一个任务时就在RAM中建立一个相应的OS_TBC

UC/OS-II学后总结(二)

三.UC/OS-II要点记录

1.中断服务所做的事应尽量少做,应把大部分工作留给任务去做。

2.OSIntExit()和OSSched()有点相似,但OSIntExit()使中断nestiing减1,而重新调度的条件是:中断nesting和锁定nesting计算器(OSLockNesting)均为0。

3.OS_TASK_SW()和OSCtxSw()的区别:后者使用于中断服务程序中,中断返回已经对cpu做了保存工作。而前者需要采用模仿软中断返回指令实现cpu保存。

4.时钟节拍

(1)UC/OS-II需要提供周期性的信号源,用于实现时间延迟和确认超时。  节拍率应为10~100Hz,时钟节拍率越高,系统额外的负荷就越重。

(2)系统多任务启动时候(调用OSStart())之后,第一件初始化事情就是  初始化定时中断。

(3)UC/OS-II中的时钟节拍服务是通过在中断服务子程序(OSTickISR())  中调用OSTimeTick()实现的。OSTimeTick()跟踪所以任务的定时器和超  时时限。 时钟节拍中断服从一般中断规则(含任务调度判断)。

5.OSTCBList指向任务控制块链表的开始,而且它总是指向最新建立的任务。

6.非常好的一个图示:OSInt()之后的变量和数据结构。请参阅P112

7.启动多任务时,执行OSStart()函数,OSStart()先从任务就绪表中找出用户建立的优先级最高的任务的任务控制块,而后调用了OSStartHighRdy(),此函数实质上是将任务堆栈中的保存内容返回到cpu寄存器中,然后执行一条中断返回指令。

【信号量专题】

1. 信号量

(1)uc/os-ii的信号量是由两个部分组成:一部分是16位的无符号整型信号量的计数值(0~65535);另一部分是等待该信号量的任务组成的等待任务表。(另外参考事件控制块ECB)

(2)信号量可以是2值的变量(称为二值信号量),也可以是计数式的。根据信号量的值,内核跟踪那些等待信号量的任务。

(3)建立信号量的工作必须在任务级代码中或者多任务启动之前完成。

(4)任务要得到信号量的问题。

想得到信号量的任务,必须执行等待操作(pend)。如果信号量有效(非0),则信号量减1,任务得以继续运行。如果信号量无效,则等待信号量的任务就被列入等待信号量的任务表中。多少内核允许定义等待超时,当等待时间超过了设定值,该信号量还是无效,则等待该信号量的任务进入就绪态,准备运行,并返回出错代码(等待超时错误)。

(5)任务对信号量的释放问题。

任务执行发信号(post)操作来释放信号量。如果没有任务等待信号量,那么信号量的值仅是简单的加1(则信号量大于0,有效);如果有任务等待该信号量,那么就会有另一个任务进入就绪态,信号量的值就不加1。

之后,这个释放的信号量给那个等待中的任务,要看内核如何调度的。收到信号量的任务可能如下:

◆等待任务中,优先级最高的;(uc/os-ii仅支持这种方式)。

◆等待任务中所有等待该信号量的任务

2. 信号量的有效与无效问题

信号量有效:信号量的计算器非0(.OSEventCnt!=0)。信号量有效表示任务对   资源可用。

信号量无效:信号量的计算器为0。信号量无效表示任务对目前资源不可用,需  要等待其他另一个任务(或者中断服务子程序)发出该信号量

3. 信号量的值(.OSEventCnt)大小表示什么?

①二值信号量,表示任务可以独占共享资源。

②计数式信号量,用于某资源可同时为N个任务所用。

4. 信号量有关的三个重要函数分析

◆OSSemCreate() 创建一个信号量  (注:由任务或启动代码操作)

创建工作必须在任务级代码中或者多任务启动之前完成。功能只要是先获取一个事件控制块ECB,写入一些参数。其中调用了OS_EeventWaitListInt()函数,对事件控制块的等待任务列表进行初始化。完成初始化工作后,返回一个该信号量的句柄(Handle)。

◆OSSemPend() 等待一个信号量 (注:只能由任务操作)

本函数应用于任务试图获得共享资源的使用权、任务需要与其他任务或中断同步及任务需要等待特定事件发生的场合。

如果任务Task_A调用OSSemPend(),且信号量的值有效(非0),那么OSSemPend()递减信号量计数器(.OSEventCnt),并返回该值。换句话说,Task_A获取到共享资源的使用权了,之后就执行该资源。

如果如果任务Task_A调用OSSemPend(),信号量无效(为0),那么OSSemPend()调用OS_EventTaskWait()函数,把Task_A放入等待列表中。(等待到什么时候呢?要看OSSemPost()(或者等待超时情况),由它释放信号量并检查任务执行权,见下资料)

◆OSSemPost() 发出(释放)一个信号量 (注:由任务或中断操作)

本函数其中调用OS_EventTaskRdy()函数,把优先级最高的任务Task_A(在这假如是Task_A,另外假设当前调用OSSemPost()的任务是Task_B)从等待任务列表中去除,并使它进入就绪态。然后调用OSSched()进行任务调度。如果Task_A是当前就绪态中优先级最高的任务,则内核执行Task_A;否则,OSSched()直接返回,Task_B继续执行。

【互斥型信号量专题】

1.互斥型信号量(mutex)

互斥型信号量具备uc/os-ii信号量的所有机制,但还具有其他一些特性。

任务可利用互斥型信号量来实现对共享资源的独占处理。

Mutex是二值信号量,1表示资源是可以使用的。

2.关于优先级反转(PIP)

下面概述优先级反转原理:

假设有三个任务,分别命名为A,B,C;A的优先级最高,C的优先级最低。任务A和任务B处于挂起状态(请注意这条件),等待某一事件的发生,任务C正在运行。当任务C等待到共享资源(命名为S1)并使用后,如果任务A等待得事件到来之后,由于A的优先级最高,所以就会剥夺任务C的CPU使用权。运行过程中,任务A也要使用资源S1,但S1的信号量还被任务C占用着,所有任务A只能进入挂起状态,等待任务C对S1的信号量的释放。此时任务C得以继续运行。

同理,任务B的事件到来后,会剥夺任务C的CPU使用权。任务B把事情搞定以后,把CPU使用权归还给任务B。任务B又得以继续运行,任务B认真处理完毕资源S1后,终于可以释放S1的信号量。而处于等待该信号量的任务A马上得到信号量并开始处理共享资源S1。

综述上面情况,任务C和任务A的优先级发生了反转。而互斥型信号量就是具有解决优先级反转问题的特性。

3.UC/OS-II的互斥型信号量由三个部分组成:

◆一个标志,指示mutex是否可以使用(0或1)

◆一个优先级,准备一旦高优先级的任务需要这个mutex,赋予给占有mutex的任务。

◆一个等待该mutex的任务列表。

时间: 2024-09-30 18:29:42

UC/OS-II功能介绍、要点记录的相关文章

uC/OS II 任务切换原理

今天学习了uC/OS II的任务切换,知道要实现任务的切换,要将原先任务的寄存器压入任务堆栈,再将新任务中任务堆栈的寄存器内容弹出到CPU的寄存器,其中的CS.IP寄存器没有出栈和入栈指令,所以只能引发一次中断,自动将CS.IP寄存器压入堆栈,再利用中断返回,将新任务的任务断点指针弹出到CPU的CS.IP寄存器中,实现任务切换.虽然明白个大概,但是其中的细节却有点模糊,为什么调用IRET中断返回指令后,弹入CPU的CS.IP寄存器的断点指针是新任务的断点指针,而不是当前任务的,UCOS II是如

uC/OS II 函数说明 之–OSTaskCreate()与OSTaskCreateExt()

1. OSTaskCreate()    OSTaskCreate()建立一个新任务,能够在多任务环境启动之前,或者执行任务中建立任务.注意,ISR中禁止建立任务,一个任务必须为无限循环结构.        源码例如以下: #if OS_TASK_CREATE_EN > 0                    /* 条件编译,是否同意任务的创建               */INT8U  OSTaskCreate (void (*task)(void *pd), /* 函数指针,void *

Python中模块之os & sys的功能介绍

os & sys的功能介绍 1. os模块 1. os的变量 path 模块路径 方法:os.path 返回值:module 例如:print(os.path) >>> <module 'ntpath' from 'D:\\python3.5.2\\lib\\ntpath.py'> #返回posixpath和netpath两个模块中任意一个模块 name 模块名 方法:os.name 返回值:str 例如:print(os.name) >>> nt

Exchange2016正式版功能介绍及全新安装配置

Exchange2016功能介绍及全新安装配置 说到Exchange服务相信很多人都在关注,微软在2015年更新了很多服务,从功能上来说确实做了很多优化及提升,具体就不多说了,微软在2015年10月1日发布了Exchange2016正式版,版本还是分为标准版和企业版,此次发布为多语言版本 同样微软在2015年发布了那些新产品呢 : 我们还是说说Exchange2016,从安装及官网文档上看微软从Exchange2010到Exchange2016角色上缩减了很多,从Exchange2010的Mai

GPS接收器控件TGPS下载及功能介绍

TGPS是一个Delphi控件,包装了GPS接收器的相关接口.TGPS是一个GPS接收器接口,它可以用于所有发送NMEA 0183数据的GPS接收器,同时也可以连接计算机的串行通信端口. TGPS的功能特性包括: 可以获取位置.时间.速度.标题.方位.路标.线路等等(主要取决于GPS接收器提供的数据,不同的GPS接收器接收的数据也可能有一些差异) 包含两个组件:提供卫星位置的图片以及信号强度 自动识别COM端口,波特率等等 TGPS 组件在Delphi 3.0, 4.0, 6.0 和 7.0开发

国际版本Office365与国内版本office365的功能介绍

说到office365相信大家也会同时想到windows azure,两个都是微软推出的云层次的功能服务.当然功能服务对于微软来说都会定义不同版本,比如最常见的操作系统,分为企业.专业.家庭等--对于微软推出的云服务来说也本例外,目前不管是office365还是windows azure,分为国内版本及国际版本,在功能上有一定差别,数据中心的托管中心也有差别,比如国际主要分布在美国,而国内版本分布在中国了,在中国委派给世纪互联做运营管理,当然具体的权限及操作还是在美国微软.在中国主要分布在北京和

从头认识Spring-3.8 简单的AOP日志实现(注解版)-扩展添加检查订单功能,以便记录并检測输入的參数

这一章节我们讨论一下扩展添加检查订单功能,以便记录并检測输入的參数. 1.domain 蛋糕类: package com.raylee.my_new_spring.my_new_spring.ch03.topic_1_8; public class Cake { private String name = ""; public String getName() { return name; } public void setName(String name) { this.name =

从头认识Spring-3.8 简单的AOP日志实现(注解版)-扩展增加检查订单功能,以便记录并检测输入的参数

这一章节我们讨论一下扩展增加检查订单功能,以便记录并检测输入的参数. 1.domain 蛋糕类: package com.raylee.my_new_spring.my_new_spring.ch03.topic_1_8; public class Cake { private String name = ""; public String getName() { return name; } public void setName(String name) { this.name =

Oracle EBS WMS功能介绍(二)

(版权声明,本人原创或者翻译的文章如需转载,如转载用于个人学习,请注明出处:否则请与本人联系,违者必究) 出货物流逻辑主要包括 1.      打包,可以进行多层嵌套式的打包,并通知用户为订单所做的特殊打包方法.打包可以在拣货时做,也可以作为一个独立的操作来做. 2.      为行程进行码头预约,可以使仓库经理计划出库运输公司的预约,码头门的可用性和仓库内的待装区的使用. 3.      拣货方法,为不同订单的拣货需要选择不同的拣货方法. 4.      管理拣货,可以使订单基于移动手持应用拣