免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 8669 | 回复: 15
打印 上一主题 下一主题

linux任务响应模型&linux实时化&RTAI 3.2分析&Adeos分析 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2006-07-18 02:24 |只看该作者 |正序浏览
下面是以前做过的关于linux(基于2.4的)实时化方面的一些学习心得,希望对大家有所帮助,同时也强烈的希望大家共同补充、修正。

从Linux本身所固有的实时性方面的缺陷可以看出,Linux实时化的最终目标是要满足实时任务快速的响应时间的要求。一个实时任务的一次运行(实时任务一般都是周期性的)是由外部中断触发的,当中断产生的时候,CPU接收到中断信号,如果CPU当前允许中断(如果不允许,则直到允许中断后才处理中断),保存当前运行的任务跳转到中断服务程序,执行中断服务程序(在中断服务程序中唤醒实时任务),然后执行中断返回,如果当前系统允许进行进程调度,则调度实时任务开始运行(假定这个实时任务的优先级最高)。为了更好的理解Linux实时化的基本原理,我们有必要对Linux的任务响应模型作详细的分析,如附件中图像所示,给出了一个简化的Linux任务响应模型。



如图所示任务响应模型中,任务2(可以看成Linux内的软实时任务)的优先级高于任务1。t0时刻任务1在运行,而任务2处于睡眠状态,等待中断唤醒;t1时刻任务1请求系统服务完成某些操作(例如通过read()文件接口读取磁盘上的文件等),此时开始,系统在内核态运行;在t2时刻,产生一个中断(在这个中断的中断服务程序中唤醒任务2),但可能由于系统在内核态进行某些操作不希望被中断, CPU的处理中断被禁止,那么这个中断信号没有立刻得到响应,而是继续在内核态执行系统服务;在t3时刻,内核态代码使能中断响应(Linux内核退出临界区),这个时候CPU开始响应在t2时刻产生的中断,并从t4时刻开始执行中断服务程序;当中断服务程序执行完之后(在这个中断服务程序中唤醒了任务2),返回被中断的代码,由于此时系统运行在内核态(执行任务1的系统服务请求),任务2无法抢占任务1的控制权,所以执行任务1的系统服务请求;在t7时刻,由于任务1的系统调用完成返回或者在执行系统服务的过程中主动请求任务调度,系统开始进行任务调度,并在时刻t8运行任务2(假定此时任务2是系统内最高优先级的任务)。
其中,从时刻t2至时刻t8这个时间段,就是我们所说的任务响应延迟时间(Task Response Time);从图可以看出,任务的响应延迟时间可以分为以下几个部分:
1)中断潜伏期(Interrupt Latency)或者说中断延迟,这个指从中断产生到CPU开始响应中断的时间段,也就是图中从t2至t3的时间段。中断潜伏期是由于内核在进入临界区前关闭CPU的中断响应所引起的,在这个时间段内,虽然外部设备使CPU的中断请求线有效,但CPU并不立刻响应中断,而是继续执行临界区的内核代码,直至退出临界区、使能中断请求,才开始进行中断的响应。当然,还需要注意的一点是,中断潜伏期实际上包含了硬件所产生的中断延迟时间,我们一般所研究的是如何最大限度的减少软件所造成的延迟时间,所以,如果没有特别说明,我们是不考虑硬件所产生的延迟(但实际上,在工程应用中,当经过软件的优化还不能满足系统实时性的要求时,唯一的办法就只有提高硬件的处理速度了)。
2)中断分发阶段(中断准备阶段),这个指从CPU开始响应中断请求到开始执行中断服务程序之间的时间段,也就是图中从t3至t4的时间段。这个期间系统要做的主要操作包括查找中断号、保存寄存器、定位中断服务程序等。这个时间段的长度对于具体的平台来说,一般是确定性的,也就是说时间长度是固定的。另外,从中断产生到开始执行中断服务程序之间的时间段被称为中断响应延迟时间(Interrupt Response Time),对应于图中t2至t4的时间段。
3)中断服务阶段,这个指从系统开始执行中断服务程序到中断服务程序执行完的时间段,也就是图中t4至t5的时间段。这个时间段的长度与具体的中断或者说具体的应用有关,也就是说,这个时间段的长度是可以控制的。
4)中断返回阶段,这个指从中断服务程序执行完到恢复被中断代码开始运行的时间段,也就是图中t5至t6的时间段。这个期间系统要做的主要操作是恢复寄存器的值,这个时间段长度一般也是固定的。
5)调度潜伏期(Schedule Latency)或者说调度延迟,这个指从系统需要进行进程调度(当前进程的进程结构中need_resched的值为1)到实际开始进行调度的时间段,也就是图中t6至t7的时间段。由于Linux2.4内核的不可抢占性,当系统运行在内核空间中时,即使有更高优先级的进程需要运行,除非主动请求进行调度,否则高优先级的进程是无法抢占当前进程运行的;所以,只有等到低优先级进程的系统调用完成或主动请求调度的时候,才能进行进程的调度。
6)进程调度时间,这个指从系统开始进行调度到最高优先级的进程开始被调度运行的时间段,也就是图中t7至t8的时间段。在这个期间,系统主要是根据系统资源的利用情况、进程的优先级、进程的运行情况,选择合适的进程进行调度。

