uCOS-II 入门理解

合集下载

第30讲UCOSII入门

第30讲UCOSII入门

30.1 UCOSII 简介
30.1.1 30.1.2 30.1.3 30.1.4 30.1.5 30.1.6 UCOSII背景知识 UCOSII体系结构 UCOSII基本概念 UCOSII的初始化和启动 UCOSII常用任务管理函数 UCOSII时间管理
广州星翼电子
官方淘宝店:
广州星翼电子 官方淘宝店: 技术支持论坛:
《原子教你玩STM32》系列视频
30.1.2 UCOSII体系结构
用户应用程序
UCOSII
UCOSII与处理器无关的代码 ucos_ii.h ucos_ii.c os_tmr.c os_time.c os_task.c os_sem.c os_q.c os_mutex.c os_mem.c os_mbox.c os_flag.c os_core.c
广州星翼电子
官方淘宝店:
技术支持论坛:
《原子教你玩STM32》系列视频
广州星翼电子
官方淘宝店:
技术支持论坛:
《原子教你玩STM32》系列视频
任务控制块OS_TCB
用来记录任务堆栈指针,任务当前状态以及任务优先级等任务 属性。UCOSII的任何任务都是通过任务控制块(TCB)的东西 来控制的,一旦任务创建了,任务控制块OS_TCB就会被赋值。 每个任务管理块有3个最重要的参数:1,任务函数指针;2, 任务堆栈指针;3,任务优先级;任务控制块就是任务在系统 里面的身份证(UCOSII通过优先级识别任务),任务控制块我 们就不再详细介绍了,详细介绍请参考任哲老师的《嵌入式实 时操作系统UCOSII原理及应用》一书第二章。
UCOSII与应用程序 相关代码 os_cfg.h includes.h
UCOSII与处理器相关的代码(移植时需要修改) os_cpu.h os_cpu_a.asm os_cpu_c.c

uCOS-II ppt 入门基础

uCOS-II  ppt 入门基础

硬件初始化
• 系统启动处理(在调用uC/OS-II操作系统初始化函数 OSInit()前,需要对CPU进行必要的初始化,例如设置异 常处理栈空间。要使uC/OS-II能够正常运行,时钟任务是 必不可少的。另外,启动代码需要存储在哪个内存空间, 在运行时需要在哪个内存中运行,这些都需要程序员手动 设置。)
典型的main函数
• • • • • • • • • • • • • • void main (void) { /*-----硬件初始化,等用户代码初始化-----*/ ... OSInit(); /* 初始化uC/OS-II */ …/*-------安装中断向量---------*/ /*通过调用OSTaskCreate ( ) 或OSTaskCreateExt ( )创建至少一个任务;*/ OSTaskCreate(TaskStart , (void*)0, &TaskStartStk[TASK_STK_SIZE - 1], 2 ); … /*通过调用OSSemCreate() 创建信号量等任务通信方式;*/ CalcSem = OSSemCreate(0); … OSStart(); /* 开始多任务调度!OSStart()永远不会返回 */ }
时钟
PC机上移植和运行uC/OS-II要注意其与PC机中其他操 作系统的关系(主要是与DOS操作系统之间的关系),不 能因为安装了uC/OS-II而使其他操作系统不能正常使用。 • 在PC机中,DOS系统时间的周期为 54.93ms(18.20648HZ)。 • DOS操作系统的系统时钟是由PC机上配置的硬件定时 DOS PC 器产生的。在硬件定时器的每个定时周期结束时,硬件定 时器便向CPU申请一次中断,在中断服务程序中处理DOS 所需要的系统时钟,同时处理DOS系统有关时间的一些管 理事务。在80X86系统的中断向量表中,产生DOS系统时 钟硬件定时器所占用的中断向量为0x08. • 在这我们把uC/OS-II的系统时钟频率设置为200HZ,这 显然比DOS的时钟频率高得多。因此,借用产生的DOS系 统时钟的定时器信号来产生uC/OS-II系统时钟。200除于11 等于18.18约等于18.2.后把uC/OS-II的时钟中断向量安装到 0x08上,而把0x08中原来的DOS的时钟中断向量转存到中 •

我的ucOS-II笔记

我的ucOS-II笔记

1.选择uC/OS-II嵌入式操作系统的原因。

