wstrom 发表于 2011-2-27 16:29

一步一步教你使用uCOS-II

<div class='showpostmsg'><P>前言篇</P>
<P>&nbsp;</P>
<P>前段时间看了Linux版块“zjw50001”网友上传的资料《一步一步教你开发嵌入式 Linux 应用程序》感觉对于学习Linux的新手来说有很大帮助。同时也很受启发。决定在UCOS版块发这样一个连续贴来介绍一下uCOS-II。主要包括uCOS-II的介绍、UCOS-II的移植、uCOS-II的的源码解析和UCOS-II的应用案例。</P>
<P>uCOS-II的版本采用常用的2.52版本,开发平台用我手头现有的STM32F103XXX自制的开发板。</P>
<P>在这采用边写边讨论的方式。如果在过程中大家有疑问请及时跟帖提出。会在每篇后给出解决方法,同时考虑到工作量比较大,所以希望大家积极参与,让我们共同把uCOS-II这个嵌入式操作系统的知识传授个每一位需要的网友。</P>
<P>&nbsp;</P>
<P><FONT color=red><FONT size=5>105楼 <CITE>leang521 上传了Borland C++ V3.1原版,需要的坛友可以去下载。在此向leang521 致谢!</CITE></FONT></FONT></P>
<P><FONT color=red><FONT size=5><CITE></CITE></FONT></FONT>&nbsp;</P><FONT color=red><FONT size=5><CITE>
<P>&nbsp;</P>
<P><FONT color=blue>我申请了一个公共邮箱</FONT><A href="mailto:bc31_share@163.com"><FONT color=blue>bc31_share@163.com</FONT></A><FONT color=blue>,邮箱密码eeworld。</FONT></P>
<P><FONT color=blue>以后需要BC31的朋友可以登录这个邮箱下载。望各位互相转告!</FONT></P></CITE></FONT></FONT>

[ 本帖最后由 wstrom 于 2011-7-29 11:30 编辑 ]</div><script>                                var loginstr = '<div class="locked">查看精华帖全部内容,请<a href="javascript:;"   style="color:#e60000" class="loginf">登录</a>或者<a href="https://bbs.eeworld.com.cn/member.php?mod=register_eeworld.php&action=wechat" style="color:#e60000" target="_blank">注册</a></div>';
                               
                                if(parseInt(discuz_uid)==0){
                                                                                        (function($){
                                                        var postHeight = getTextHeight(400);
                                                        $(".showpostmsg").html($(".showpostmsg").html());
                                                        $(".showpostmsg").after(loginstr);
                                                        $(".showpostmsg").css({height:postHeight,overflow:"hidden"});
                                                })(jQuery);
                                }
</script><script type="text/javascript">(function(d,c){var a=d.createElement("script"),m=d.getElementsByTagName("script"),eewurl="//counter.eeworld.com.cn/pv/count/";a.src=eewurl+c;m.parentNode.insertBefore(a,m)})(document,523)</script>

wstrom 发表于 2011-2-28 22:24

使用BC31工具编译UCOS-II的源码过程

使用BC31工具编译UCOS-II的源码过程见附件

wstrom 发表于 2011-2-28 22:17

BC31 安装过程

详细的安装过程见附件,里面有截图

[ 本帖最后由 wstrom 于 2011-2-28 22:25 编辑 ]

墨秋晓 发表于 2011-2-28 21:06

搬个小凳子 扎起。。。:shy:

wanghongyang 发表于 2011-2-27 16:45

可以考虑用PC机作为载体,这样可能会方便没有开发板的坛友。

soso 发表于 2011-2-27 17:18

回复 楼主 wstrom 的帖子

呵呵 不错的方式 支持一下 有兴趣的朋友可以和楼主一起来做做啊

wanghongyang 发表于 2011-2-27 18:28

回复 板凳 soso 的帖子

自行车买到了?:lol

academic 发表于 2011-2-27 18:34

回复 楼主 wstrom 的帖子

这么好的想法,一定要支持一下!

daicheng 发表于 2011-2-27 20:11

支持,也懂一点,可以一起讨论一下