待续……

[ 本帖最后由 siasd 于 2006-7-26 21:37 编辑 ]

论坛徽章:
0
16 [报告]
发表于 2006-10-27 00:37 |只看该作者
根据Adeos的机制,RTAI和Linux kernel之间的函数是不能直接调用的(记得好像是),他们属于不同的域,而域之间的通信方式就只有通过Adeos提供的虚拟中断机制了,比如,如果RTAI想要执行Linux kernel中的某个函数操作,可以先在linux 域中建立一个虚拟中断处理程序来调用RTAI想要执行的操作,然后在RTAI中触发这个中断;这样的话,当linux 域开始运行的时候,就会调用那个虚拟中断处理程序了;比如,在rtai中可以调用printk,就是用这种放法来实现的。

论坛徽章:
0
15 [报告]
发表于 2006-10-26 00:46 |只看该作者

siasd能否介绍一下rtdm和rtai访问硬件?

rtai如果不能在kern有效的访问硬件,硬实时就白搭了。原以为comedi可以直接为rtai提供驱动来访问硬件,看来好像不行。从iarte等几个项目看,需要利用rtdm为rtai的硬实时专门写驱动。希望siasd能介绍有关rtai驱动的注意事项。例如直接加入pci_get_device函数,编译能通过,但模块不能执行,不知怎末回事。

论坛徽章:
0
14 [报告]
发表于 2006-10-22 22:22 |只看该作者
LZ,整理一个PDF方便一下大家,呵呵

论坛徽章:
0
13 [报告]
发表于 2006-10-22 22:05 |只看该作者

linux实时性评测方法

在完成Linux的实时化研究和实现之后,只有对实现后的系统进行评测,才能证明研究和实现的正确性,只有通过实验数据,才能检验实现的系统是否达到了实时性的要求。
通过分别对通用Linux和实时化后的Linux进行实时性的测试,得出它们的实时性测试结果,用来检验研究实现的实时化Linux在实时性方面的改进。
从图2-1可以看出,实时性的一个重要参数就是任务响应延迟时间,它包含了其它几个重要的实时性参数(中断潜伏期时间,调度潜伏期时间等),任务响应延迟时间越短,说明任务对外部事件的响应速度越快,实时性也就越好。本课题测试的参数就是任务响应延迟时间。由于测量实时性参数与测量一般的时间参数不同,它一方面要求很高的时间测量精度(至少微秒级),这用纯软件的方法很难实现,另一方面测试方法本身也必须经过精心的设计,不能由于测试方法本身的时间误差而影响测量的精度和准确性。
所以,本课题采用硬件定时器(S3C2410的定时器精度可达0.04微秒)进行任务响应延迟时间的测量,而且对通用Linux和实时化后的Linux分别设计了测试程序,使测试程序对系统的影响降到最小;
测试所选用的系统负载主要来源于Linux Test Project,系统负载程序取自于LTP当前最新的测试包ltp-base-20051205.tgz(可以从LTP站点http://ltp.sourceforge.net获得),所选用的负载内容包括:
1)创建5个进程反复进行开平方根操作;
2)创建5个进程反复进行内存的分配和释放操作;
3)创建5个进程反复进行大文件的写操作(文件大小1GB),测试系统的根文件系统用的是NFS网络文件系统,一方面可以支持大文件的写操作,另一方面实际上也给系统增加网络负载,因为对文件系统的写操作实际上是通过网络最终写到NFS服务器上的。
4)反复创建多个进程进行进程间通信操作,主要包括消息队列、管道、信号量、共享内存、信号等。
从测试过程中可以看出,当运行以上的系统负载的时候,系统处于满负荷状态,这可以从几方面看出,一方面是系统控制台的响应速度非常慢,几乎已经无法进行交互操作了,另一方面系统会反复出现内存不足的情况,还有就是网络操作经常出现超时的情况。
对通用Linux和实时化后的Linux分别作了无负载和有负载情况下的实时性测试,测试以定时器中断来模拟外部事件,定时器每1ms产生一次中断,产生中断后测试程序进行一次测量,每次测试过程测试400万次,所以,每次测试过程持续时间大约是67分钟。
另外,测试过程中由于系统负载过重,会出现系统内存不足的情况,这时系统就会选择某些进程,将它们强行终止以获取可用内存;而测试进程在系统中占用的内存最多(4M*8B=32MB),每次在测试过程中测试进程都会被系统终止,无法完成测试任务。为了解决这个问题,经过分析得知,系统在内存紧缺的情况下对所要终止的进程的选择,是依据内核函数static int badness(struct task_struct *p)的返回值来确定的,而且这个函数的返回值则是以进程占用的内存数为基准的,所以,由于测试进程占用的内存相当大,才会每次被终止;为了防止测试进程被终止,对内核的badness函数进行了修改,当进程的调度策略为SCHED_FIFO(测试进程的调度策略)的时候,使它的返回值为0,这样,系统在选择要被终止的进程的时候,就不会选择测试进程了。
测试后的400万次测试结果,按测试先后时间分成200组,每组20000个数据,例如,第一个200次测试结果分别为200组的第一个数据,第二个200次测试结果分别为200组的第二个数据,以此类推。然后将这200组数据分别在同一个坐标平面内以曲线形式表现出来,得到比较直观的测试图。
==============
通用Linux实时性测试
测试方法
利用S3C2410的定时器Timer2来对任务响应延迟时间进行测量,整个测试程序分为内核空间(Timer2驱动程序)和用户空间两部分,驱动程序提供对定时器的操作(包括设置中断周期、读取计数值、开启/停止定时器等),用户空间程序主要是通过驱动程序提供的操作控制定时器,测量任务响应延迟时间,并记录测试结果。图5-1显示了任务响应延迟时间的测试原理(可以结合图2-1的Linux任务响应模型来理解)。