●与终端硬件平台相适应,全部源代码5500行,可裁减定制,生成的可执行代码占15~20k,可以移植到多种系列单片机上,包括ARM;●考虑成本,免费的源代码公开;●uC/OS-II代码简单,容易掌握和使用;具有多任务调度的基本功能;2.uC/OS-II嵌入式操作系统的缺点●缺少技术支持,相关的支持软件少;●和商业软件比,功能较弱(如不支持时间片轮转,最大任务数为64等);对应用开发的支持不够;3.uC/OS操作系统的特点uC/OS是一个完成的,可移植、可固化、可裁减的抢占式实时多任务操作系统内核。

主要用ANSI的C语言编写,少部分代码是汇编语言。

uC/OS主要有以下特点:1、可移植性可以移植到多个CPU上,包括三菱单片机。

2、可固化可以固化到嵌入式系统中3、可裁减可以定制uC/OS,使用少量的系统服务4、可剥夺性uC/OS是完全可剥夺的实时内核,uC/OS总是运行优先级最高的就绪任务。

5、多任务运行uC/OS可以管理最多64个任务。

不支持时间片轮转调度法,所以要求每个任务的优先级不一样。

6、可确定性uC/OS的函数调用和系统服务的执行时间可以确定。

7、任务栈每个任务都有自己的单独的栈,而且每个任务栈空间的大小可以不一样。

8、系统服务uC/OS有很多系统服务,如信号量、时间标志、消息邮箱、消息队列、时间管理等等。

4.uC/OS基本概念1、前后台系统也称为超循环系统。

应用程序是一个无限的循环,循环中实现相应的操作,这部分看成后台行为。

用中断服务程序处理异步事件,处理实时性要求很强的操作,这部分可以看成前台行为。

2、共享资源可以被一个以上任务使用的资源叫做共享资源。

3、任务:一个任务是一个线程,一般是一个无限的循环程序。

一个任务可以认为CPU资源完全只属于自己。

任务可以是以下五种状态之一:休眠态,就绪态,运行态,挂起态和被中断态。

uC/OS-II提供的系统服务可以使任务从一种状态变为另一种状态。

第五篇:uCOS-II

第五篇:uCOS-II

第五篇:uCOS-II 信号量及其操作1.信号量使⽤信号量之前⾸先要对信号量有⼀个本质的认识(1)信号量的含义:信号量是⼀类事件,使⽤信号量的最初⽬的是为了给共享资源设⽴⼀个标志,该标志表⽰共享资源的占⽤情况,这样,当⼀个任务在访问共享资源之前,就可以对这个标志进⾏查询,从⽽在了解资源被占⽤的情况之后,再来决定⾃⼰的⾏为。

(2)UCOS-II的信号量⾥⾯有⼀个OSEventCnt,正确的认识这个,是使⽤信号量的关键。

OSSemCreate(0):这种情况下可以⽤任务的同步。

OSSemCreate(1):这种情况类似于互斥信号量,有⼀个名字就是⼆值信号量,可⽤于⼀个资源的使⽤OSSemCreate(>1):这种情况表⽰有>1个资源可以使⽤。

(3)OSEventCnt的初始数据代表可⽤的资源数,1就是⼀个可⽤资源,n就是n可⽤资源。

(4)OSTimeTick 函数⾥⾯有⼀个需要注意的地⽅。

a如果事件中设置了0SxxxPend的延时的话,会进到下⾯函数的这个地⽅。

b如果设置的是⼀直等到的话,将通过OSXXXPost释放。

在延迟的时间⾥⾯没有就绪的话,任务OSTCBStatPend被设置成超时,并清除相应的标志位。

if ((ptcb->OSTCBStat & OS_STAT_PEND_ANY) != OS_STAT_RDY) {ptcb->OSTCBStat &= (INT8U)~(INT8U)OS_STAT_PEND_ANY;ptcb->OSTCBStatPend = OS_STAT_PEND_TO;}在延迟的时间⾥⾯任务收到信息,任务OSTCBStatPend被设置成OKelse{ptcb->OSTCBStatPend = OS_STAT_PEND_OK;}如果任务没有被挂起的话,任务将加⼊到就绪列表。

