RTLinuxPro处理器预留和中断控制技术_第1页
RTLinuxPro处理器预留和中断控制技术_第2页
RTLinuxPro处理器预留和中断控制技术_第3页
RTLinuxPro处理器预留和中断控制技术_第4页
RTLinuxPro处理器预留和中断控制技术_第5页
已阅读5页,还剩1页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、RTLinuxPro处理器预留和中断控制技术        一些Linux实时操作系统制造商把中断响应时间和处理器预留作为得到实时Linux的主要方法。但其负面结果是功能环境缩小、服务功能简单,没有实时性的保证。本文分析了RTLinuxPro是如何简易地为用户产生处理器预留和中断控制,以及如何提供一个完整的POSIX RTOS环境来支持它。     硬实时操作系统一直以来是一个功能单一、非集成化,不受重视的应用领域。另一方面,Linux系统则代表了目前计算机技术当中良好的集成

2、性和普适性。如果把这二者结合起来,那将得到一个功能完善的硬实时操作系统,同时可以把具有web接入的用户的网络功能部分以一种快捷、安全和简单的方式集成到系统当中。 图1:RTLinux技术。    RTCore就是这样一种能够为RTLinuxPro和RTCoreBSD提供硬实时环境的例子。除了大量的Linux应用接口外,RTCore还提供POSIX环境下硬实时的中断句柄、线程、信号、互斥体(mutexes)、信号量(semaphores)、进程间通信等。     同类技术中,其它方法的重点是放在对中断响应时间的提高方

3、面。其工作本身是有探索价值的,但取得的结果却很有限,只是在一个特定LINUX版本和硬件体系结构下使中断响应时间得到了改善,仍然没有硬实时方面的保证。同时,采用这些方法的操作系统提供给编程者的服务也十分有限。尽管对于某些基础应用,如频繁的采样和对采样信号的简单快速响应的场合,这些方法是有效的,但多数情况下,却反映出现实中的应用领域根本就不是那么地简单。 特定CPU上的线程引导     先来看一个实时线程如何将自己装入一个给定的CPU的例子。 -此处放L1-     这里没有什么新的东西,一个新的线程产生,就像其他任何

4、的POSIX应用一样。区别只是这一行“pthread_attr_setcpu_np(&attr, 0);”。这句告诉RTCore当新的线程创建的时候,应该把它放到CPU 0中,而且永远不会从CPU中被清除掉。原因在于当一个线程/任务被允许从一个处理器转移到另一个的时候,高速缓存(Cache)的影响会改变实时性能。如果知道了在什么样的CPU上都有哪些线程,那么就可以把这种转移的影响降低到最小,实时性能也会得到显著提高,同时RTOS的调度负荷也降到了最低。     另外一个比较新的东西是“timespec_add_ns(&next,1000*

5、1000);”,这句给timespec结构体增加了一个毫秒,它是为了方便起见而提供的一个函数(POSIX并没有定义这个函数,所以用户通常要手工规格化一些数据)。如果用户熟悉RTLinux,就不应该对这个函数感到陌生,它已经用了好几年了。RTLinuxPro的用户应该注意到这个函数:rtl_main_wait(),这是一个事件等待句柄,它允许程序暂时挂起直到从用户或者系统接收到一个退出信号。(类似于GUI应用中的事件等待进入函数)。     上述已经在一个特定的CPU上有了一个线程,并且可以保留该CPU不被普通OS所占用。本文中进行的所有测试都把Linux

6、当作一个普通的OS。 预留处理器     这个小标题似乎有些模棱两可。本文的题目隐含了处理器预留这个难题的重点,似乎需要深入而详细地讨论,但实际上,代码里只要一行程序就可以了。下面是对前面程序的修改: . pthread_attr_setcpu_np(&attr, 0); pthread_attr_setreserve_np(&attr, 1); pthread_create(&thread, NULL, thread_code, 0); . “pthread_attr_setreserve_np(&attr, 1);”这