下面根据图5-1所示来阐述在普通Linux下任务响应延迟时间的测量。
先将定时器Timer2的驱动程序模块成功加载,并在系统中建立相应的设备节点,然后开始运行用户空间的测试程序,这时对应于图5-1中的t0时刻;一方面为了防止其它进程与测试程序分享CPU资源,保证测试程序能够及时的实现对定时器的操作,另一方面为了保证任务调度延迟时间测量的准确性(消除由于分时调度而引起的误差),将测试进程的调度方式设为SCHED_FIFO,将优先级设为99(最高优先级),也就是说设为Linux本身所说的实时进程,这些操作都是在图5-1中时间段①内完成的;紧接着在时间段②内通过定时器驱动程序提供的设备接口,对定时器进行设置,并开启定时器,这时定时器开始计数(每一个时钟周期减一),同时,测试进程进入等待状态(在定时器驱动程序提供的等待队列上等待,直到定时器的中断服务程序执行才将其唤醒);
在时间段④内,测试程序处于睡眠等待状态,定时器在运行(每个时钟周期减一),系统的其它进程(系统负载)占用CPU资源而处于运行状态,负载在运行过程中,会反复的在用户空间和内核空间交替运行,而且在调用系统服务的过程中(也就是在内核空间运行的时候)也会经常进入系统的临界区(禁止CPU响应外部中断),从而会产生中断响应延迟;当系统运行到t3时刻时,定时器计数到0,开始下一个周期的运行,同时向CPU产生一个中断,请求CPU的中断处理,但这时由于中断延迟(图5-1中t3至t4的时间段)的存在,CPU很可能不能立即响应中断,直到时刻t4,CPU才开始进行定时器的中断处理;在时间段⑤内,运行定时器的中断服务程序,这个中断服务程序完成的唯一功能就是向系统纪录定时器的一次周期运行(通过变量的加一实现)并唤醒等待在定时器驱动程序队列中的进程(就是测试程序),当中断服务程序返回的时候,测试进程处于就绪状态,而且它的优先级在系统中最高,但这时由于被中断的系统负载进程很可能正处于内核空间,而在内核空间是不允许进行进程抢占的,所以直到t6时刻系统负载进程完成了系统调用,测试进程才能被开始调度运行,从测试进程处于就绪状态可以被调度运行的时刻到它实际上被调度运行的时刻之间的时间就是我们所说的调度延迟时间。
在时间段⑥,测试进程被唤醒开始运行,唤醒后立刻读取定时器当前的计数值,从图中可以看出,从定时器产生中断的时刻t3到测试进程被唤醒的时刻t6之间的时间间隔就是任务响应的延迟时间,我们可以通过进程被唤醒后所读取的定时器的计数值和定时器初始值之差来获得这个延迟时间(当然,实际实现的时候比这个复杂,因为在测试进程被唤醒之前定时器很可能已经运行了不止一个周期)。当测试进程读取完定时器的计数值,得到一次任务响应延迟时间的采样值后,再次进入睡眠等待状态,开始下一次采样。
========
测试结果分析
表5-5对比显示了普通Linux和实时化Linux的实时性测试结果。