wstrom 发表于 2011-2-27 21:00

听取坛友 wanghongyang 的建议,使用PC机作为学习平台,这样大家容易找到一个共同的学习平台。到移植章节的时候再结合一两种单片机来学习。

wstrom 发表于 2011-2-27 21:15

第一篇 UCOS介绍

<P>第一篇 UCOS介绍</P>
<P>&nbsp;</P>
<P>这个大家都知道。呵呵。考虑到咱们学习的完整性还是在这里唠叨一下。让大家再熟悉一下。高手们忍耐一下吧! uC/OS II(Micro Control Operation System Two)是一个可以基于ROM运行的、可裁减的、抢占式、实时多任务内核,具有高度可移植性,特别适合于微处理器和控制器,是和很多商业操作系统性能相当的实时操作系统(RTOS)。为了提供最好的移植性能,uC/OS II最大程度上使用ANSI C语言进行开发,并且已经移植到近40多种处理器体系上,涵盖了从8位到64位各种CPU(包括DSP)。   </P>
<P>uC/OS II可以简单的视为一个多任务调度器,在这个任务调度器之上完善并添加了和多任务操作系统相关的系统服务,如信号量、邮箱等。其主要特点有公开源代码,代码结构清晰、明了,注释详尽,组织有条理,可移植性好,可裁剪,可固化。内核属于抢占式,最多可以管理60个任务。 </P>
<P>μC/OS-II 的前身是μC/OS,最早出自于1992 年美国嵌入式系统专家Jean J.Labrosse 在《嵌入式系统编程》杂志的5 月和6 月刊上刊登的文章连载,并把μC/OS 的源码发布在该杂志的B B S 上。   </P>
<P>μC/OS 和μC/OS-II 是专门为计算机的嵌入式应用设计的, 绝大部分代码是用C语言编写的。CPU 硬件相关部分是用汇编语言编写的、总量约200行的汇编语言部分被压缩到最低限度,为的是便于移植到任何一种其它的CPU 上。用户只要有标准的ANSI 的C交叉编译器,有汇编器、连接器等软件工具,就可以将μC/OS-II嵌人到开发的产品中。μC/OS-II 具有执行效率高、占用空间小、实时性能优良和可扩展性强等特点, 最小内核可编译至 2KB 。μC/OS-II 已经移植到了几乎所有知名的CPU 上。   </P>
<P>严格地说uC/OS-II只是一个实时操作系统内核,它仅仅包含了任务调度,任务管理,时间管理,内存管理和任务间的通信和同步等基本功能。没有提供输入输出管理,文件系统,网络等额外的服务。但由于uC/OS-II良好的可扩展性和源码开放,这些非必须的功能完全可以由用户自己根据需要分别实现。 </P>
<P>uC/OS-II目标是实现一个基于优先级调度的抢占式的实时内核,并在这个内核之上提供最基本的系统服务,如信号量,邮箱,消息队列,内存管理,中断管理等。 </P>
<P>uC/OS-II以源代码的形式发布,但并不意味着它是开源软件。你可以将其用于教学和私下研究(peaceful research);但是如果你将其用于商业用途,那么你必须通过Micrium获得商用许可。</P>
<P>虽然uCOS-II在商业上使用时需要的得到授权并且费用也是一笔不小的数字,但是他的开源毕竟带领我们走入了内核的世界。在此我代表嵌入式工程师向Mr Jean J.Labrosse 致谢。</P>

[ 本帖最后由 wstrom 于 2011-2-27 22:06 编辑 ]

fengzhang2002 发表于 2011-2-27 21:49

支持一下

wstrom 发表于 2011-2-27 22:08

任务管理

