一步一步教你使用uCOS II组合
Task:是指向任务代码的指针, pdata:是任务开始执行是,传递给任务的参数的指针,ptos: 是分配给任务的堆栈的栈顶指针,prio是分配给任务的优先级。 也可以用 OSTaskcreatExt(),不过该函数需要9个参数,前四个参数与 OSTask creat0)样,例 如 INTSU OSTask CreateExt(void( task)(void*pd), void pdata, OS STK*ptos, INT8U prio, INT16U id, OS STK pbos, OS STk pbos, OS STK *pbos, INT16U opt) id参数为要建立的任务创建一个特殊的标识符。pbos是指向任务的堆栈栈底的指针,用于 堆栈的检验。stk_size用」指定堆栈成员数目的容量。pext是指向用户附加的数据域的指 针,用来扩展任务的OS_ TCB. opt用于设定 OSTask create Ext)的选项,指定是否允许堆栈检 验,是否将堆栈清零,任务是否要进行浮点操作等等。 2:任务堆栈 OS STK() 每个任务都有自己的堆栈,堆栈必须申明为 OS STK类型,并且由连续的内存空间组成。可 以静态分配堆栈空间,也可以动态分配堆栈空间 3:堆栈检验 OSTaskStkchk( 有时确定任务实际需要的堆栈空间的大小是很有必要的,因为这样就可以避免为仁务分配过 多的堆栈空间,从而减少应用程序代码所需的RAM空间 4:删除任务 OSTaskde( 有吋需要删除任务,朋除任务,是说仨务返回并处于休眠态,并不是说任务的代码被朋除了, 只是任务的代码不用被UcoS调用。删除任冬前应保证所删仼务并非空闲任务 5:请求删除任务 OSTask Del Req( 有时,任务会占用一些内存缓冲或信号量一类的资源。这时,假如另一个任务试图删除该任 务,这些被占用的资源就会因为没有被释放而云失。在这种情况下,需想办法拥有这些资源 的任务在使用完资源后先释放资源,再朋除自己。 6:改变任务的优先级 OSTaskChangePrio 在建立任务时,会分配给任务一个优先级。在程序运行期间,可以通过调用该函数改变任务 的优先级。也就是说,Ucos允许动态的改变任务的优先级。 7:起仟务 OSTaskSuspend() 冮务挂起是一个附加功能,也就是说,如果任务在被挂起的同时也在等待延迟时间到,那么, 需要对任务做取消挂起的操作,并且等待延迟时间到,任务才能转让就绪状态。任务可以挂 起自己或者其他任务。 8:恢复任务 OSTask Resume( 挂起的仟务只有通过该函数才能被恢复。 9:获得仁务的信息 OSTaskQuery() 通过调用该函数,来获得自身或其他应用任务的信息 时间管理 uC/OS-1的时间管理是通过定时中断来实现的,该定时中断一般为10毫秒或100毫秒发生 次(这个时间片段是oS的作者推荐的,大家可以参考邵贝贝翻译的《嵌入式实时操作系 统ucos-》这本书),时间频率取决于用户对硬件系统的定时器编程来实现。中断发生的时 间间隔是固定不变的,该中断也成为一个时钟节拍。这里隐含的意思就是你选择的芯片如果 想使用UcoS系统,前提条件一定要有一个 Timer u/0S1要求用户在定时中断的服务程序中,调用系统提供的与时钟节拍相关的系统函数, 例如中断级的任务切换函数,系统时间函数。 本课件由 EEWORLD版主 strom讲解,并有 eworld论坛注册用 户wo4 fisher收集整理,送给那些在学习uC/OS的朋友 uCos时间管理的相关函数 1:任务延迟函数 OSTime Dly() Ucos提供一个可以被仼务调用而将任务延时一段特定时间的功能函数,即 OSTime Dly().任务 调用 OSTime Dly()后,一旦规定的时间期满或者有其他的仟务通过调用 OSTime dly Resume( 取消了延时,他就会进入就绪状态。只有当该仨务在所有就绪态任务中具有最高的优先级, 它才会立即运行。 2:按时,分,秒延时函数 OSRimedLyHMSM(0 与 OSTimeDly()一样,调用 OSRime DlyHMSM(函数也会是UCos进行一次任务调度,并且执 行下一个优先级最高的就绪仟务。当 OSTime DlyHMSM()后,一旦规定的时间期满,或者有 OSTime dly Resume(),它就会马上处于就绐态。同样,只有当该任务在所有就绪态任务中具 有最高的优先级,他才开始运行。 3:恢复延时的任务 OSTime dly Resume( 延时的任务可以不等待延时的期满,而是通过其他任务取消延时而使自己处于就绪态,可以 通过该函数来实现,实际上, OSTime Dly Resume(也可以唤醒正在等待的事件。 4:系统时间 oSTimeget(和 oSTimeset() 内存管理 在ANSC中是使用 malloc和free两个函数来动态分配和释放内存。例如在 Linux系统中就 是这样。但在嵌入式实时系统中,多次这样的操作会导致内存碎片,因为嵌入式系统尤其是 uCoS是实地址模式,这种模式在分配任务堆栈吋需要整块连续的空间,否则任务无法止桷 运行。且山于内存管理算法的原因,malc和fre的执行时间也是不确定。这点是实时内 核最大的矛盾。 基于以上的原因uC/oS4中把连续的大块内存按分区管理。每个分区中包含整数个大小相同 的内存块,但不同分区之间的内存快大小可以不同。用户需要动态分配内存时,系统选择 个适当的分区,按块来分配内存。释放内存时将该块放回它以前所属的分区,这样能有效解 决碎片问题,同时执行时间也是區定的。 同时uCOS-根据以上的处理封装了适合于自己的动态内存分配函数 OSMemget()和 OSEm Put(),但是使用这两个函数动态分配內存前需要先创建内存空间,也就是第二段 咱们介绍的内存分块。呵呵,不罗嗦了,具体的关于內存管理的函数如下 内存控制块的数据结构 Typedef struct oid* osmemaddr;指向内存分区起始地址的指 Void* osmemfreelist;指向下一个空余内存控制块或者下一个空余内存块的指针, nt32 u osmemblksize;内存分区中内存块的大小,是建立内存分区时定义的 nt32 u osmemnb|ks;内存分区中总的内存块数量,也是建立该内存分区时定义的。 nt3 2u osmemnfree;内存分区块中当前获得的空余块数量 os mem; 1:;建立一个内存分区, OSMem Create) 2:分配一个内存块, OSMem get() 应用程序通过调用该函数,从已经建立的内存分区中申请一个内存块。该函数唯一的参数是 指向特定内存分区的指针 3:释放一个内存块, OSMem Put() 本课件由 EEWORLD版主 strom讲解,并有 eworld论坛注册用 户wo4 fisher收集整理,送给那些在学习uC/OS的朋友 当应用程序不再使用一个内存块时,必须及时的把它释放,并放回到相应的内存分区中,这 个操作就是通过调用该函数实现的。 4:查询一个内存分区的状态, OSQMemQuery( 任务间通信与同步 对一个多任务的操作系统来说,任务间的通信和同步是必不可少的。uC/OS-中提供了4和 同步对象,分别是信号量,邮箱,消息队列和事件。所有这些同步对象都有创建,等待,发 送,查询的接口用于实现进程间的通信和同步。 对于这4种同步对象将在后面一一讨论。 任务调度 uC/os-米用的是可剥夺型实时多任务内核。可剥夺型的实时内核在任何时候都运行就绪了 的最高优先级的任务。 uC/os-的任务调度是完全基于任务优先缴的抢占式调度,也就是最高优先级的任务旦处 于就绪状态,则立即抢占正在运行的低优先级任务的处理器资源。为了简化系统设计, C/Os1规定所有任务的优先级不同,因为任务的优先级也同时唯一标志了该任务本身。 UcOS的任务调度在一下情况下发生 1)高优先级的任务因为需要某和临界资源,主动请求挂起,让出处理器,此时将调度就绪 状态的低优先级任务获得执行,这种调度也称为任务级的上下文切换。 2)高优先级的任务因为时钟节拍到来,在时钟中断的处理程序中,内核发现高优先级任务 获得了执行条件(如休眠的时钟到时),则在中断态直接切换到高优先级任务执行。这种调度 也称为中断纵的上下文切换 这两种调度方式在uC/Os-1的执行过程中非常普遍,一般来说前者发生在系统服务中,后者 发生在时钟中断的服务程序中。 调度工作的内容可以分为两部分:最高优先级任务的寻找和任务切换。其最高优先级任务的 寻找是通过建立就绪任务表来实现的。uC/OS中的每一个任务都有独立的堆栈空间,并有 个称为任务控制块TCB( Task control block)的数据结构,其中第一个成员变量就是保存的任 务堆栈指针。仟务调度模块首先用变量 OSTCBHighRdy记录当前最高级就绪仟务的TCB地 址,然后调用OS_TASK_sW(函数米进行任务切换 第二章搭建UCOS-2.52版的调试平台 在这一章中我们主要讨论UCOS的源码调试环境,为了给大家一个共同的学习平台,我搜 集整理了一写资料,就是以X86为台,使用BC31(这个堪称骨灰级的编译器)来调试 UCOSII 源码。当然你也可以用BC45或更高版本的编译器,具体方法大同小异,我在此就不再啰嗦 本章节的主要内容包括四点: 1、下载并安装BC31编译器 2、下载并安装UCOS-2.52版本源代码 3、使用BC31编译UCOS源吗 4、让OS的第一个任务RUN起来 本课件由 EEWORLD版主 strom讲解,并有 eworld论坛注册用 户wo4 fisher收集整理,送给那些在学习uC/OS的朋友 接下来会在每个帖子中讨论一点。耐心等待哦! 下载并安装BC31编译器 我在这里提供给大家这个骨灰级的编译器BC31需要的可以下载。见附件〔骨灰级编译器 BC31)由于这个软件的比较大,分成两个压缩包。下班了,先到这里,回家再传附件 让自己的第一个任务Run起来 前面已经给大家介绍了如何在PC机上调试UCOS,方法和需要的软件都介绍给大家了,相 信有兴趣的朋友凵经安装调试了,下面咱们就让自u的第一个任务在PC上Run起来。 OK,下面我就分步介绍建立自己的第一个任务 笫一步: Copy:\ SOFTWARE\uCS-目录下的EX1x86L文件火。作为我们的工程模板 第二步:修改工程模板的名字为:Hel| oNEWorld 竻三部:按照咱们前面的《使用BC31工具编译υoS-II的源码过程》修改配置文件: 第四步:修改 Test.c文件,建立自己的第个任务 具体的内容我就不帖子上写了。大家可以参考附件 HelloeeWorld. rar里面的 Test.c文件。 然后编译 oK,第一个任务就Run起来了,显小如下界面 cA C: \SOFTWARE\uCOS-II\HELLOE I\BC45\TEST\TEST. EXE Use uC/oS-II Step by Step By ustron Hello EEWorld Example Hello EWOrld He llo EWOrld Hello EWOrld Hello EWOrld mAsks CPU Usage:■ 83P MTask switch/sec - PRESS·E$ C TO QUIT- 第三章:关于UCOS任务的理解 关于UC0S任务的理解 UCOS的运行是基于任务运行的,为了能够好的使用UCOS我们先要对UCOS的任务的概念 做一个理解 在学习UCOS任务前我们先对我们以前使用的模式做一个回顾一一前后台模式。 本课件由 EEWORLD版主 strom讲解,并有 eworld论坛注册用 户wo4 fisher收集整理,送给那些有学习uC/Os的朋友... Background -- Foreground- ISR Time ISR 电了工酲世界 Code execu eworld com. cn 自电设计之 2011-3-622:2 这种系统可称为前后台系统或超循环系统( Super-Loos)。应用程序是一个无限的循环,循环 中调用相应的函数完成相应的操作,这部分可以看成后台行为 background)。中断服务程序 处埋异步事件,这部分可以看成前台行 foreground。后台也可以叫徹任务级。前台也叫中断 级。时间相关性很强的关键操作( Critical operation)一定是靠中断服务来保证的。因为中断服 务提供的信息一直要等到后台程序走到该处理这个信息这一步时才能得到处理,这种系统在 处理信息的及时性上,比实际可以做到的要差。这个指标称作仼务级响应时间。最坏情况卜 的任务级响应时间取决于整个循环的执行时间。因为循环的执行时间不是常数,程序经过某 特定部分的准确吋间也是不能确定的。进而,如果程序修改了,循环的吋序也会受到影响。 这种系统是在我们上学时和做小项日时经常用到,很多工程师称这种方式为“裸奔”。哈哈! 我大学毕业后的钱三年写的项目都是在裸奔 UCoS-是基」任务运行的。一个任务,也称作一个线程,是一个简单的程序,该程序可以 认为CPU完全只属该程序自己。实时应用程序的设计过程,包括如何把问题分割成多个仟 务,每个任务都是整个应用的某部分,每个任务被赋予·定的优先级,有它自己的套 CPU寄存器和自己的栈空间(如下图所示)。 本课件由 EEWORLD版主 strom讲解,并有 eworld论坛注册用 户wo4 fisher收集整理,送给那些有学习uC/Os的朋友... TASK #1 TASK #2 TASK #n stack Stack Stack Task Task LInArin MEMORY CPU 电子工酲世界 eworld comen 钢电寻设钟之 Pic22011-3-622:23 可以这么解,UCOS1的每个任务都有个CPU,任务在运行时占用CPU的全部资源, 同时拥有自己的一套寄存器,当任务执行完毕后(时间片到),他把自己的CPU寄存器所有 内容保存到自己的堆栈中,同时把CPU让给别的任务,那么得到CPU使用权的任务把自己 的CP∪寄存器从自凵的堆栈中放到真正的CPU寄存器中廾始运行,就这样周而复始。 人家一定不要把仟务的运行当成是函数的调用,这完全是两回事。这个我们到后面的仟务调 度时在细说。每个任务都是一个无限的循环。每个任务都处在以下5种状态之一的状态下, 这5种状态是休眠态,就绪态、运行态、挂起态(等待某一事件发生)和被中断态(参见 下图)休眠态相当于该任务驻留在内存中,但并不被多任务内核所调度。就绪意味着该 任务已经准各好,可以运行了,但由于该任务的优先级比止在运行的任务的优先级低,还 暂时不能运行。运行态的仟务是指该仟务掌握了CPU的控制权,正在运行中。挂起状态也 可以叫做等待事件态 WAITING,指该任务在等待,等待某一事件的发生,(例如等待某外 改的/o換作,等待某共享资源由暂不能使用变成能使用状态,等待定时脉冲的到来或等 待超时信号的到来以结東目前的等待,等等)。最后,发生中断时,CPU提供相应的中断 服务,原来止在运行的任务暂不能运行,就进入了被中断状态。如下图表示C/OS-II中 些函数提供的服务,这些函数使任务从一种状态变到力一种状态。 本课件由 EEWORLD版主 strom讲解,并有 eworld论坛注册用 户wo4 fisher收集整理,送给那些有学习uC/Os的朋友... WAITING OSMB)xPo osMEraPand SPeNd OSopostfrontg oSTadE OSSonmPest oSScmpend sTasrRagmnn OSTasksuspn oSTimsuyRasuneo oSTimeDlyy osTioTEby OSTime DIdHNSHn oSTagkacotci OsT3skc1em1=En0 osstartt OS TASK SY DORMANT READY RUNNING ISR asTaskbely oSnIEx) 电子上m界 eworld.com.cn Pic32011-3-622:23 简单的我们可以把每一次任务的切换当成一次中断,这个中断不同于我们在使用前后台模式 吋的中断,那个中断是硬件中断,中断时需要保存的CPU寄存器是由硬件实现的,而在UCoS 中的仟务切换是软中断,CPU保存了必要的寄存器后在切换时系统会在保存仟务使用的寄存 补充知识-可剥夺型内核和不可剥夺型内核 不可剥夺型内核 不可剥夺型内核要求每个任务自我放弃CPU的所有权。不可剥夺型调度法也称作合作型多 任务,各个任务彼此合作共享个CPU。异步事件还是由中断服务来处理。中断服务可以 使一个高优先级的任务由挂起状态变为就绪状态。但中断服务以后控制权还是回到原来被 中断了的那个任务,直到该任务主动放弃CPU的使用权时,那个高优宄级的任务才能获得 CPU的使用权。 不可剥夺型内核允许每个任务运行,直到该任务自愿放弃CpU的控制权。中断可以打入运 行着的任务。中断服务完成以后将CPU控制权还给被中断了的任务。任务级响应时间要 大大好于前后系统,但仍是不可知的,商业软件几乎没有不可剥夺型内核。 不可剥夺型内核的工作过程见下图: 本课件由 EEWORLD版主 strom讲解,并有 eworld论坛注册用 户wo4 fisher收集整理,送给那些有学习uC/Os的朋友... Low Priority task 1 ISR (3 ISR makes the high priority task ready Time 5 High Priority Task Low priority task re languishes the CPu G 电程世界 eworld. com. cn 电干旋计2源 20113-622:26 可剥夺型内核 当系统响应时间很重要吋,要使用可剥夺型内核。因此,μC/0S-II以及绝大多数商业上销 售的实时内核都是可剥夺型内核。最高优先级的仟务一旦就绪,总能得到CPU的搾制权。 当一个运行着的任务使一个比它优先级高的任务进入了就绪态,当前任务的CPU使用权就 被剥夺了,或者说被挂起了,那个高优先级的任务立刻得到了CPU的控制权。如果是中断 服务子程序使一个高优先级的任务进入就绪态,中断完成时,中断了的任务被挂起,优先级 晑的那个任务开始运行。使用可剥夺型内核,最高优先级的任务什么时候可以执行,可以得 到cPU的控制权是可知的。使用可剥夺型内核使得任务级响应时间得以最优化。 可剥夺型内核的工作过程是这样的 Low Priority Task High priority Task ISR makes the high priority task ready Time 电子工酲世界 eworld. com. cn 2011-3-622:26 UC0s-II任务调度 本课件由 EEWORLD版主 strom讲解,并有 eworld论坛注册用 户wo4 fisher收集整理,送给那些有学习uC/Os的朋友...
用户评论