在嵌入式实时系统中设置调度禁区的方法

文档序号:6651620阅读:144来源:国知局
专利名称:在嵌入式实时系统中设置调度禁区的方法
技术领域
本发明涉及一种设置调度禁区的方法,尤其涉及一种在嵌入式实时系统中设置调度禁区的方法。
背景技术
随着嵌入式系统功能的增强,现在大多数系统都采用了多进程的方式。而作为实时应用系统,进程调度成了嵌入式实时操作系统(RTOS-Real-TimeOperating System)中最关键的部分,因为进程调度所耗的时间直接关系到了实时系统的实时性。
进程的调度可以分成两部分一是进行进程“上下文”的交换,称为进程切换,它属于进程调度的后半部分;前半部分则是用来确定进程调度的时机,称为进程调度。在现在流行的嵌入式系统设计中,大家一般醉心优化进程切换操作。而即使是较复杂的系统,也往往只会多十几条指令,虽然速度确实会慢些,但对于现代CPU越来越快的运行速度,这方面的差别实际上可以忽略不计。
然而,进程调度就不同了,特别是当系统因功能的增强而越来越复杂时,同时运行的进程数急剧增加,实时调度策略运用又使得进程调度算法变得更复杂,这就会增加系统的调度延迟。但系统调度延迟主要还不在于此,而在于从产生调度要求到实施真正的进程调度,即进行切换,所需等待的时间。对于实时系统来说,最好是有调度请求,就能立即进行调度,因为这样才能更好地满足实现高优先级任务的要求。不论调度的请求是由当前进程主动发起的,还是由于中断产生更紧迫的任务,抢占CPU运行的任务往往具有更高的优先级。然而这只是个美好的愿望,因为在多进程的环境中不可能不存在“调度禁区”。调度禁区就是禁止进行进程切换的代码段。
事实上,整个系统所有“调度禁区”的勘定极为困难。对于简单地系统,也许靠经验丰富的系统设计人员可以划分出所需调度保护的代码片断。但对于日益复杂的嵌入式系统,如智能手机等,则几乎不可能了。为了满足嵌入式系统实时性的要求,目前常用的做法有两种一种是以时间片或定时器的方式统一限定了进程不可进行调度的时间限制;二是在嵌入式操作系统设计时,对“调度禁区”进行粗略地划分。明显对于第一种策略简单易行,但会产生当没有调度请求时也要进行进程调度,这与节约宝贵的嵌入式系统的精神是不相符的。第二种策略以最新嵌入式Linux2.6为代表,正是看到了第一种策略的弱点,对调度禁区进行了划分,并对操作系统的内核进行了修补,以实现更精确的实时调度。但是鉴于系统的复杂性,这种划分往往是粗略的,而耗时最长的调度禁区,它将决定我们嵌入式系统的实时性能。像嵌入式Linux2.6就是利用调度禁区与对称多处理器(SMP-Symmetric MultipleProcessor)结构的“访问禁区”大部分重合的特点,充分利用了“访问禁区”机制来实现规避调度禁区的实时调度。然而调度禁区并不完全与“访问禁区”重合,里面又包含了多余的“访问禁区”成分。而且目前“禁区”地划分无章可循,谁也不能保证是否有“调度禁区”被遗漏,如果真被遗漏了,那对整个系统都可能是灾难性,而且故障极难定位。