<P>uC/OS-II 中最多可以支持64 个任务,分别对应优先级0~63,其中0 为最高优先级。63为最低级,系统保留了4个最高优先级的任务和4个最低优先级的任务,所有用户可以使用的任务数有56个。   </P>
<P>uC/OS-II提供了任务管理的各种函数调用,包括创建任务,删除任务,改变任务的优先级,任务挂起和恢复等。   </P>
<P>系统初始化时会自动产生两个任务:一个是空闲任务,它的优先级最低,该任务仅给一个整形变量做累加运算;另一个是系统任务,它的优先级为次低,该任务负责统计当前cpu的利用率。</P>
<P>在系统初始化完毕后启动任务时必须创建一份用户任务,也就是说必须有一个应用程序(用户任务,使用应用程序对于我们经常使用Windows用户容易接受一些。呵呵),否则系统会崩溃。当然还有一些其他的要求,咱们后续再说,下面简要概述一下任务管理相关的函数</P>
<P><FONT face="Times New Roman">1</FONT><FONT style="FONT-SIZE: 10.5pt"><FONT face="宋体 ">:建立任务</FONT></FONT><FONT style="FONT-SIZE: 10.5pt"><FONT face="Times New Roman ">OSTaskCreat()/OSTaskCreatExt()</FONT></FONT><BR><FONT face="宋体 "><FONT style="FONT-SIZE: 10.5pt">如果想让</FONT></FONT><FONT style="FONT-SIZE: 10.5pt"><FONT face="Times New Roman ">UCOS</FONT></FONT><FONT face="宋体 "><FONT style="FONT-SIZE: 10.5pt">管理用户的任务,必须先建立任务。可以通过将任务的地址和其他参数传递到以下两个函数之一来建立任务。当调用</FONT></FONT><FONT style="FONT-SIZE: 10.5pt"><FONT face="Times New Roman ">OSTaskCreat()</FONT></FONT><FONT face="宋体 "><FONT style="FONT-SIZE: 10.5pt">时,需要四个参数:</FONT></FONT><FONT style="FONT-SIZE: 10.5pt"></FONT><BR><FONT color=red><FONT style="FONT-SIZE: 10.5pt"><FONT face="Times New Roman ">OSTaskCreate(void(*task)(void*pd),void*pdata,OS_STK*ptos,INTU prio)</FONT></FONT></FONT><BR><FONT style="FONT-SIZE: 10.5pt"><FONT face="Times New Roman ">Task</FONT></FONT><FONT face="宋体 "><FONT style="FONT-SIZE: 10.5pt">:是指向任务代码的指针,</FONT></FONT><FONT style="FONT-SIZE: 10.5pt"><FONT face="Times New Roman ">pdata</FONT></FONT><FONT face="宋体 "><FONT style="FONT-SIZE: 10.5pt">:是任务开始执行是,传递给任务的参数的指针,</FONT></FONT><FONT style="FONT-SIZE: 10.5pt"><FONT face="Times New Roman ">ptos</FONT></FONT><FONT face="宋体 "><FONT style="FONT-SIZE: 10.5pt">:是分配给任务的堆栈的栈顶指针,</FONT></FONT><FONT style="FONT-SIZE: 10.5pt"><FONT face="Times New Roman ">prio</FONT></FONT><FONT face="宋体 "><FONT style="FONT-SIZE: 10.5pt">是分配给任务的优先级。</FONT></FONT><FONT style="FONT-SIZE: 10.5pt"></FONT><BR><FONT face="宋体 "><FONT style="FONT-SIZE: 10.5pt">也可以用</FONT></FONT><FONT style="FONT-SIZE: 10.5pt"><FONT face="Times New Roman ">OSTaskCreatExt()</FONT></FONT><FONT face="宋体 "><FONT style="FONT-SIZE: 10.5pt">,不过该函数需要</FONT></FONT><FONT style="FONT-SIZE: 10.5pt"><FONT face="Times New Roman ">9</FONT></FONT><FONT face="宋体 "><FONT style="FONT-SIZE: 10.5pt">个参数,前四个参数与</FONT></FONT><FONT style="FONT-SIZE: 10.5pt"><FONT face="Times New Roman ">OSTaskCreat()</FONT></FONT><FONT face="宋体 "><FONT style="FONT-SIZE: 10.5pt">一样,例如:</FONT></FONT><FONT style="FONT-SIZE: 10.5pt"></FONT><BR><FONT color=red><FONT style="FONT-SIZE: 10.5pt"><FONT face="Times New Roman ">INT8U OSTaskCreateExt(void(*task)(void *pd),void *pdata,OS_STK *ptos, INT8U prio, INT16U&nbsp; &nbsp;id, OS_STK&nbsp;&nbsp;*pbos, OS_STK&nbsp;&nbsp;*pbos, OS_STK&nbsp;&nbsp;*pbos, INT16U&nbsp;&nbsp;opt)</FONT></FONT></FONT><BR><FONT face="宋体 "><FONT style="FONT-SIZE: 10.5pt">id</FONT></FONT><FONT face="宋体 "><FONT style="FONT-SIZE: 10.5pt">参数为要建立的任务创建一个特殊的标识符。pbos是指向任务的堆栈栈底的指针,用于堆栈的检验。stk&nbsp;&nbsp;_size用于指定堆栈成员数目的容量。pext是指向用户附加的数据域的指针,用来扩展任务的OS_TCB。opt用于设定OSTaskCreateExt()的选项,指定是否允许堆栈检验,是否将堆栈清零,任务是否要进行浮点操作等等。</FONT></FONT><FONT style="FONT-SIZE: 10.5pt"></FONT><BR><FONT style="FONT-SIZE: 10.5pt"><FONT face="Times New Roman ">2</FONT></FONT><FONT face="宋体 "><FONT style="FONT-SIZE: 10.5pt">:任务堆栈</FONT></FONT><FONT style="FONT-SIZE: 10.5pt"><FONT face="Times New Roman ">OS_STK</FONT></FONT><FONT face="宋体 "><FONT style="FONT-SIZE: 10.5pt">()</FONT></FONT><FONT style="FONT-SIZE: 10.5pt"></FONT><BR><FONT face="宋体 "><FONT style="FONT-SIZE: 10.5pt">每个任务都有自己的堆栈,<FONT color=red>堆栈必须申明为</FONT></FONT></FONT><FONT color=red><FONT style="FONT-SIZE: 10.5pt"><FONT face="Times New Roman ">OS_STK</FONT></FONT></FONT><FONT color=red><FONT face="宋体 "><FONT style="FONT-SIZE: 10.5pt">类型,并且由连续的内存空间组成</FONT></FONT></FONT><FONT face="宋体 "><FONT style="FONT-SIZE: 10.5pt">。可以静态分配堆栈空间,也可以动态分配堆栈空间。</FONT></FONT><FONT style="FONT-SIZE: 10.5pt"></FONT><BR><FONT style="FONT-SIZE: 10.5pt"><FONT face="Times New Roman ">3</FONT></FONT><FONT face="宋体 "><FONT style="FONT-SIZE: 10.5pt">:堆栈检验</FONT></FONT><FONT style="FONT-SIZE: 10.5pt"><FONT face="Times New Roman ">OSTaskStkChk()</FONT></FONT><BR><FONT face="宋体 "><FONT style="FONT-SIZE: 10.5pt">有时确定任务实际需要的堆栈空间的大小是很有必要的,因为这样就可以避免为任务分配过多的堆栈空间,从而减少应用程序代码所需的</FONT></FONT><FONT style="FONT-SIZE: 10.5pt"><FONT face="Times New Roman ">RAM</FONT></FONT><FONT face="宋体 "><FONT style="FONT-SIZE: 10.5pt">空间。</FONT></FONT><FONT style="FONT-SIZE: 10.5pt"></FONT><BR><FONT style="FONT-SIZE: 10.5pt"><FONT face="Times New Roman ">4</FONT></FONT><FONT face="宋体 "><FONT style="FONT-SIZE: 10.5pt">:删除任务</FONT></FONT><FONT style="FONT-SIZE: 10.5pt"><FONT face="Times New Roman ">OSTaskDel()</FONT></FONT><BR><FONT face="宋体 "><FONT style="FONT-SIZE: 10.5pt">有时需要删除任务,删除任务,是说任务返回并处于休眠态,<FONT color=red>并不是说任务的代码被删除了,只是任务的代码不再被</FONT></FONT></FONT><FONT color=red><FONT style="FONT-SIZE: 10.5pt"><FONT face="Times New Roman ">UCOS</FONT></FONT></FONT><FONT color=red><FONT face="宋体 "><FONT style="FONT-SIZE: 10.5pt">调用。删除任务前应保证所删任务并非空闲任务。</FONT></FONT></FONT><FONT color=red><FONT style="FONT-SIZE: 10.5pt"></FONT></FONT><BR><FONT style="FONT-SIZE: 10.5pt"><FONT face="Times New Roman ">5</FONT></FONT><FONT face="宋体 "><FONT style="FONT-SIZE: 10.5pt">:请求删除任务</FONT></FONT><FONT style="FONT-SIZE: 10.5pt"><FONT face="Times New Roman ">OSTaskDelReq()</FONT></FONT><BR><FONT face="宋体 "><FONT style="FONT-SIZE: 10.5pt">有时,任务会占用一些内存缓冲或信号量一类的资源。这时,假如另一个任务试图删除该任务,这些被占用的资源就会因为没有被释放而丢失。在这种情况下,需想办法拥有这些资源的任务在使用完资源后先释放资源,再删除自己。</FONT></FONT><FONT style="FONT-SIZE: 10.5pt"></FONT><BR><FONT style="FONT-SIZE: 10.5pt"><FONT face="Times New Roman ">6</FONT></FONT><FONT face="宋体 "><FONT style="FONT-SIZE: 10.5pt">:改变任务的优先级</FONT></FONT><FONT style="FONT-SIZE: 10.5pt"><FONT face="Times New Roman ">OSTaskChangePrio()</FONT></FONT><BR><FONT face="宋体 "><FONT style="FONT-SIZE: 10.5pt">在建立任务时,会分配给任务一个优先级。在程序运行期间,可以通过调用该函数改变任务的优先级。也就是说,</FONT></FONT><FONT style="FONT-SIZE: 10.5pt"><FONT face="Times New Roman ">UCOS</FONT></FONT><FONT face="宋体 "><FONT style="FONT-SIZE: 10.5pt">允许动态的改变任务的优先级。</FONT></FONT><FONT style="FONT-SIZE: 10.5pt"></FONT><BR><FONT style="FONT-SIZE: 10.5pt"><FONT face="Times New Roman ">7</FONT></FONT><FONT face="宋体 "><FONT style="FONT-SIZE: 10.5pt">:挂起任务</FONT></FONT><FONT style="FONT-SIZE: 10.5pt"><FONT face="Times New Roman ">OSTaskSuspend()</FONT></FONT><BR><FONT face="宋体 "><FONT style="FONT-SIZE: 10.5pt">任务挂起是一个附加功能,也就是说,如果任务在被挂起的同时也在等待延迟时间到,那么,需要对任务做取消挂起的操作,并且等待延迟时间到,任务才能转让就绪状态。任务可以挂起自己或者其他任务。</FONT></FONT><FONT style="FONT-SIZE: 10.5pt"></FONT><BR><FONT style="FONT-SIZE: 10.5pt"><FONT face="Times New Roman ">8</FONT></FONT><FONT face="宋体 "><FONT style="FONT-SIZE: 10.5pt">:恢复任务</FONT></FONT><FONT style="FONT-SIZE: 10.5pt"><FONT face="Times New Roman ">OSTaskResume()</FONT></FONT><BR><FONT face="宋体 "><FONT style="FONT-SIZE: 10.5pt">挂起的任务只有通过该函数才能被恢复。</FONT></FONT><FONT style="FONT-SIZE: 10.5pt"></FONT><BR><FONT style="FONT-SIZE: 10.5pt"><FONT face="Times New Roman ">9</FONT></FONT><FONT face="宋体 "><FONT style="FONT-SIZE: 10.5pt">:获得任务的信息</FONT></FONT><FONT style="FONT-SIZE: 10.5pt"><FONT face="Times New Roman ">OSTaskQuery()</FONT></FONT><BR><FONT face="宋体 "><FONT style="FONT-SIZE: 10.5pt">通过调用该函数,来获得自身或其他应用任务的信息</FONT></FONT><FONT style="FONT-SIZE: 10.5pt"></FONT><BR></P>

