uocs-ii和单片机结合的心得体会

上传人:平*** 文档编号:12801551 上传时间:2017-10-20 格式:DOC 页数:4 大小:40KB
返回 下载 相关 举报
uocs-ii和单片机结合的心得体会_第1页
第1页 / 共4页
uocs-ii和单片机结合的心得体会_第2页
第2页 / 共4页
uocs-ii和单片机结合的心得体会_第3页
第3页 / 共4页
uocs-ii和单片机结合的心得体会_第4页
第4页 / 共4页
亲,该文档总共4页,全部预览完了,如果喜欢就下载吧!
资源描述

《uocs-ii和单片机结合的心得体会》由会员分享,可在线阅读,更多相关《uocs-ii和单片机结合的心得体会(4页珍藏版)》请在金锄头文库上搜索。

1、从寒假开始接触操作系统到今天初步完成一个基于 STC89C52 单片机,使用 UC/OS-II微内核的时钟应用程序也有一段时间了.在这不长不短的一段时间里,可以说我每天都有新的发现.知识就是这样一点一点的积累起来的.我相信只要这样继续下去,我的水平一定能上一个层次.在没有看这本书之前,通过一些平时模糊的了解,就只能把进程这样的一些概念理解为许多个不同的应用程序在处理器上通过某种方流地切换来实现处理器资源的使用率的最大化.还有更多的其他一些概念甚至是连听都没有听说过的.由于基础比较差,加上寒假在家里较封闭.少有信息获取渠道,所以在看这本书的时候比较吃力.可以说那一段时间看书真是一种煎熬.不过后来

2、提前来了学校,情况就好多了.之前看书时有许多不懂的概念,在学校里可以通过上网查找资料了.最开始看到进程的时候,感觉进程就是跟之前理解的差不多嘛,但是当看到线程这里的时候一下子又蒙了.这个时候就把进程跟线程给弄混淆了,但是没办法,在家里条件艰苦,只好这样子带着混淆看下去啦.到了学校连了网立刻就在找到了一篇文章.它那里面举一个马车的例子来比喻进程与线程的关系.在后面的篇幅也很清晰的把进程和线程的各种关系说出来了.于是我就这样子理解:其实系统就是把一大堆资源分配给进程,由进程来管理它所获得的资源,它爱怎么用就怎么用.而线程又是进程里面的一小个环节.线程可以使用进程获得的资源来完成自己的事情.如果说进

3、程要完成一个大的事情,那么它就必须把这样一个大的事情分成一个个小的事情.那么进程就是这些小的事情和必要的资源的集合,而线程就是完成这样一个个小的事情的实体.举个例子来说,比如一个人现在要做一道菜.如果我们把做一道菜看做是一个进程的话,那么我们先要找到这个会做菜的人.这个人就相当于我们的处理器.然后还必须要有煤气炉,锅.铲子.刀,一些调料之类等等一些工具,那这些就是我们必要的一些资源.我们的进程先要申请得到这些资源.首先我们要把做一道菜这个大任务分成一个个小的任务.这些任务包括有比如说切菜啦,煮水啦,炒菜啦,加调料啦,控制火候啦,还有等待啦.等等.而这些就可以看成是一个个线程了.那么当我们决定要

4、做一道菜的时候可以看成是创建了一个进程了.接下来这个人开始做的时候就看做是进程开始运行了.首先这个人会开始切菜那这是第一个线程开始得到运行.就是在处理器上运行.切了一会的时候.他突然发现可以先煮一下水.那么他就会先放正在切着的菜转去煮水.这就是线程的切换啦.然后当把水放到锅里面去了就让它煮着吧,人不用去管它了.那这时处理器就可以空出来做其它的事情了.他可以返回去继续切菜,也可以转而去做其他事.我们假设他返回去继续切菜好了.当他切完之后就开始就开始炒菜了,而在炒菜的过程中他偶尔也可以做些其他事.如加调料啦.控制火候啦.等等.这样的一些工作可以是并发的.注意是并发不是同时.到最后必须要让这菜在锅里

5、煮一下时.这时人也就是处理器就空闲下来了.他可以去做其他的事.那就相当于进程的切换了.只须要在菜煮熟的时候把它铲起来就行了.这样一个进程就算运行完毕了.当然我只是打了一个很粗略的比喻.并不能概括进程跟线程的全部关系.在后来当我看完了 UC/OS-II 的任务部分之后.虽然说 UC/OS-II 把进程和线程的概念模糊掉了,只有一个任务的概念.但是我还是不禁会把它跟进程跟线程联系起来.那这样的话我就认为 UC/OS-II 下只有一个应用程序.而把这个应用程序看作是一个进程.而把其中的每一个任务看做是一个个线程.不知道这样子理解对不对.好啦.进程跟线程好像纠结了好久的样子.其实在家里已经把这本书要看