if ((ptcb->OSTCBStat & OS_STAT_SUSPEND) == OS_STAT_RDY) {OSRdyGrp |= ptcb->OSTCBBitY;OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX;}(5)下⾯分两种情况进⾏详细的讨论A. OSSemCreate(0)这种情况下⽤于信号的同步OSSemPen(xx, 0, xx)设置为0的话,任务将被⼀直挂起直到收到OSSemPost信号。

uCOS-II一些入门资料_内核架构解析等

uCOS-II一些入门资料_内核架构解析等

嵌入式系统——基础知识操作系统OS控制和管理计算机软硬件资源,合理组织计算机工作流程,方便用户使用计算机的系统软件。

可将OS看成是应用程序与硬件间的接口或虚拟机。

OS功能:进程管理、存储管理、文件管理、设备管理、网络和通信管理等。

嵌入式操作系统EOS运行在嵌入式硬件平台上,对整个系统及其所操作的部件装置等资源进行统一协调、指挥和控制的系统软件。

EOS特点:微型化、可裁剪性、实时性、高可靠性、易移植性重点关注:高实时性、硬件相关依赖性、软件固化、应用专用性、网络功能。

实时操作系统TROS能使计算机及时响应外部事件请求,并能及时控制所有实时设备与实时任务协调运行,且能在规定时间内完成事件处理的OS。

RTOS基本要求:1、逻辑功能正确:RTOS的计算必须产生正确的结果;2、时间正确:RTOS的计算必须在预定的周期内完成。

RTOS应满足条件:1、多任务系统;2、任务的切换时间应与系统中的任务书无关;3、中断延时的时间可预知并尽可能短。

无论在什么情况下,OS完成任务所需的时间应该是在程序设计时就可预知的。

嵌入式实时操作系统ERTOS用于嵌入式系统,对系统资源和多个任务进行管理,且具有高可靠性、良好可裁剪性等优良性能的,为应用程序提供运行平台和实时服务的微型系统软件。

ERTOS最重要的三项服务:1、多任务管理2、内存管理3、外围资源管理嵌入式微处理器(特点)1、对实时多任务OS有很强的支持能力;2、具有功能很强的存储区域保护功能;3、处理器结构可扩展;4、低功耗;微处理器主要发展方向:小体积、高性能、低功耗微处理器分类:MCU、MPU、DSP、SOC嵌入式系统发展方向1、嵌入式开发是一项系统工程,嵌入式系统厂商不仅要提供嵌入式软硬件系统本身,还需要提供强大的硬件开发工具与软件支持包;2、网络化、信息化的要求随着因特网技术的成熟、宽带的提高而日益提高,使得以往单一功能的设备功能不再单一,结构更加复杂;3、网络互连成为必然趋势(IEEE1394、USB、CAN、Bluetooth等网络接口);4、精简系统内核、算法、降低功耗和软硬件成本;5、提供友好的多媒体人机界面。

Ucos-II基础原理讲解,任务创建及中断问题

Ucos-II基础原理讲解,任务创建及中断问题

Ucos-II基础原理讲解,任务创建及中断问题2013-6-26 周三Haibara AI Ucos-II在移植过程中的特性,首先要理解所加入的实时操作系统是一个给予定时器节拍的系统。

怎么理解这个问题呢,由该定时器产生脉冲来驱动不同的任务调度,且由于该系统是基于可剥夺内核类型,任务之间的切换时间间隔也由该定时器完成。

不宜过大,否则会造成CPU利用率不高,不宜过小,否则会造成CPU在执行任务时非常被动,时间特别赶。

就想人的心脏一样,动力是固定的,你非要去跑个100公里,心脏不加速你是会窒息而死的。

我们正常心脏跳动是60次左右,同样,单片机也需要一个这样的相对宽松的节拍驱动。

注:众所周知,脉冲本质上仍由晶振提供(或实时时钟),原理都一样,再次请各位不要较真,就暂时以晶振为例。

大家可以考虑一下,晶振的作用是否特别类似于人体的心脏呢?答案是很显然的。

心脏跳动给人体提供输送血液和养料的压力,晶振的设计原理也正是源于此。

他可以像人体心脏一样提供动力输送各个外设(相当于人体器官)所需要的能量。

说这么多,就是要大家理解,人可以实时做出反应,因为人是有生命的,也就是他有反应、判断和处理能力,可以决定什么时间应该做什么。