[ 本帖最后由 wstrom 于 2011-2-27 22:19 编辑 ]

wstrom 发表于 2011-2-27 22:17

时间管理

uC/OS-II的时间管理是通过定时中断来实现的,该定时中断一般为10毫秒或100毫秒发生一次(这个时间片段是OS的作者推荐的,大家可以参考邵贝贝翻译的《嵌入式实时操作系统ucos-II》这本书),时间频率取决于用户对硬件系统的定时器编程来实现。中断发生的时间间隔是固定不变的,该中断也成为一个时钟节拍。这里隐含的意思就是你选择的芯片如果想使用UCOS系统,前提条件一定要有一个Timer。   
uC/OS-II要求用户在定时中断的服务程序中,调用系统提供的与时钟节拍相关的系统函数,例如中断级的任务切换函数,系统时间函数。
uCOS时间管理的相关函数
1:任务延迟函数OSTimeDly()
Ucos提供一个可以被任务调用而将任务延时一段特定时间的功能函数,即OSTimeDly().任务调用OSTimeDly()后,一旦规定的时间期满或者有其他的任务通过调用OSTimeDlyResume()取消了延时,他就会进入就绪状态。只有当该任务在所有就绪态任务中具有最高的优先级,它才会立即运行。
2:按时,分,秒延时函数OSRimeDLyHMSM()
与OSTimeDly()一样,调用OSRimeDlyHMSM()函数也会是UCOS进行一次任务调度,并且执行下一个优先级最高的就绪任务。当OSTimeDlyHMSM()后,一旦规定的时间期满,或者有OSTimeDlyResume(),它就会马上处于就绪态。同样,只有当该任务在所有就绪态任务中具有最高的优先级,他才开始运行。
3:恢复延时的任务OSTimeDlyResume()
延时的任务可以不等待延时的期满,而是通过其他任务取消延时而使自己处于就绪态,可以通过该函数来实现,实际上,OSTimeDlyResume()也可以唤醒正在等待的事件。
4:系统时间OSTimeGet()和OSTimeSet()