6、的章节都大概的看过一遍了虽然有看到进程的同步与通信那里有什么信号量啊,消息邮箱啊,还有消息队列之类,但是根本就不知道它们是什么东西.还有邵贝贝的 UC/OS-II 也看了一部分.只是由于第一次看看得相当纠心.只当是看天书了.所以到学校后.就拼命的找资料.看了一些操作系统比较基础的概念还有 UC/OS-II 的一些比较基础的东西之后.觉得操作系统那本书有必要再看一遍.但是后来第二遍还是没有看完,但是第二次看毕竟有不同看起来也比较没那么辛苦了.因为又发现了另一本更容易懂的讲 UC/OS-II 的书,就是任哲那本书.接下来的几天就一直看这本书了.他讲的还是比较浅显的.看完了他这本书之后呢又找时间看了

7、一下 UC/OS-II 的源代码.感觉还是比较好懂的.这时候基本上对多任务的概念啊.任务之间的同步与通信啊及其具体的实现都有了初步的理解.接下来就讲一下我对 UC/OS-II 的理解吧.看过这样一篇文章说的是 UC/OS-II 的两个核心算法.该文章道出了 UC/OS-II 微内核的设计哲学:以空间换时间,因为 UC/OS-II 是一个嵌入式操作系统的内核.而大部分嵌入式讲究实时性.那要讲究实时性就必须知道任务切换的确定时间,而不应该因为任务数量而影响这个时间.因此 UC/OS-II 就是通过牺牲存储空间来保障其实时性的.两大核心算法其中一个是说基于优先级的任务调度的. Jean J. Lab

8、rosse 也就是 UC/OS-II 的作者使用一个数组 OSRdyTbl来记录具有某一优先级的任务的就绪情况,称为就绪表.并用另一个变量 OSRdyGrp 以方便查询某一任务的就绪情况.另外再加两张表得出查询结果.这样查询某一任务的就绪情况的时间就变成了一个可以预测的值了.现在看起来, UC/OS-II 本身内容并不多.也就是一个基于优先级的任务调度,一个任务切换,一个任务管理,一个时间管理,还有几个任务同步与通信的事件控制.如信号量.消息邮箱,消息队列.标志组,等等.先说基于优先级的任务调度吧,基于优先级就是近似保证在每一个时间段内都是优先级最高的任务处于运行状态.至于什么情况下才会需要任

9、务调度呢.那就有很多种情况了,比如说正在运行的任务由于某种需要,自行挂起自身或者调用时间延时一段时间.在这种情况下就会产生任务调度.又比如说某任务释放一定的信号量或者其他的什么任务之间的同步与通信的事件,从而使具有更高优先级的任务处于就绪状态,这时也会产生任务调度.总之,一个任务有运行,就绪,等待,挂起,中断等等各状态,通过各种调度使得任务在这些状态之间来回变换.再说任务切换吧.任务切换其实就通过修改 sp 指针和任务堆栈来起来保存当前任务断点而转去运行另一个任务.这个在后面说到 UC/OS-II 的移植的时候再具体的讲吧.再来谈谈任务管理.任务管理需要一个叫做 tcb 的任务控制块.tcb

10、里面保存有本任务所必要的一些基本信息.处理器根据这些信息来得到对应的任务.至于其他的一些比如任务的建立啊.任务的删除啊,任务的初始化啊等等的一些具体实现在这就不多说了.还有就是时间管理了,系统维护一个全局时钟,应用程序可以对这个全局时钟进行读写操作.同时任务控制块里有一个变量记录本任务需要等待延时的时间片数,通过时间中断逐一减少,等减到为零时,该任务重新返回到就绪状态. UC/OS-II 的时间管理比较简单.至于任务之间的同步与通信,信号量,消息邮箱,消息队列都要使用到一个叫做 ecb 的事件控制块.里面主要有一个信号计数变量,一个消息指针.还有一个类似于就绪表的任务等待队列表.当一个任务申请

11、得到一个信号或消息时,在有信号或消息的情况下,会立即给这个任务信号或消息,但是当没有信号或消息时,就会把任务送进任务等待队列,并挂起任务.直到有信号或消息或者等待超时.这里有衍生出来一个新的问题.就是如果在等待队列中有多个任务在等待.而信号只有一个,那么谁该得到信号并运行呢? UC/OS-II 有两个解决方法,要么只给优先级最高的那个任务,要么通知所有等待的任务有信号了,至于该谁运行,那就要看谁的优先级最高了.好啦. UC/OS-II 的基本部分都讲了,下面讲一下关于 UC/OS-II 在具体处理器上的移植吧.一般情况下的移植就是要把一些与处理器相关的内容做具体修改咯.那哪些是与处理器相关的内