但是单片机是没有生命的,换句话说,他所谓的处理能力源于人们的代码和程序。

那么,怎么让单片机像人一样拥有生命呢?答案很简单,给他指令,帮助他决定什么时间该做什么,这也就是所谓的实时操作系统。

不只是ucos,其他实时操作系统也是这个道理。

下面我以代码为例,讲述一下ucos的工作流程,如有错误,还请各位前辈指点。

首先任务是怎么样开始执行的?os_err = OSTaskCreateExt((void (*)(void *)) App_TaskStart, */1 (void * ) 0, 2(OS_STK * )&App_TaskStartStk[APP_TASK_START_STK_SIZE - 1],3(INT8U ) APP_TASK_START_PRIO,4(INT16U ) APP_TASK_START_PRIO,5(OS_STK * )&App_TaskStartStk[0],6(INT32U ) APP_TASK_START_STK_SIZE,7(void * )0,8(INT16U )(OS_TASK_OPT_STK_CLR | OS_TASK_OPT_STK_CHK));9这个东西好像是非常复杂,但是实际上并不需要细究(当然非要细究也是允许的,只不过是C语言而已,看也不是看不懂,对于初学者而言并不推荐而已)。

uCOS-II操作系统简介及实验解读

uC/OS-II操作系统
uC/OS-II操作系统
uC/OS-II操作系统简介 及开发过程
uC/OS-II操作系统
内 容
• • • • • • • •
一、 uCOS-II操作系统简介 二、 uCOS-II操作系统内核结构
三、 uCOS-II操作系统任务管理
四、 uCOS-II操作系统内存管理 五、 uCOS-II操作系统时间管理 六、 uCOS-II操作系统任务间的通讯 七、 uCOS-II操作系统移植 八、 uCOS-II操作系统实验
}任务(task)

μC/OS-Ⅱ可以管理多达64个任务。
优先级为0-63 优先级号越低,任务的优先级越高。 每个任务的优先级不能相同。

保留优先级:
高优先级:0、1、2、3 低优先级:OS_LOWEST_PRIO-3、 OS_LOWEST_PRI0-2,OS_LOWEST_PRI0-1以及 OS_LOWEST_PRI0

用户可以有多达56个应用任务。
uC/OS-II操作系统
删除任务
2.3 任务状态
等待 或挂 起 收 到 消 息
挂 起 时 间 到 任务调度
等 待 消 息
挂 起
中断
创建任务
休眠
删除任务
就绪
任务被抢占
删除任务
运行
中断结束
中断 服务
uC/OS-II操作系统
任务状态
• • • • • •
休眠态 - OSTaskCreate()或OSTaskCreateExt() 就绪态 等待态,就绪态,运行态 - OSTaskDel() - 休眠态 就绪态 - OSStart() - 运行态 运行态 - OSTimeDly()或OSTimeDlyHMSM() , OSSemPend(),OSMboxPend(),或OSQPend() 等待态 等待态 - OSTimeTick() -就绪态 空闲任务 - OSTaskIdle()

uCOS-II内核详解

UC/OS-II内核详解一.内核概述:多任务系统中,内核负责管理各个任务,或者说为每个任务分配CPU时间,并且负责任务之间的通讯。

内核提供的基本服务是任务切换。

之所以使用实时内核可以大大简化应用系统的设计,是因为实时内核允许将应用分成若干个任务,由实时内核来管理它们。

内核本身也增加了应用程序的额外负荷,代码空间增加ROM的用量,内核本身的数据结构增加了RAM的用量。

但更主要的是,每个任务要有自己的栈空间,这一块吃起内存来是相当厉害的。

内核本身对CPU的占用时间一般在2到5个百分点之间。

UC/OS-II有一个精巧的内核调度算法,实时内核精小,执行效率高,算法巧妙,代码空间很少。

UC/OS-II的内核还可以被裁剪,Hmax中RTOS的就是一个被高度裁剪过的UC/OS-II。

二.任务控制块 OS_TCB:uC/OS-II的TCB数据结构简单,内容容易理解,保存最基本的任务信息,同时还支持裁减来减小内存消耗,TCB是事先根据用户配置,静态分配内存的结构数组,通过优先级序号进行添加,查找,删除等功能。

减少动态内存分配和释放。

因为依靠优先级进行TCB分配,每个任务必须有自己的优先级,不能和其他任务具有相同的优先级。

typedef struct os_tcb{OS_STK *OSTCBStkPtr;#if OS_TASK_CREATE_EXT_ENvoid *OSTCBExtPtr;OS_STK *OSTCBStkBottom;INT32U OSTCBStkSize;INT16U OSTCBOpt;INT16U OSTCBId;#endifstruct os_tcb *OSTCBNext;struct os_tcb *OSTCBPrev;#if (OS_Q_EN && (OS_MAX_QS >= 2)) || OS_MBOX_EN || OS_SEM_ENOS_EVENT *OSTCBEventPtr;#endif#if (OS_Q_EN && (OS_MAX_QS >= 2)) || OS_MBOX_ENvoid *OSTCBMsg;#endifINT16U OSTCBDly;INT8U OSTCBStat;INT8U OSTCBPrio;INT8U OSTCBX;INT8U OSTCBY;INT8U OSTCBBitX;INT8U OSTCBBitY;#if OS_TASK_DEL_ENBOOLEAN OSTCBDelReq;#endif} OS_TCB;.OSTCBStkPtr是指向当前任务栈顶的指针。

ucosII 学习总结

UCOS II入门学习一、写在前面的话在进行学习ucos II之前,我们先考虑几个问题:1、ucos II是什么?-μCOS-II是一种可移植的,可植入ROM的,可裁剪的,抢占式的,实时多任务操作系统内核。

2、那什么是操作系统,什么是内核?-非计算机相关专业的人,看到这个问题,可能就一下子吓怕了,要学习ucos II是不是一定要先从这些基础学起,是不是要去拿计算机专业的相关知识系统的学一次?个人觉得如果觉得真的很疑惑,可以先百度看看简单的概念,或者可以直接的跳过这个问题的答案,但是脑子里要有这个问题。

配套教材《嵌入式实时操作系统μCOS原理与实践》也有相关介绍;这个时侯可以先什么都不管,我们就以自己只写过简单的C代码的基础,去看看ucos II到底是什么东西。

代码框架二、二、代码框架这是卢有亮教程里的,在VC环境中的配套代码,在C51环境中的划分如下;我们看到基本上是一样的,只是与CPU有关的部分不同而已,而且对于我们的入门学习,这个部分不是我们的重点,这个到最后需要移植时再具体去分析。

现在我们的重点是与CPU无关的CORE即内核代码。

整个UCOS II最主要的代码就是这部分了。

剩下的是用户部分,这里面就是我们根据自己的需要编写的、实现某些具体功能的函数、变量集合。

然后与CPU有关的也是一些具体的功能函数,宏定义等。

现在,我们看到ucos II的所有代码都在这里了,你说很复杂吗,应该也不算,但是简单吗,也不见得。

下面我们看看最主要的、最核心的部分代码即CORE 里面的,到底用来干什么。

三、core内核的功能在具体分析这部分代码之前,我们首先看一个例子:如图:有一个服务员,为了充分利用时间,同时为三个窗口服务,而且要保证这三个窗口中,他觉得最重要的窗口先得到服务。

1、我们先看看他是怎么充分利用时间的:假设当前服务员为窗口3服务,在交谈过程中,窗口3的人需要思考或者接电话等,就是有别的事吧。

这时候服务员为了充分利用时间,不再等他思考完毕,直接给窗口2服务,如果窗口2又有事,服务员就又到窗口1服务,服务完了又回到2或者3中;就这样来回的跑在这三个窗口之间,如果服务员跑得很快,而且服务过程也很快,那么三个窗口的人都会觉得服务员在一直为自己服务。

ucos_II

uC/OS II可以简单的视为一个多任务调度器,在这个任务调度器之上完善并添加了和多任务操作系统相关的系统服务,如信号量、邮箱等。

其主要特点有公开源代码,代码结构清晰、明了,注释详尽,组织有条理,可移植性好,可裁剪,可固化。

内核属于抢占式,最多可以管理60个任务。

CPU 硬件相关部分是用汇编语言编写的、总量约200行的汇编语言部分被压缩到最低限度,为的是便于移植到任何一种其它的CPU 上。

用户只要有标准的ANSI 的C交叉编译器,有汇编器、连接器等软件工具,就可以将μC/OS-II嵌人到开发的产品中。

μC/OS-II 具有执行效率高、占用空间小、实时性能优良和可扩展性强等特点,最小内核可编译至 2KB 。

μC/OS-II 已经移植到了几乎所有知名的CPU 上。

严格地说uC/OS-II只是一个实时操作系统内核,它仅仅包含了任务调度,任务管理,时间管理,内存管理和任务间的通信和同步等基本功能。

没有提供输入输出管理,文件系统,网络等额外的服务。

但由于uC/OS-II良好的可扩展性和源码开放,这些非必须的功能完全可以由用户自己根据需要分别实现。

uC/OS-II目标是实现一个基于优先级调度的抢占式的实时内核,并在这个内核之上提供最基本的系统服务,如信号量,邮箱,消息队列,内存管理,中断管理等。

任务管理uC/OS-II 中最多可以支持64 个任务,分别对应优先级0~63,其中0 为最高优先级。

63为最低级,系统保留了4个最高优先级的任务和4个最低优先级的任务,所有用户可以使用的任务数有56个。

uC/OS-II提供了任务管理的各种函数调用,包括创建任务,删除任务,改变任务的优先级,任务挂起和恢复等。

系统初始化时会自动产生两个任务:一个是空闲任务,它的优先级最低,该任务仅给一个整形变量做累加运算;另一个是系统任务,它的优先级为次低,该任务负责统计当前cpu的利用率。

在系统初始化完毕后启动任务时必须创建一份用户任务,也就是说必须有一个应用程序(用户任务,使用应用程序对于我们经常使用Windows用户容易接受一些。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

uCOS-II 初级程序员指南(一)uC/OS-II 简介uC/OS-II是一种基于优先级的可抢先的硬实时内核。

自从92年发布以来,在世界各地都获得了广泛的应用,它是一种专门为嵌入式设备设计的内核,目前已经被移植到40多种不同结构的CPU 上,运行在从8位到64位的各种系统之上。

尤其值得一提的是,该系统自从2.51版本之后,就通过了美国FAA认证,可以运行在诸如航天器等对安全要求极为苛刻的系统之上。

鉴于uC/OS-II可以免费获得代码,对于嵌入式RTOS而言,选择uC/OS无疑是最经济的选择。

(二)uC/OS-II应用程序基本结构应用uC/OS-II,自然要为它开发应用程序,下面论述基于uC/OS-II的应用程序的基本结构以及注意事项。

每一个uC/OS-II应用至少要有一个任务。

而每一个任务必须被写成无限循环的形式。

以下是推荐的结构:void task ( void* pdata ){INT8U err;InitTimer(); // 可选For( ;; ){// 你的应用程序代码…….……..OSTimeDly(1); // 可选}}以上就是基本结构,至于为什么要写成无限循环的形式呢?那是因为系统会为每一个任务保留一个堆栈空间,由系统在任务切换的时候换恢复上下文,并执行一条reti 指令返回。

如果允许任务执行到最后一个花括号(那一般都意味着一条ret指令)的话,很可能会破坏系统堆栈空间从而使应用程序的执行不确定。

换句话说,就是“跑飞”了。

所以,每一个任务必须被写成无限循环的形式。

程序员一定要相信,自己的任务是会放弃CPU使用权的,而不管是系统强制(通过ISR)还是主动放弃(通过调用OS API)。

现在来谈论上面程序中的InitTimer()函数,这个函数应该由系统提供,程序员有义务在优先级最高的任务内调用它而且不能在for循环内调用。

注意,这个函数是和所使用的CPU相关的,每种系统都有自己的Timer初始化程序。

在uC/OS-II的帮助手册内,作者特地强调绝对不能在OSInit()或者OSStart()内调用Timer初始化程序,那会破坏系统的可移植性同时带来性能上的损失。

所以,一个折中的办法就是象上面这样,在优先级最高的程序内调用,这样可以保证当OSStart()调用系统内部函数OSStartHighRdy()开始多任务后,首先执行的就是Timer初始化程序。

或者专门开一个优先级最高的任务,只做一件事情,那就是执行Timer初始化,之后通过调用OSTaskSuspend()将自己挂起来,永远不再执行。

不过这样会浪费一个TCB空间。

对于那些RAM吃紧的系统来说,还是不用为好。

(三)一些重要的uC/OS-II API介绍任何一个操作系统都会提供大量的API供程序员使用,uC/OS-II也不例外。

由于uC/OS-II面向的是嵌入式开发,并不要求大而全,所以内核提供的API也就大多和多任务息息相关。

主要的有以下几类:1)任务类2)消息类3)同步类4)时间类5)临界区与事件类我个人认为对于初级程序员而言,任务类和时间类是必须要首先掌握的两种类型的API。