表 5-5
        普通Linux无负载        RTAI/Linux无负载        普通Linux有负载        RTAI/Linux有负载
平均值(微秒)        4.7941429        26.352688        148.60925        69.6369351
最大值(微秒)        1048.96        123.52        68568.96        506.24
最小值(微秒)        4.48        9.6        4.48        9.6
小于10微秒        99.24%        4.44%        0.03%        0.23%
小于20微秒        99.48%        68.58%        0.04%        0.55%
小于30微秒        99.70%        79.01%        0.05%        0.73%
小于40微秒        99.72%        79.33%        0.28%        1.14%
小于50微秒        99.73%        79.33%        0.54%        2.47%
小于60微秒        99.73%        79.33%        0.68%        16.35%
小于70微秒        99.94%        86.21%        19.15%        23.76%
小于80微秒        99.96%        99.55%        64.59%        96.20%
小于90微秒        99.98%        99.72%        70.27%        97.67%
小于100微秒        99.99%        99.83%        72.47%        99.18%
小于200微秒        100.00%        100.00%        82.70%        100.00%
小于500微秒        100.00%        100.00%        98.11%        100.00%
小于1毫秒        100.00%        100.00%        99.64%        100.00%
小于10毫秒        100.00%        100.00%        99.99%        100.00%
小于50毫秒        100.00%        100.00%        100.00%        100.00%
小于100毫秒        100.00%        100.00%        100.00%        100.00%


从任务响应延迟时间的最大值来看,在无负载和有负载的情况下,普通Linux分别为1048.96微秒和68568.96微秒,而RTAI+Linux则分别为123.52微秒和506.24微秒,由此可见,实时化后的系统最大任务响应延迟时间缩短了将近10倍,显著的提高了Linux对实时任务的支持程度。
从任务响应延迟时间的最小值来看,实时化Linux是普通Linux的2倍,这是由于实时化后的Linux底层的中断管理都是由Adeos来控制,然后才传递给Adoes中的域(Linux和RTAI),所以,实时化Linux的中断处理路径要比普通Linux复杂,花费的时间稍长。

论坛徽章:
0
12 [报告]
发表于 2006-10-12 08:57 |只看该作者
这么好的帖子一定要顶,希望楼主还有更好的资料可以共享!!!

论坛徽章:
0
11 [报告]
发表于 2006-09-14 23:48 |只看该作者

rtai还是不错的,社区很多

rtai许多领域在用,工控、机械加工、机器人、高速数据采集处理....等,主要看中他的实时性能。再者非商业性,一切透明。多数非用rtai不可的领域都是作专用设备,移植不移植的无所谓。
bluecat软实时,肯定不能和rtai比,MontaVista也差不多,商业化的。好像工业领域不太适合,做手机、机顶盒比较合适。

论坛徽章:
0
10 [报告]
发表于 2006-09-14 10:45 |只看该作者
我觉得,RTAI和RTLINUXPRO这一系列,因为采用的是双os架构,实时性可能比较好,但是编程接口不通用和rtlinux的封闭性,造成了不可能广泛的流行。

论坛徽章:
0
9 [报告]
发表于 2006-09-14 08:46 |只看该作者
RTAI 已经死了, 从内核到应用程序,没有移植性的,没有兼容性,其实现方式注定了他的灭亡,
从2.6 开始实时linux 就是 bluecat 和  MontaVista 的天下。2.6 内核的realtime 代码很多是MontaVista 提供的。

论坛徽章:
0
8 [报告]
发表于 2006-09-14 02:57 |只看该作者

感谢楼主,写得真好,应当加为“精品”.

刚开始学习rtai编程,此文使我对rtai的实现机制有了很多了解。
我用的是rtai-3.4-test2版+debian(sarge3.1)+kernel2.6.16.19,
用rtai-3.4包中自带的rt-hal.patch为kernel打的补丁,编译安装都成功了
中间有点小挫折,很快克服了,主要是内核的apic设置不对,还有就是kernel2.6.12之前的版本不支持ipipe的问题。

现在testsuite目录下的程序都能运行通过,只是我还没太搞透程序
的含义和原理,主要是我对内核还缺乏了解,现在读了楼主的帖子
帮助很大,再一次感谢啊!

希望楼主能继续发帖,不吝赐教。
我也会将自己的一些所得贴上来的,下步我还准备装上comedi+rtai-lab
还有scilab。还有好象xenomai比较有用,不知怎么用法抽空了解,了解。先写到这儿吧。
  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP