在线咨询
eetop公众号 创芯大讲堂 创芯人才网
切换到宽版

EETOP 创芯网论坛 (原名:电子顶级开发网)

手机号码,快捷登录

手机号码,快捷登录

找回密码

  登录   注册  

快捷导航
搜帖子
芯片精品文章合集(500篇!) 创芯人才网--重磅上线啦!
查看: 3212|回复: 3

[转帖]从UCOS到多任务实现--初学者的一些认识

[复制链接]
发表于 2005-11-2 14:43:21 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?注册

x
[转帖]从UCOS到多任务实现--初学者的一些认识

前段时间学了学UCOS,有了点感想,想说说,它也许对DX来说是垃圾,但对有些人或许还有那么一丁点作用,如果其中有不妥之处,请各位指出来,
所谓的多任务有下面几个实现方式:
方案:
1.
时间片轮回,每个任务分一个时间片,调度时到达该任务的时间片即开始运行该任务,达到并行的目的,这种方案缺点是任务响应的实时性与时间片的大小关系很大,时间片大,任务多时,一些任务可能会得不到及时的响应.但实现容易.
2.
任务间使用信号量或者消息队列或者消息等机制通讯的发式,这种发式建立了任务间的通讯机制,一但有任务满足了执行条件,立刻开使执行,实时性较好.
3.
任务间中断的方式,一旦有中断进行,即刻进入一个任务,实时性较高.
实现:
1.任务的运行:每个任务即是一个死循环,该任务一直运行直到有其他任务到达运行时间或满足运行条件.
2.任务的切换:其他任务到达运行时间或满足了运行条件,就需要切换到其它任务中,称作任务切换.相反,在其它任务运行中,如果又有任务满足执行条件,即刻任务切换.
3.任务切换的实现:
在此我们先假定任务间没有通讯,没有时间片的轮回,没有中断,一个任务仅仅是我们普通的一个死循环的函数.
类似于这样的函数任务A:VOID TASK(VOID* P){FOR(;;){...}}
任务B:VOID TASK(VOID* P){FOR(;;){...}}
在这个假定下,我们设想有两个任务A,B.当前正在A中,由于A为死循环,正如我们想象的,它将无止境的运行下去,看来这样任务B是没指望得到机会运行了,怎么办呢,让我们一部一部将任务机制建立起来吧:
A)让任务B得到运行:我们想到一个软中断可以使一段程序得到运行,我们试试它吧,以INTEL80X86CPU为例,一条INT N指令即可以将CPU的控制权交给中断象量在4*N地址的程序段,现在我们要做的就是将任务B程序起始地址放在4*N处,然后在任务A中假如INT N指令,
现在任务A变成了这样VOID TASK(VOID* P){FOR(;;){...;INT N}}
任务B仍然为: VOID TASK(VOID* P){FOR(;;){...}}
B)让任务A得到运行:现在就实现了我们的目的,任务A可以切换到任务B了,我们终于迈出了一步,编译,连接,运行我们惊奇的发现当任务A运行到INT N时,果然开始了任务B的运行,这样就实现了A到B的切换,可是随之而来我们发现任务B原来还是一个死循环,它无止境的运行以至于任务A被"饿死了",仔细一看原来是我们忘了也给任务B一个INT N了,好,仿照任务A,我们做类似的处理,这样他们就变成了下面这样:
现在任务A变成了这样VOID TASK(VOID* P){FOR(;;){...;INT N}}
任务B仍然为: VOID TASK(VOID* P){FOR(;;){...;INT M}}
编译,联结,运行,看看运行情况,这个时候两个任务果然每次到切换点INT X时开使互相切换,
到这时,我们已经实现了最简单的多任务,但是这种方法大家已经看到,每个任务有一个中断号,即N!=M,似乎不是很好,那么下面我们让它们相等,即试着用一个中断号实现多任务的切换.
C)任务内容的保存:我们可以想象的到,要使用同一个中断号,那么任务切换前必须预先将要切换到的任务的执行地址装入4*N处(以使用中断号N为例),怎么实现呢,当然有很多方法,其中比较好的一个方法就是每个任务对应一个存储区(任务STACK),该任务的起始地址都有保存于其中(这种方案当然不是仅仅为了保存任务地址而设),任务切换前,先访问该任务的任务STACK,取出该任务执行地址装入4*N处,然后执行任务切换,这样就达到了使用一个中断号的效果.
现在任务A变成了这样VOID TASK(VOID* P){FOR(;;){...;安装N;INT N}}
任务B仍然为: VOID TASK(VOID* P){FOR(;;){...;安装N;INT N}}
至此,我们已经构筑了多任务实现的一个机制,
现在,我们回到前面提到的三个多任务实现的方案:
1.时间片的实现:其实就照上面的方法已经是最简单的时间片实现了,较复杂的实现要结合任务通讯机制来实现.
2.所谓的信号量(semaphore)其实就是一个标志位FLAG,消息(MESSAGE)机制其实就是一个指针,消息队列(MESSAGE QUEUE是多个消息组成的一个队列机制,拿最简单的信号量来说,最简单的通讯机制你可以这样:
现在任务A变成了这样VOID TASK(VOID* P){FOR(;;){IF(CONDITION )SET FLAG;...;IF(FLAG){安装N;INT N}}}
任务B仍然为: VOID TASK(VOID* P){FOR(;;){...IF(CONDITION) SET FLAG;...;IF(FLAG){安装N;INT N}}
不过,真正的任务通讯没有这样做的,基于任务切换,你可以设计你自己的任务通讯方式,你可以想出各种方法来实现这种通讯,关于任务间通讯的学问很大,基本上多任务实现的核心知识可能就是这个了.

3.任务间中断的方式,就是任务中产生中段,标志某个事件发生或条件满足,然后满足该条件的任务得到执行.值得注意的是中断代码应该尽量短小精悍,占时少.
最基本的多任务就是这样的!
最后我再结合我自己说说如何学习UCOS.其实呢,只要你理解了我上面说的多任务切换的基本原理,然后再拿一个简单的实际例子,比如UCOS作者本人的著作“µC/OS, The Real-Time Kernel”中给出的例子中的一个,展开所有的调用函数,从头到尾,细细研读,再加上做者本人的讲解,理解应该不难.其中我要强调的是初始化函数OSInit(),把它展开,勾画出所有的数据结构,你就对UCOS所用的数据结构成竹在胸,在后面其它的阅读中追踪这些数据结构,你会发现其实UCOS很简单.一旦读懂一个例子,不论它使用哪个任务通讯机制,或是DELAY(),基本上大体框架你已经没问题了,后面再看其他例子,用到哪个通讯机制(其实也就三个semaphore,MESSAGE,QUEUE)查哪个,基本上做的事情大同小异.
 楼主| 发表于 2005-11-2 14:54:48 | 显示全部楼层

[转帖]从UCOS到多任务实现--初学者的一些认识

自己先顶...
发表于 2007-6-20 21:09:22 | 显示全部楼层


多点老手的见解
自己也轻松一点
发表于 2007-10-6 13:13:06 | 显示全部楼层
不错!!!
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

站长推荐 上一条 /2 下一条


小黑屋| 手机版| 关于我们| 联系我们| 在线咨询| 隐私声明| EETOP 创芯网
( 京ICP备:10050787号 京公网安备:11010502037710 )

GMT+8, 2024-12-24 07:48 , Processed in 0.021868 second(s), 9 queries , Gzip On, Redis On.

eetop公众号 创芯大讲堂 创芯人才网
快速回复 返回顶部 返回列表