采用双内核机制基于uClinux的实时操作系统分析与实现
发布时间:2008/5/28 0:00:00 访问次数:618
引言:本文提出了一种基于uclinux的实时操作系统,在对于资源要求苛刻而应用场合多变的嵌入式领域很有优势。该系统采用了双内核机制、借助实时硬件抽象层(rthal)概念、利用模块动态加载,对普通uclinux进行了实时性改进,实验表明完全满足实时系统的时限约束。
嵌入式linux以代码开放、价格低廉、功能强大又易于移植的特性正在被广泛应用,为嵌入式操作系统提供了一个极具吸引力的选择。uclinux是专门针对无存储器管理单元(mmu)处理器设计的嵌入式linux,非常适合中低端嵌入式系统的需求,在工业控制领域有着广阔的应用前景。
但许多实际应用要求对外部事件在限定的时间内做出反应,而普通uclinux并不是一种实时操作系统,所以本文提出了一种基于uclinux的实时性解决方案,经测试可以严格满足实时应用的时限约束,有良好的应用价值。
基于uclinux的实时方案分析
1.uclinux实时性缺陷
uclinux虽然符合posix1003.1b关于实时扩展部分的标准,例如支持sched_fifo和sched_rr实时调度策略、实时信号等实时功能,但由于其最初的设计目标为通用分时操作系统,因此在实时性支持方面,uclinux仍存在如下缺陷:
a.非抢占式内核。uclinux有用户态和核心态两种模式,当进程运行在用户态时,可以被优先级更高的进程抢占;在内核中,一个进程可以通过schedule()函数自愿地启动一次调度。除此之外,非自愿的强制调度只能发生在每次从系统调用返回前,或每次从中断或异常处理返回到用户空间前。
b.公平的调度算法。普通uclinux作为一个分时系统,其调度算法的目标是提供一种公平的调度机制,平衡系统响应时间和吞吐量,这与实时应用要求的低延迟和高度的可预测性相矛盾。实时操作系统必须保证目前运行的任务的优先级是可运行任务中最高的。
c.频繁地关中断操作。uclinux为了保证核心数据的完整性,在对关键数据结构进行修改前,通常采用"关中断"的方式。而非周期实时任务大多是由中断作出响应,周期性实时任务也需要调度模块来调度运行,而调度模块的执行也要由时钟中断触发。所以,频繁的关中断会导致实时任务不能被及时调度执行。
d.时钟粒度粗糙。时钟管理是操作系统的脉搏,是进程调度的重要依据。普通uclinux的时钟粒度被设置为10ms,而实时应用一般都需要微秒级的响应精度。
2.uclinux实时解决方案
uclinux支持硬实时性的策略有以下两种:
a.直接修改内核法
将内核中的进程调度、中断处理、时钟等部分遵循posix标准进行改写,在源代码级的基础上使uclinux变成一个实时操作系统。这种策略虽然可以获得高的执行效率,但实现难度大、周期比较长,而且对原有内核太强的依赖性使得升级工作繁重而不方便。
b.双内核方法
在同一硬件平台上采用了两个相互配合、共同工作的系统内核,一个内核提供精确的实时多任务管理,另一个内核提供复杂的非实时通用功能。由于uclinux支持内核模块动态加载,因此实时内核可在需要时以模块的形式载入。双内核机制避免了大规模结构改造,以较小的代价提供了强实时性,新系统可使用几乎所有常规uclinux操作系统提供的功能。
本文提出的嵌入式实时操作系统采用双内核的设计思想,在普通uclinux基础上,通过增加一个实时内核实现了调度的可抢占性,同时在系统中实现了硬件抽象层rthal,避免了频繁关中断所导致的实时任务不能被及时调度执行的缺陷。最后,对系统时钟进行了改进,满足了实时应用微秒级的响应精度。
基于uclinux的实时操作系统设计
1.抢占式实时内核
实时内核完全掌握了硬件层,而把非实时内核作为一个优先级最低的普通任务运行于自己之上。实时内核采用了抢占式调度算法,非实时内核也通过rthal获得实时内核所用的替代函数,这就为应用双内核机制实现可抢占式内核奠定了基础。
实时内核将各种功能以模块形式实现,在系统运行时可以方便地加载、卸载,从而大大减少核心代码的规模,节省内核空间并方便进行动态配置。图1是双内核结构的嵌入式实时uclinux的体系结构图。可以看出,在rthal架构下实时内核主要由中断分发器和实时调度器构成,这是实时内核最基本的功能。同时还将实时shm、实时fifo、rtcom和sflib设计成模块的形式,可以灵活地根据应用需求进行加载。
实时shm和实时fifo是实时内核任务和非实时内核任务之间的通信桥梁。sflib是浮点运算软件模拟的功能模块,为了解决处理器不支持内核浮点运算而设计的。rtcom则可以提供实时串口通信功能。
图2:实时调度处理流程图。
抢占式内核提供多种实时调度策略,包括fifo、rr、rm、edf算法,同时还允许使用者根据应用需要编写自己的调度算法。任务调度的时机有两种,一种是主动调度,即在程序中主动调用rt_schedule()函数来让出运行权;另一种是被动调度,即在时钟中断处理函数rt_tim
引言:本文提出了一种基于uclinux的实时操作系统,在对于资源要求苛刻而应用场合多变的嵌入式领域很有优势。该系统采用了双内核机制、借助实时硬件抽象层(rthal)概念、利用模块动态加载,对普通uclinux进行了实时性改进,实验表明完全满足实时系统的时限约束。
嵌入式linux以代码开放、价格低廉、功能强大又易于移植的特性正在被广泛应用,为嵌入式操作系统提供了一个极具吸引力的选择。uclinux是专门针对无存储器管理单元(mmu)处理器设计的嵌入式linux,非常适合中低端嵌入式系统的需求,在工业控制领域有着广阔的应用前景。
但许多实际应用要求对外部事件在限定的时间内做出反应,而普通uclinux并不是一种实时操作系统,所以本文提出了一种基于uclinux的实时性解决方案,经测试可以严格满足实时应用的时限约束,有良好的应用价值。
基于uclinux的实时方案分析
1.uclinux实时性缺陷
uclinux虽然符合posix1003.1b关于实时扩展部分的标准,例如支持sched_fifo和sched_rr实时调度策略、实时信号等实时功能,但由于其最初的设计目标为通用分时操作系统,因此在实时性支持方面,uclinux仍存在如下缺陷:
a.非抢占式内核。uclinux有用户态和核心态两种模式,当进程运行在用户态时,可以被优先级更高的进程抢占;在内核中,一个进程可以通过schedule()函数自愿地启动一次调度。除此之外,非自愿的强制调度只能发生在每次从系统调用返回前,或每次从中断或异常处理返回到用户空间前。
b.公平的调度算法。普通uclinux作为一个分时系统,其调度算法的目标是提供一种公平的调度机制,平衡系统响应时间和吞吐量,这与实时应用要求的低延迟和高度的可预测性相矛盾。实时操作系统必须保证目前运行的任务的优先级是可运行任务中最高的。
c.频繁地关中断操作。uclinux为了保证核心数据的完整性,在对关键数据结构进行修改前,通常采用"关中断"的方式。而非周期实时任务大多是由中断作出响应,周期性实时任务也需要调度模块来调度运行,而调度模块的执行也要由时钟中断触发。所以,频繁的关中断会导致实时任务不能被及时调度执行。
d.时钟粒度粗糙。时钟管理是操作系统的脉搏,是进程调度的重要依据。普通uclinux的时钟粒度被设置为10ms,而实时应用一般都需要微秒级的响应精度。
2.uclinux实时解决方案
uclinux支持硬实时性的策略有以下两种:
a.直接修改内核法
将内核中的进程调度、中断处理、时钟等部分遵循posix标准进行改写,在源代码级的基础上使uclinux变成一个实时操作系统。这种策略虽然可以获得高的执行效率,但实现难度大、周期比较长,而且对原有内核太强的依赖性使得升级工作繁重而不方便。
b.双内核方法
在同一硬件平台上采用了两个相互配合、共同工作的系统内核,一个内核提供精确的实时多任务管理,另一个内核提供复杂的非实时通用功能。由于uclinux支持内核模块动态加载,因此实时内核可在需要时以模块的形式载入。双内核机制避免了大规模结构改造,以较小的代价提供了强实时性,新系统可使用几乎所有常规uclinux操作系统提供的功能。
本文提出的嵌入式实时操作系统采用双内核的设计思想,在普通uclinux基础上,通过增加一个实时内核实现了调度的可抢占性,同时在系统中实现了硬件抽象层rthal,避免了频繁关中断所导致的实时任务不能被及时调度执行的缺陷。最后,对系统时钟进行了改进,满足了实时应用微秒级的响应精度。
基于uclinux的实时操作系统设计
1.抢占式实时内核
实时内核完全掌握了硬件层,而把非实时内核作为一个优先级最低的普通任务运行于自己之上。实时内核采用了抢占式调度算法,非实时内核也通过rthal获得实时内核所用的替代函数,这就为应用双内核机制实现可抢占式内核奠定了基础。
实时内核将各种功能以模块形式实现,在系统运行时可以方便地加载、卸载,从而大大减少核心代码的规模,节省内核空间并方便进行动态配置。图1是双内核结构的嵌入式实时uclinux的体系结构图。可以看出,在rthal架构下实时内核主要由中断分发器和实时调度器构成,这是实时内核最基本的功能。同时还将实时shm、实时fifo、rtcom和sflib设计成模块的形式,可以灵活地根据应用需求进行加载。
实时shm和实时fifo是实时内核任务和非实时内核任务之间的通信桥梁。sflib是浮点运算软件模拟的功能模块,为了解决处理器不支持内核浮点运算而设计的。rtcom则可以提供实时串口通信功能。
图2:实时调度处理流程图。
抢占式内核提供多种实时调度策略,包括fifo、rr、rm、edf算法,同时还允许使用者根据应用需要编写自己的调度算法。任务调度的时机有两种,一种是主动调度,即在程序中主动调用rt_schedule()函数来让出运行权;另一种是被动调度,即在时钟中断处理函数rt_tim