wstrom 发表于 2011-2-27 22:28

内存管理

<P>在ANSI C中是使用malloc和free两个函数来动态分配和释放内存。例如在Linux系统中就是这样。但在嵌入式实时系统中,多次这样的操作会导致内存碎片,因为嵌入式系统尤其是uCOS是实地址模式,这种模式在分配任务堆栈时需要整块连续的空间,否则任务无法正确运行。且由于内存管理算法的原因,malloc和free的执行时间也是不确定。这点是实时内核最大的矛盾。</P>
<P>基于以上的原因uC/OS-II中把连续的大块内存按分区管理。每个分区中包含整数个大小相同的内存块,但不同分区之间的内存快大小可以不同。用户需要动态分配内存时,系统选择一个适当的分区,按块来分配内存。释放内存时将该块放回它以前所属的分区,这样能有效解决碎片问题,同时执行时间也是固定的。</P>
<P>同时uCOS-II根据以上的处理封装了适合于自己的动态内存分配函数OSMemGet()和OSMemPut(),但是使用这两个函数动态分配内存前需要先创建内存空间,也就是第二段咱们介绍的内存分块。呵呵,不罗嗦了,具体的关于内存管理的函数如下:</P>
<P><FONT face=宋体>内存控制块的数据结构<FONT style="FONT-SIZE: 10.5pt"></FONT><BR></FONT><FONT style="FONT-SIZE: 10.5pt"><FONT face="Times New Roman ">Typedef<BR>struct</FONT></FONT><BR><FONT style="FONT-SIZE: 10.5pt"><FONT face="Times New Roman ">{void&nbsp; &nbsp;*osmemaddr&nbsp; &nbsp; ;</FONT></FONT><FONT face="宋体 "><FONT style="FONT-SIZE: 10.5pt">指向内存分区起始地址的指针。</FONT></FONT><FONT style="FONT-SIZE: 10.5pt"></FONT><BR><FONT style="FONT-SIZE: 10.5pt"><FONT face="Times New Roman ">Void&nbsp; &nbsp;*osmemfreelist&nbsp;&nbsp;;</FONT></FONT><FONT face="宋体 "><FONT style="FONT-SIZE: 10.5pt">指向下一个空余内存控制块或者下一个空余内存块的指针,</FONT></FONT><FONT style="FONT-SIZE: 10.5pt"><FONT face="Times New Roman "><BR>Int32u&nbsp;&nbsp;osmemblksize&nbsp;&nbsp;;</FONT></FONT><FONT face="宋体 "><FONT style="FONT-SIZE: 10.5pt">内存分区中内存块的大小,是建立内存分区时定义的。</FONT></FONT><FONT style="FONT-SIZE: 10.5pt"><FONT face="Times New Roman "><BR>Int32u osmemnblks&nbsp; &nbsp;&nbsp;&nbsp;;</FONT></FONT><FONT face="宋体 "><FONT style="FONT-SIZE: 10.5pt">内存分区中总的内存块数量,也是建立该内存分区时定义的。</FONT></FONT><FONT style="FONT-SIZE: 10.5pt"><FONT face="Times New Roman "><BR>Int32u&nbsp;&nbsp;osmemnfree&nbsp; &nbsp; ;</FONT></FONT><FONT face="宋体 "><FONT style="FONT-SIZE: 10.5pt">内存分区块中当前获得的空余块数量。</FONT></FONT><FONT style="FONT-SIZE: 10.5pt"></FONT><BR><FONT style="FONT-SIZE: 10.5pt"><FONT face="Times New Roman ">}os_mem;</FONT></FONT><BR><FONT style="FONT-SIZE: 10.5pt"><FONT face="Times New Roman ">1</FONT></FONT><FONT face="宋体 "><FONT style="FONT-SIZE: 10.5pt">;建立一个内存分区,</FONT></FONT><FONT style="FONT-SIZE: 10.5pt"><FONT face="Times New Roman ">OSMemCreate()</FONT></FONT><BR><FONT style="FONT-SIZE: 10.5pt"><FONT face="Times New Roman ">2</FONT></FONT><FONT face="宋体 "><FONT style="FONT-SIZE: 10.5pt">:分配一个内存块,</FONT></FONT><FONT style="FONT-SIZE: 10.5pt"><FONT face="Times New Roman ">OSMemGet()</FONT></FONT><BR><FONT face="宋体 "><FONT style="FONT-SIZE: 10.5pt">应用程序通过调用该函数,从已经建立的内存分区中申请一个内存块。该函数唯一的参数是指向特定内存分区的指针。</FONT></FONT><FONT style="FONT-SIZE: 10.5pt"></FONT><BR><FONT style="FONT-SIZE: 10.5pt"><FONT face="Times New Roman ">3</FONT></FONT><FONT face="宋体 "><FONT style="FONT-SIZE: 10.5pt">:释放一个内存块,</FONT></FONT><FONT style="FONT-SIZE: 10.5pt"><FONT face="Times New Roman ">OSMemPut()</FONT></FONT><BR><FONT face="宋体 "><FONT style="FONT-SIZE: 10.5pt">当应用程序不再使用一个内存块时,必须及时的把它释放,并放回到相应的内存分区中,这个操作就是通过调用该函数实现的。</FONT></FONT><FONT style="FONT-SIZE: 10.5pt"></FONT><BR><FONT style="FONT-SIZE: 10.5pt"><FONT face="Times New Roman ">4</FONT></FONT><FONT face="宋体 "><FONT style="FONT-SIZE: 10.5pt">:查询一个内存分区的状态,</FONT></FONT><FONT style="FONT-SIZE: 10.5pt"><FONT face="Times New Roman ">OSQMemQuery()</FONT></FONT><FONT face="宋体 "><FONT style="FONT-SIZE: 10.5pt">。</FONT></FONT><FONT style="FONT-SIZE: 10.5pt"></FONT><BR></P>