12、容呢?比如说 C 语言中的各种数据类型在本处理器上具体是多少个字节啊,一些硬件的接口啊.具体的任务切换啊,任务的堆栈分配啊.等等.所以我们就要根据具体的处理器做出相应的修改了.比较难的地方可能就是任务切换的设计吧.当然在开始任务切换之前我们必须先约定一下堆栈的协议.就是必须按照一定的出栈入栈的规则来操作堆栈,否则将不能正确的返回到断点继续执行.所以就要先写一个堆栈初始化的函数,先规定每一个断点信息在堆栈的位置.任务的切换前面提到了一点,就是通过修改 sp 指针和任务堆栈来起来保存当前任务断点而转去运行另一个任务.为了有更好的实时性,这些一般都是用汇编语言写的.我们可以想象,要进行任务切换,那首

13、先你要先把当前的任务的断点信息给保存起来.否则将来要重新运行这个任务的时候怎样继续执行,难道要重新开始运行?当然不可能!所以要保存断点,那断点是保存在哪呢,当然就是刚才讲的任务堆栈啦.所以我们要做的事情就是先把断点保存在任务堆栈里,然后才能去取出另一个任务的断点,再从它的断点开始继续运行.说到断点,断点具体包括一些什么东西呢.比如说有 pc 指针啦.有 cpu 寄存器啦.psw 啦.sp指针啦.这些都是断点的一部分.可是 pc 指针也就是程序断点地址我们是不能够直接操作的,即我们不能对它进行读写,那该怎么办呢.通常有两种方式可以引发 pc 指针自动入栈.那就是函数调用或者是中断出现.其中中断出

14、现是随机的,不是我们能够控制的.但是函数调用我们是可以用的.所以我们一般是通过函数调用来模拟一次中断的出现.这样就可以做到 pc 指针自动入栈了.在硬件支持的情况下,我们可以直接把 sp 指针指到要运行的任务的任务堆栈的入口上去来导出断点.但是有些处理器可能硬件不支持.比如说 51 单片机,它的 sp 指针只有八位,而任务堆栈又一般是放在外部存储器上的,它的寻址需要两个字节.那 sp 指针就到不了任务堆栈而不能直接操作任务堆栈了.在这种情况下,我们只好在内部 ram 里开辟一个系统堆栈.对这个系统堆栈操作,然后通过复制的方法把它送到任务堆栈里.当然这又要花费一定的 cpu 时间了.所以从整一个

15、切换的过程来看的话,那就是先使用入栈指令 push 按照先前规定好的入栈规则把断点信息保存在系统堆栈里.然后再把这个断点信息复制到任务堆栈里.接着从要运行的任务的任务堆栈里把断点信息复制到系统堆栈里去再使用出栈指令 pop 弹出到处理器的相应位置.说了那么多,还没有说明白到底怎样找到这个任务堆栈呢.原来在我们的任务控制块 tcb 里有一个指针变量专门用来指向它的任务堆栈的.那只要沿着 tcb 地址就能找到任务堆栈的地址了.对了,移植时还有一个地方可以用汇编语言写的.就是 UC/OS-II的时间中断函数. UC/OS-II 自身有一个时钟,这个时钟就是通过时间中断函数来确保的.中断的频率不同那时

16、钟在每一秒钟内的节拍就不同.当我把 UC/OS-II 移植到 51 单片机的时候基本上就是按照上面的思路进行的.但是由于 51 单片机的特殊性,有些地方还是要注意的.比如说. UC/OS-II 里面会用 pdata,data 等来做函数的形参.可是由于这些都是 keil 里面的关键字.如果不改的话就会报错.编译不通过.那么就必须把它们全部都改成其他的以防止编译器报错.还有一点就是由 keil 编译器编译通过的程序是不可重入的.但是我们要求 UC/OS-II 里的大部分函数具有可重入性.这样我们就必须在每个函数后面加一个 reentrant 关键字.还有我考虑到由于我们把任务堆栈放到了外部 ram 里了.那为了让可使用的任务数最大化,最好仅有的 256 个字节的外 ram 全部用于任务堆栈.那就必须把其他的东西搬到内部 ram 去了.其中任务控制块在外部 ram 占了很大一个空间.故后来我就在任务控制块的定义那里加了一个 idata 使其只能存放于内部 ram,再修改了任务切换函数让它只在内部 ram 寻找任务控制块的地址.这样就能保证外部 r

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 行业资料 > 其它行业文档

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号