下面我就来介绍比较重要的:1)OSTaskCreate函数这个函数应该至少在main函数内调用一次,在OSInit函数调用之后调用。

作用就是创建一个任务。

目前有四个参数,分别是任务的入口地址,任务的参数,任务堆栈的首地址和任务的优先级。

调用本函数后,系统会首先从TCB空闲列表内申请一个空的TCB指针,然后将会根据用户给出参数初始化任务堆栈,并在内部的任务就绪表内标记该任务为就绪状态。

最后返回,这样一个任务就创建成功了。

2)OSTaskSuspend函数这个函数很简单,一看名字就该明白它的作用,它可以将指定的任务挂起。

如果挂起的是当前任务的话,那么还会引发系统执行任务切换先导函数OSShed来进行一次任务切换。

这个函数只有一个参数,那就是指定任务的优先级。

那为什么是优先级呢?事实上在系统内部,优先级除了表示一个任务执行的先后次序外,还起着分别每一个任务的作用,换句话说,优先级也就是任务的ID。

所以uC/OS-II不允许出现相同优先级的任务。

3)OSTaskResume函数这个函数和上面的函数正好相反,它用于将指定的已经挂起的函数恢复成就绪状态。

如果恢复任务的优先级高于当前任务,那么还为引发一次任务切换。