[ 本帖最后由 wstrom 于 2011-2-27 22:32 编辑 ]

hui370 发表于 2011-2-28 16:18

跟帖学习 哈哈:)

wstrom 发表于 2011-2-28 17:30

任务间通信与同步

对一个多任务的操作系统来说,任务间的通信和同步是必不可少的。uC/OS-II中提供了4种同步对象,分别是信号量,邮箱,消息队列和事件。所有这些同步对象都有创建,等待,发送,查询的接口用于实现进程间的通信和同步。
对于这4种同步对象将在后面一一讨论。

wstrom 发表于 2011-2-28 17:33

任务调度

uC/OS-II 采用的是可剥夺型实时多任务内核。可剥夺型的实时内核在任何时候都运行就绪了的最高优先级的任务。
uC/os-II的任务调度是完全基于任务优先级的抢占式调度,也就是最高优先级的任务一旦处于就绪状态,则立即抢占正在运行的低优先级任务的处理器资源。为了简化系统设计,uC/OS-II规定所有任务的优先级不同,因为任务的优先级也同时唯一标志了该任务本身。
UCOS的任务调度在一下情况下发生:
1) 高优先级的任务因为需要某种临界资源,主动请求挂起,让出处理器,此时将调度就绪状态的低优先级任务获得执行,这种调度也称为任务级的上下文切换。
2) 高优先级的任务因为时钟节拍到来,在时钟中断的处理程序中,内核发现高优先级任务获得了执行条件(如休眠的时钟到时),则在中断态直接切换到高优先级任务执行。这种调度也称为中断级的上下文切换。
这两种调度方式在uC/OS-II的执行过程中非常普遍,一般来说前者发生在系统服务中,后者发生在时钟中断的服务程序中。
调度工作的内容可以分为两部分:最高优先级任务的寻找和任务切换。其最高优先级任务的寻找是通过建立就绪任务表来实现的。u C / O S 中的每一个任务都有独立的堆栈空间,并有一个称为任务控制块TCB(Task Control Block)的数据结构,其中第一个成员变量就是保存的任务堆栈指针。任务调度模块首先用变量OSTCBHighRdy 记录当前最高级就绪任务的TCB 地址,然后调用OS_TASK_SW()函数来进行任务切换。