7、句设置了线程的一个布尔属性。当在特定处理器上产生了一个线程后,只要该线程存在,GPOS就被禁止在这个处理器上运行。     实际上也是如此的,一旦这条语句被执行,GPOS就被禁止在处理器上面运行了,只能为创立的线程保留CPU(包括运行在CPU上的其它实时线程)。在有些情况下,允许所有的实时应用程序直接保留在处理器的高速缓存中。由于处理器不用再去RAM中取代码了,所以处理器的性能相对得到了提高。因为GPOS永远不会在Cache中运行,从而不会把实时代码挤出Cache,所以Cache永远都被实时代码占据。(Linux相当庞大,一旦运行起来就会占据很大的Cac

8、he空间)。 中断控制     在上面的代码中,为实时代码保留CPU会对其上的GPOS中断产生负面的影响。由于Linux不在其上运行了,不能接受中断了,所以对于其他设备,如以太网设备这样的硬件就只等通过另外一个CPU为Linux提供信号了。这样就使得保留的处理器不处理任何除了产生实时线程以外的任何中断。     现在处理器完全在实时线程的控制下了,我们再次把重点放在处理器上所感兴趣的实时中断上。对于线程,由于可控的高速缓存的作用而使得结果的性能更好,同时也使得中断控制器被激活的次数达到最小,只需要处理很少量的中断了

9、。     下面看一下如何处理这个问题,由于POSIX处理不了中断,所以必须要有专门的RTCore函数来处理它,首先,我们在函数的前面定义一个counting中断句柄: . static int interrupt_count = 0; unsigned int interrupt_handler(unsigned int irq, struct rtl_frame *regs) interrupt_count+; rtl_global_pend_irq(irq); return 0; . 然后把它加入到线程代码中,重新关注一下CPU 0的中断: . s

10、tatic unsigned long affinity = 1; static unsigned long old_affinity; void *thread_code(void *t) struct timespec next; rtl_request_irq(4, interrupt_handler); rtl_irq_set_affinity(4, &affinity, &old_affinity); .     在这里,有一个非常基本的中断句柄,该句柄只是增加中断源4接收到的中断计数值(虽然我们对此中断不感兴趣,但它为GPOS

11、保留中断做以后处理)。该句柄是通过rtl request irq()函数加入到代码中的。一旦中断被清除,则释放该句柄同时恢复原来的相关屏蔽。 . pthread_join(thread, NULL); rtl_irq_set_affinity(4, &old_affinity, NULL); rtl_free_irq(4); .     在线程的初始化阶段,第一个相关函数调用将确保4号中断在处理器0上面(相关参数为CPU屏蔽位,如第0位为1说明中断应该指向CPU0)。原来的相关屏蔽就被存到旧的相关参数中了,这样当应用程序结束以后就可以重新恢复了。

12、 实际结果     对于现在这些结果和所有的这些测试,我们只报告其中最坏的情况。测试结果一般情况值通常都非常低,但对实时应用而言没有什么意义。如果你看到实时操作系统的提供商引用那些一般情况、或向你展示改善了的事件分布,则实际上,或者是他们想使的数字看起来更好一些,或者是由于他们的操作系统根本就是一个软实时系统。FSMLabs相信,如果要保证代码的绝对可*,那就必须在一个硬实时的系统当中,而系统的边界条件必须是最坏的情况。如果不是这样,那这样的操作系统就要归结到GPOS了,通常这样的GPOS都是非实时的或者充其量是软实时的。   