其参数类似OSTaskSuspend函数,为指定任务的优先级。

需要特别说明是,本函数并不要求和OSTaskSuspend函数成对使用。

4)OS_ENTER_CRITICAL宏很多人都以为它是个函数,其实不然,仔细分析一下OS_CPU.H文件,它和下面马上要谈到的OS_EXIT_CRITICAL都是宏。

他们都是涉及特定CPU的实现。

一般都被替换为一条或者几条嵌入式汇编代码。

由于系统希望向上层程序员隐藏内部实现,故而一般都宣称执行此条指令后系统进入临界区。

其实,它就是关个中断而已。

这样,只要任务不主动放弃CPU使用权,别的任务就没有占用CPU 的机会了,相对这个任务而言,它就是独占了。

所以说进入临界区了。

这个宏能少用还是少用,因为它会破坏系统的一些服务,尤其是时间服务。

并使系统对外界响应性能降低。

5)OS_EXIT_CRITICAL宏这个是和上面介绍的宏配套使用另一个宏,它在系统手册里的说明是退出临界区。

其实它就是重新开中断。

需要注意的是,它必须和上面的宏成对出现,否则会带来意想不到的后果。

最坏的情况下,系统会崩溃。

我们推荐程序员们尽量少使用这两个宏调用,因为他们的确会破坏系统的多任务性能。

6)OSTimeDly函数这应该程序员们调用最多的一个函数了,这个函数完成功能很简单,就是先挂起当起当前任务,然后进行任务切换,在指定的时间到来之后,将当前任务恢复为就绪状态,但是并不一定运行,如果恢复后是优先级最高就绪任务的话,那么运行之。

简单点说,就是可以任务延时一定时间后再次执行它,或者说,暂时放弃CPU的使用权。

一个任务可以不显式的调用这些可以导致放弃CPU使用权的API,但那样多任务性能会大大降低,因为此时仅仅依靠时钟机制在进行任务切换。

一个好的任务应该在完成一些操作主动放弃使用权,好东西要大家分享嘛!(四)uC/OS-II 多任务实现机制分析前面已经说过,uC/OS-II是一种基于优先级的可抢先的多任务内核。

那么,它的多任务机制到底如何实现的呢?了解这些原理,可以帮助我们写出更加健壮的代码来。

由于我们面向的初级程序员,本文不打算写成又一篇uC/OS-II的源码分析,那样的文章太多了,本文打算从实现原理的角度探讨这个问题。