发明内容
本发明所要解决的技术问题在于提供一种在嵌入式实时系统中设置调度禁区的方法,从而更精细的划分嵌入式实时系统中的调度禁区。
为了解决上述技术问题,本发明提供一种在嵌入式实时系统中设置调度禁区的方法,包含(1)在所述嵌入式实时系统中确定一个进程;(2)在该进程与操作系统交互的接口处,判断该进程对操作系统的访问是否有返回值;(3)如果该进程对操作系统的访问有返回值,则确定影响该返回值的内部局部变量,并判断该局部变量的变化是否与全局变量相关;(4)如果该局部变量的变化与全局变量相关,则确定影响该局部变量的全局变量,并定位对该全局变量进行操作的代码段与对该局部变量进行操作的代码段;(5)将所述两个代码段紧密的放在一起,作为一个整体代码段加锁,设置该区域为调度禁区。(6)遍历所述嵌入式实时系统中的所有进程,对每个进程重复执行步骤(2)至(5);(7)通过查询所述嵌入式实时系统的操作系统内核中的全局变量所能影响到的变量,检查所述调度禁区的设置是否有遗漏,如果有遗漏,则对遗漏的代码段加锁,设置为调度禁区。
其中,所述步骤(7)包括如下步骤(7-1)在所述嵌入式实时系统的操作系统内核中确定一个全局变量;(7-2)根据该全局变量,确定该全局变量所能影响到的变量;(7-3)判断该受全局变量影响的变量是否会对系统进程的执行结果产生影响;(7-4)如果该受全局变量影响的变量会对系统进程的执行结果产生影响,则定位对该全局变量进行操作的代码段与对该受全局变量影响的变量进行操作的代码段;(7-5)将所述两个代码段紧密的放在一起,作为一个整体代码段加锁,设置该区域为调度禁区;(7-6)遍历所述操作系统内核中的所有全局变量,对每个全局变量重复执行步骤(7-2)至(7-5)。
本发明的优点在于经过精细化划分嵌入式实时系统的调度禁区,避免了调度禁区被遗漏的现象,有力地保证整个系统设计的稳定性,同时使得调度禁区短小精悍,从而使得新的调度请求可以迅速得到响应,极大提高了系统的实时性能。