wstrom 发表于 2011-2-28 17:37

第二章 搭建UCOS-II 2.52版的调试平台

<P>在这一章中我们主要讨论UCOSII的源码调试环境,为了给大家一个共同的学习平台,我搜集整理了一写资料,就是以X86为平台,使用BC31(这个堪称骨灰级的编译器)来调试UCOSII源码。当然你也可以用BC45或更高版本的编译器,具体方法大同小异,我在此就不再啰嗦。</P>
<P>本章节的主要内容包括四点:</P>
<P>1、下载并安装BC31编译器 </P>
<P>2、下载并安装UCOS-II2.52版本源代码 </P>
<P>3、使用BC31编译UCOS-II源码</P>
<P>4、让OS的第一个任务RUN起来</P>
<P>接下来会在每个帖子中讨论一点。耐心等待哦!</P>

[ 本帖最后由 wstrom 于 2011-2-28 17:51 编辑 ]

wstrom 发表于 2011-2-28 17:55

下载并安装BC31编译器

<P>我在这里提供给大家这个骨灰级的编译器BC31.需要的可以下载。见附件(骨灰级编译器BC31)由于这个软件的比较大,分成两个压缩包。下班了,先到这里,回家再传附件! </P>
<P>上传了好几次都没有上传成功。可能是我的网速太慢。如果有需要的坛友把邮箱留给我吧,我发邮箱去!</P>

[ 本帖最后由 wstrom 于 2011-2-28 22:12 编辑 ]

academic 发表于 2011-2-28 17:58

回复 17楼 wstrom 的帖子

在PC上可以学ucos,可是还是没有在单片机上实战地好啊。

450678797 发表于 2011-2-28 19:15

谢谢楼主不吝赐教,学习之
页: [1] 2 3 4 5 6 7 8 9 10
查看完整版本: 一步一步教你使用uCOS-II