首先我们来看看为什么多任务机制可以实现?其实在单一CPU的情况下,是不存在真正的多任务机制的,存在的只有不同的任务轮流使用CPU,所以本质上还是单任务的。

但由于CPU执行速度非常快,加上任务切换十分频繁并且切换的很快,所以我们感觉好像有很多任务同时在运行一样。

这就是所谓的多任务机制。

由上面的描述,不难发现,要实现多任务机制,那么目标CPU必须具备一种在运行期更改PC的途径,否则无法做到切换。

不幸的是,直接设置PC指针,目前还没有哪个CPU支持这样的指令。

但是一般CPU 都允许通过类似JMP,CALL这样的指令来间接的修改PC。

我们的多任务机制的实现也正是基于这个出发点。

事实上,我们使用CALL指令或者软中断指令来修改PC,主要是软中断。

但在一些CPU上,并不存在软中断这样的概念,所以,我们在那些CPU上,使用几条PUSH指令加上一条CALL指令来模拟一次软中断的发生。

回想一下你在微机原理课程上学过的知识,当发生中断的时候,CPU保存当前的PC和状态寄存器的值到堆栈里,然后将PC设置为中断服务程序的入口地址,再下来一个机器周期,就可以去执行中断服务程序了。

执行完毕之后,一般都是执行一条RETI指令,这条指令会把当前堆栈里的值弹出恢复到状态寄存器和PC里。

这样,系统就会回到中断以前的地方继续执行了。

那么设想一下?如果再中断的时候,人为的更改了堆栈里的值,那会发生什么?或者通过更改当前堆栈指针的值,又会发生什么呢?如果更改是随意的,那么结果是无法预料的错误。

因为我们无法确定机器下一条会执行些什么指令,但是如果更改是计划好的,按照一定规则的话,那么我们就可以实现多任务机制。

事实上,这就是目前几乎所有的OS的核心部分。

不过他们的实现不像这样简单罢了。

uC/OS-II v2.52学习摘要(一)特别声明:本笔记是对uc/os-ii研究做一些重要的内核思路整理和心得记录,以日期为作为记录块,故没有思路和规范可言,为此贴于工程师笔记里面,一来方便自己温故知新,二来希望能给初学者带来一些方便和帮助。

高手别见笑^_^,偶刚起步。

另外,如有错误和不当之处,请指正和发表您的心得体会。

谢谢!2005-12-181.任务是一个无返回的无穷循环。

uc/os-ii总是运行进入就绪状态的最高优先级的任务。

2.任务是如何调度(切换)的?因为uc/os-ii总是运行进入就绪状态的最高优先级的任务。

所以,确定哪个任务优先级最高,下面该哪个任务运行,这个工作就是由调度器(scheduler)来完成的。

任务级的调度是由函数OSSched()完成的,而中断级的调度是由函数OSIntExt()完成。

对于OSSched(),它内部调用的是OS_TASK_SW()完成实际的调度(人为模仿一次中断);OSIntExt() 内部调用的是OSCtxSw()实现调度。

参考:P92,P106任务切换其实很简单,由如下2步完成:(1)将被挂起任务的处理器寄存器推入自己的任务堆栈。

(2)然后将进入就绪状态的最高优先级的任务的寄存器值从堆栈中恢复到寄存器中。

参见P92(1)作为uc/os-ii的一条普通原则,调用uc/os-ii功能函数时,中断总应当是开着的。

(2)任务永不返回,就算任务自我删除,也绝对不会返回。

(任务删除并非代码删除,只是ucos-ii不会理会这任务。

)(3)OSTimeTick()函数是ucos-ii内部函数,用户无需调用。

(4)ucos-ii从中断返回之前,要判断被中断的任务是否还是就绪状态任务中优先级最高的任务。

3.OSInit()初始化示意图我做了一个很好的图示,竟然粘贴不出来,没办法...4.任务的5种状态参见P79 图睡眠态(task dormat):任务驻留于程序空间(rom或ram)中,暂时没交给ucos-ii处理。

就绪态(task ready):任务一旦建立,这个任务就进入了就绪态。

运行态(task running):调用OSStart()可以启动多任务。

OSStart()函数只能调用一次,一旦调用,系统将运行进入就绪态并且优先级最高的任务。

相关文档
最新文档