图1为根据本发明实施例所述的设置调度禁区的系统结构图;图2为根据本发明实施例所述的变量验证模块结构图;图3为根据本发明实施例所述的设置调度禁区的方法流程图;图4为根据本发明实施例所述的全局变量验证方法流程图。
具体实施例方式
下面结合附图,对本发明的实施例进行详细说明。
要划分调度禁区,就是要对嵌入式操作系统中的代码段进行审查,将确实不允许在中途发生调度的代码片断保护起来,放在临界区中,即调度禁区中。如图1所示,本发明的系统包含访问判断模块201,用于在该进程与操作系统交互的接口处,判断该进程对操作系统的访问是否有返回值,如果该进程对操作系统的访问没有返回值,则放弃对该进程的追踪。变量判断模块202,当该进程对操作系统的访问有返回值时,用于确定影响该返回值的局部变量,并判断该局部变量的变化是否与全局变量相关,如果该局部变量的变化与全局变量无关,则放弃对该进程的追踪。代码段定位模块203,当该局部变量的变化与全局变量相关时,用于确定影响该局部变量的全局变量,并定位对该全局变量进行操作的代码段与对该局部变量进行操作的代码段;代码段加锁模块204,用于将所述两个代码段紧密的放在一起,作为一个整体代码段前/后设置lock/unlock原子操作进行加锁,设置该区域为调度禁区;进程遍历模块205,用于在所述嵌入式系统中遍历全部进程,从中获取一个进程给所述访问判断模块201进行判断;变量验证模块206,用于通过查询所述嵌入式实时系统的操作系统内核中的全局变量所能影响到的变量,检查所述调度禁区的设置是否有遗漏,如果有遗漏,则对遗漏的代码段加锁,设置为调度禁区。
如图2所示,所述变量验证模块206,包括变量查询模块2061,用于根据全局变量,确定该全局变量所能影响到的局部变量。变量重判断模块2062,用于判断该受全局变量影响的局部变量是否会对系统进程的执行结果产生影响,如果判断到该受全局变量影响的局部变量不会对系统进程的执行结果产生影响,则放弃对该局部变量的追踪。代码段重定位模块2063,当该受全局变量影响的局部变量会对系统进程的执行结果产生影响时,定位对该全局变量进行操作的代码段与对该受全局变量影响的局部变量进行操作的代码段;代码段重加锁模块2064,用于将所述两个代码段紧密的放在一起,作为一个整体代码段前/后设置lock/unlock原子操作进行加锁,设置该区域为调度禁区;变量遍历模块2065,用于遍历所述操作系统内核中的所有全局变量,将每个全局变量依次提供给所述变量查询模块2061。
如图3所示,在实际操作中,首先在所述嵌入式实时系统中确定一个进程(步骤101)。然后,通过访问判断模块201在该进程与操作系统交互的接口处,判断该进程对操作系统的访问是否有返回值(步骤102),如果该进程对操作系统的访问没有返回值,则放弃对该进程的追踪(步骤103);如果该进程对操作系统的访问有返回值,则通过代码段定位模块203确定影响该返回值的局部变量(步骤104),并判断该局部变量的变化是否与全局变量相关(步骤105),如果该局部变量的变化与全局变量无关,则放弃对该进程的追踪(步骤106);如果该局部变量的变化与全局变量相关,则通过代码段定位模块203确定影响该局部变量的全局变量(步骤107),并定位对该全局变量进行操作的代码段与对该局部变量进行操作的代码段(步骤108)。再通过代码段加锁模块204将所述两个代码段紧密的放在一起,作为一个整体代码段前/后设置lock/unlock原子操作进行加锁,设置该区域为调度禁区(步骤109)。接着,通过进程遍历模块205遍历所述嵌入式实时系统中的所有进程,对每个进程重复执行步骤102至步骤109(步骤110)。最后,通过变量验证模块206查询所述嵌入式实时系统的操作系统内核中的全局变量所能影响到的变量,检查所述调度禁区的设置是否有遗漏(步骤111),如果有遗漏,则对遗漏的代码段加锁,设置为调度禁区(步骤112)。
如图4所示,所述步骤111在实际操作中是这样实现的首先在所述嵌入式实时系统的操作系统内核中确定一个全局变量(步骤1111)。再通过变量查询模块2061确定该全局变量所能影响到的局部变量(步骤1112)。然后,通过变量重判断模块2062判断该受全局变量影响的局部变量是否会对系统进程的执行结果产生影响(步骤1113);如果该受全局变量影响的局部变量不会对系统进程的执行结果产生影响,则放弃对该局部变量的追踪(步骤1114)。如果该受全局变量影响的局部变量会对系统进程的执行结果产生影响,则通过代码段重定位模块2063定位对该全局变量进行操作的代码段与对该受全局变量影响的局部变量进行操作的代码段(步骤1115)。接着,通过代码段重加锁模块2064将所述两个代码段紧密的放在一起,作为一个整体代码段前/后设置lock/unlock原子操作进行加锁,设置该区域为调度禁区(步骤1116)。最后,通过变量遍历模块2065遍历所述操作系统内核中的所有全局变量,对每个全局变量重复执行步骤1112至步骤1116(步骤1117)。
竞争是由进程这些“活动者”引起的,因此我们首先从各进程入手审查嵌入式系统可能存在的“调度禁区”。根据调度禁区产生的机理,从各进程与操作系统交互的接口系统调用入手,判断所调用的系统调用是否有值返回,如没有,就不再考虑该系统调用。如有,则要进一步审查影响该值的局部变量,并判断该局部变量变化是否与全局变量相关。如没有,也将不再考虑;如有,则应将与其相关全局变量的操作和对局部变量的直接操作紧密地放在一块,并在该段代码片段前/后加上lock/unlock原子操作,即标识出并制造出一块精细化的调度禁区,以这个操作遍历完所有的进程。如有进程A要根据某一局部变量VLOCAL值确定执行路线,而该局部变量又受控于一共享全局变量VGLOBAL,则根据VGLOBAL改变VLOCAL值的代码就应加锁,否则该段代码随时可被中断,那VGLOBAL的值就可能被改变,从而导致进程A所做出的响应与系统并不符,或该响应的动作被漏掉,结果整个系统就会乱套。因此,我们首先统计进程对操作系统访问的系统调用,重点关注调用返回变量。
对嵌入式实时系统中所有进程的遍历,涉及到进程的统计工作,而嵌入式系统与普通计算机系统一个最大的不同点,就是嵌入式系统上运行的进程是固定的。面对不同的嵌入式操作系统,统计整个系统的进程数的具体方法会有所不同。从程序语句上,创建新进程的函数的名称往往因操作系统的不同而不同,但不管采用何种操作系统,它一般都有那么固定的几种产生进程的方法。将这些函数(或方法)取个通用名CreateProcess,根据这些专用的函数名(或方法名),运用SourceInsight等代码阅读分析工具,来找出和统计出所构建的嵌入式系统可能的进程,并建立起相应的进程森林图。各种嵌入式操作系统提供厂商,考虑到嵌入式系统的灵活性和针对性较强的特点,公开了绝大部分的源代码。从源代码入手,找出嵌入式系统上运行的进程,并统计出其数量。另外,各操作系统一般也提供了查看系统中运行进程状态的命令或工具,如Linux中的PS,Windows中的任务管理器等。通过这些命令或工具也可以统计出系统中运行的进程情况,并验证前面根据源代码所做统计的正确性。
我们还要统计操作系统全局变量的信息。该信息在本发明的作用是来验证根据进程划分出的调度禁区是否有遗漏,这点特别重要,正是因为它,我们才得以确保调度禁区不被遗漏。由于进程调度是操作系统最内核的东西,调度禁区遗漏对整个实时系统将是致命的。为此在所发明的方法中还安排了检查工作。不过这次是以引起竞争调度的另一半--全局变量为切入点,审查每个全局变量所会影响的变量,接着审查这些变量是否会对进程的执行结果产生影响,从而查找出可能的调度禁区,并与上一步审查结果相比对,如发现遗漏的调度禁区,依上一步的方法标识出该段“新”的“调度禁区”。
同样,对嵌入式实时系统中所有变量的遍历,涉及到变量的统计工作。内核的全局量都是共享资源,其中全局常量因其值不变,不会影响调度禁区,因此不考虑全局常量。对于嵌入式系统中其他的共享资源,如外围端口等,一般与全局变量一样被映射到了某一内存地址,其值因随外部设备的状态会变化,因此把它当全局变量看待。光有进程,没有被抢的共享资源是不会产生调度禁区的问题的。至于全局变量的统计,也是是通过分析各嵌入式源代码来实现的。全局变量在代码中有其独特的形式,根据其特点,应用SourceInsight等代码阅读与分析工具,可以方便地将它们找出来。
不同的操作系统往往有自己实现具体系统调用的接口的方法,但在源代码中也都是有迹可查的。如Linux中,所有上层要用到的系统调用的定义,都放在了/include/asm/unistd.h这个头文件中,这些系统调用又将会映射到内核中系统调用表的表项,而这些表项将指到具体的功能实现代码。运用SourceInsight等代码阅读分析工具可以方便地把进程与内核系统的通信找出。采取深度优先算法,在每个进程下进行了该类搜索,并将系统调用的名称,功能代码段的名称和牵涉到的交互变量以图的形式,记录在每一个进程树图下。一个进程可有多个系统调用,每个系统调用构成一个分支并挂在对应的进程下,最后形成了一棵树。
上述进程与内核系统交互的纵向探索中,重点就是要查获系统调用是否有返回,是否会对具体进程中的变量产生影响,并挖掘出影响该变量值的局部变量。工作完成后,这些属于各进程的变量和属于内核系统的变量,在上述对应的进程树中都将有所体现。这些是在应用代码阅读分析工具的基础上,由系统工程师深入阅读与分析源代码实现的。
由于进程的运行是动态的,没有人能对内核何时对进程的执行产生了影响作出判定。本发明是要更加精细化调度禁区,就是让不可抢占调度权的代码段尽可能地短,从而尽可能快地响应其他的实时任务。如上所述,如果发现有内核变量可能对上层进程的变量产生影响,就将在可能改变该内核变量的代码前后加上lock/unlock原子操作进行加锁,以表明该代码段将运行于调度禁区内。如在Linux中可在该代码前加上prempt_disable,以禁止其后代码运行时可被抢占CPU的执行权;而在该代码后加上prempt_enable,标识其后的代码可以继续被抢占调度,以让CPU响应更高优先级的任务。
权利要求
1.一种在嵌入式实时系统中设置调度禁区的方法,其特征在于,包括如下步骤(1)在所述嵌入式实时系统中确定一个进程;(2)在该进程与操作系统交互的接口处,判断该进程对操作系统的访问是否有返回值;(3)如果该进程对操作系统的访问有返回值,则确定影响该返回值的局部变量,并判断该局部变量的变化是否与全局变量相关;(4)如果该局部变量的变化与全局变量相关,则确定影响该局部变量的全局变量,并定位对该全局变量进行操作的代码段与对该局部变量进行操作的代码段;(5)将所述两个代码段紧密的放在一起,作为一个整体代码段加锁,设置该区域为调度禁区。(6)遍历所述嵌入式实时系统中的所有进程,对每个进程重复执行步骤(2)至(5);(7)通过查询所述嵌入式实时系统的操作系统内核中的全局变量所能影响到的变量,检查所述调度禁区的设置是否有遗漏,如果有遗漏,则对遗漏的代码段加锁,设置为调度禁区。
2.如权利要求1所述的方法,其特征在于,所述的步骤(7),包括如下步骤(7-1)在所述嵌入式实时系统的操作系统内核中确定一个全局变量;(7-2)根据该全局变量,确定该全局变量所能影响到的变量;(7-3)判断该受全局变量影响的变量是否会对系统进程的执行结果产生影响;(7-4)如果该受全局变量影响的变量会对系统进程的执行结果产生影响,则定位对该全局变量进行操作的代码段与对该受全局变量影响的变量进行操作的代码段;(7-5)将所述两个代码段紧密的放在一起,作为一个整体代码段加锁,设置该区域为调度禁区;(7-6)遍历所述操作系统内核中的所有全局变量,对每个全局变量重复执行步骤(7-2)至(7-5)。
3.如权利要求1所述的方法,其特征在于,所述步骤(2)中,如果该进程对操作系统的访问没有返回值,则放弃对该进程的追踪。
4.如权利要求1所述的方法,其特征在于,所述步骤(3)中,如果该局部变量的变化与全局变量无关,则放弃对该进程的追踪。
5.如权利要求1所述的方法,其特征在于,所述步骤(5)中,是通过在整体代码段前/后设置lock/unlock原子操作而进行加锁的。
6.如权利要求2所述的方法,其特征在于,所述步骤(7-3)中,如果该受全局变量影响的变量不会对系统进程的执行结果产生影响,则放弃对该变量的追踪。
7.如权利要求2所述的方法,其特征在于,所述受全局变量影响的变量是一个局部变量。
8.如权利要求2所述的方法,其特征在于,所述步骤(7-5)中,是通过在整体代码段前/后设置lock/unlock原子操作而进行加锁的。
全文摘要
本发明提供一种在嵌入式实时系统中设置调度禁区的方法,具体包含(1)在嵌入式实时系统中确定一个进程;(2)判断该进程对系统的访问是否有返回值;(3)如果有,则确定影响该返回值的局部变量,判断该局部变量的变化是否与全局变量相关;(4)如相关,则确定影响该局部变量的全局变量,定位对该全局变量与局部变量进行操作的代码段;(5)将两个代码段作为一个整体加锁,设为调度禁区。(6)遍历所有进程,对每个进程重复执行(2)至(5);(7)通过查询操作系统内核中的全局变量所能影响到的变量,检查调度禁区的设置是否有遗漏,如果有,则对遗漏的代码段加锁,设置为调度禁区。本发明更精细的划分了嵌入式实时系统中的调度禁区。
文档编号G06F9/46GK1983190SQ20051013422
公开日2007年6月20日 申请日期2005年12月12日 优先权日2005年12月12日
发明者刘洋 申请人:中兴通讯股份有限公司
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1