13、60; 首先,改变测试例子来跟踪最坏情况下期望执行时间和实际执行时间之间的延迟。加入以下代码到线程代码中,同时声明结构体timespec以跟踪最坏的情况: . clock_nanosleep(CLOCK_REALTIME, TIMER_ABSTIME, &next, NULL); clock_gettime(CLOCK_REALTIME, &sample); timespec_sub(&sample, &next); if (timespec_gt(&sample,&worst) worst.tv_sec = sample.tv_sec

14、; worst.tv_nsec = sample.tv_nsec; printf("Worst case - %lds, %ldns ", worst.tv_sec,worst.tv_nsec); .     每一个测试都将跟踪该程序体并且打印出新出现的最坏情况。因为我们关心的是处理器的预留和中断控制,所有的测试都是在RTCore下面做的,普通的Linux测试都是没有用的。 无处理器预留的实时代码     首先我们看一下上面讲过的无处理器预留的测试例子。例子涉及到实时线程每1毫秒跟踪其最坏情况偏

15、移(测试硬件是一个成熟的1.2G双核Athlon)。     定时器中断将直接用来测量中断延迟。因为定时器中断延迟影响了进入调度器以及最后进入线程代码的总延迟,测试中最坏情况下的延迟是这三个因素的总和。因此,在本测试中最坏情况下的中断延迟保证要比最后的结果要低。     测试例子经过了几天的运行,在极其高的磁盘负载、虚拟机负荷、网络负载以及开发者的使用下的得到的最坏情况下的值为16.299us。通过对比该值与下一步将要得到的结果,你很容易发现高速缓存和Linux之间的密切关系将影响系统,常常迫使Linux从RAM重

16、新装载回Cache。实际上,测试表明使用NetBSD作为GPOS将使得最坏情况数值降低,因为NetBSD总体上比较小,不像Linux运行起来要占用大量的CACHE。 有处理器预留的实时代码     在相同的一组条件下,处理器预留开启,并且程序运行周期相同,进行了同样的测试,得到的最坏情况值是2.079us,情况得到了大幅改善。其它的如高IDE使用率、以太网和其它的中断负载都对系统没有影响,因为它们都不是关注的焦点。总之,在初始化阶段计算出来Cache的影响后,就可以找到最坏情况值了。     这就是测试的整个过程,

17、没有神秘的设置或者要费神的思考,也没有统计数据、规则或者其他之类的,就只是一个最坏情况值。在一个预留的处理器上运行一个周期性的线程,然后测量调度偏差并把最坏情况值打印出来。RTCore 的最坏情况下,时间延迟2.079us,而实际上,在新的硬件上该值更小,同时仍然能够提供所需要的Linux系统的所有正常服务。 进一步减小最坏情况值     在一些应用当中,可能2us的延迟也嫌太长。在这些情况下,RTCore提供预先定时器功能,它会告诉调度器有多少的内在硬件执行时间必须要考虑在内。在这种情况下,还有多达2.709us的时间可以减小。所以,我们作如下的改动:

18、 . struct timespec worst = 0, 0 ; struct timespec advance = 0, 2500 ; void *thread_code(void *t) .     这个新的预先结构体表明了在此硬件上考虑的最坏情况补偿时间是2.5us(如果需要,可以把该值设定为2.709us),下面的代码就告诉调度器在调度一个任务的时候要把这个时间考虑在内: . timespec_add_ns(&next, 1000*1000); clock_nanosleep(CLOCK_REALTIME, TIMER_ABSTIME|

19、TIMER_ADVANCE, &next, &advance); clock_gettime(CLOCK_REALTIME, &sample); .     在和以前一样的负载下,运行同样的测试例子,我们看到的最坏情况值为143纳秒。最坏情况值开始于16us,然后伴随着处理器预留减小到2us,最后在加入3行预先调度代码后减小到0.1ms左右。这种预先调度法所带来的减小是这样的,在预先时间的一部分调度器被激活,虽然这个过程要花费额外的几个周期,但是所带来了的好处是要求的线程活动能够在预定的几个时间片(每个为10亿分之一秒)内发生。 超线程     英特尔的超线程为实时处理器预留提供了一些方法。超线程本质上是在一个核内的多处理器,因此对于像Linux这样的GPOS,就有两个逻辑处理器,但实际中只有一个物理处理器。从逻辑上讲这样做的一个优势就是可以隐藏CPU所有的复杂细节,然而处理器核仍然在共享着内部的一些资源而不是去复制这些资源。对于Linux,这一点显得不那么重要,因为对于一些应用而言带来的是好处,但对于其它的则变成了损失了。从实时的观点来看,如果一个线程运行在逻辑处理器0上(物

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论