linux任务响应模型&linux实时化&RTAI 3.2分析&Adeos分析(3)
- UID
- 1029342
- 性别
- 男
|
linux任务响应模型&linux实时化&RTAI 3.2分析&Adeos分析(3)
RTAI分析
RTAI(Real-Time ApplicationInterface)是对Linux内核的硬实时扩展,它遵循自由软件规范;它可以提供工业级的RTOS功能,而且其所有的功能都可无缝的通过GNU/Linux环境访问。RTAI项目是由意大利米兰理工学院航天工程系(DIAPM)发起开发的遵循GPL的开源项目。
RTAI目前的稳定版本是3.3(以下的分析基于3.2),支持的CPU类型包括I386,PPC和ARM,在ARM类型处理器上的移植官方软件包仅包含对EP9301和PXA255的支持;
目前,基于RTAI已经有了很多的应用,如RTnet,USB4RT,RTCAN等。
RTnet是基于Xenomai和RTAI的开源的硬实时网络协议栈;它使用标准的以太网硬件,并且已经支持流行的网络芯片;它以确定性的方式实现了UDP/IP,ICMP和ARP,并且给内核模块和实时用户进程提供了POSIX套接字接口。
USB4RT的目标是在Linux/RTAI上实现一个具有硬实时能力的USB协议栈;它当前已经实现了核心栈和一个UHCI主机控制器驱动的功能,其将来的工作包括实现各种高层功能和支持EHCI(2.0)。
RTCAN为基于Linux的CAN节点提供了一个实时通讯的框架,通过RTCAN提供的一组功能,CAN消息可以通过RTAI进行发送和接收;RTCAN的重点在于平台的可移植性,它为控制系统的开发者提供了一个强有力的工具。
RTAI为开发硬实时系统提供了丰富的功能,其主要功能如下:
提供多种对实时任务的调度方式,它的调度器分为UP(Uniprocessor),SMP(Symmetric MultipleProcessor和MUP(Multi-Uniprocessor)三类;其中,UP调度器用于单处理器的系统;SMP调度器用于对称的多处理器的系统,所有的CPU使用相同的时钟中断源,也就是说,任务在所有的CPU上都是以相同的模式运行;而MUP调度器也是用于多处理器系统,只不过每个CPU有自己独立的时钟中断源,所以,在不同的CPU上运行的任务可以以不同的时钟模式运行。在这三类调度方式中,时钟运行的模式都有两种,单触发模式(one-shot mode)和周期模式(periodic mode)。
提供了丰富的任务间的通信方法,主要包括邮箱机制(Mailboxe),消息和过程调用机制(Message andRPC),信号量机制(Semaphore),管道机制(FIFO),共享内存机制(Sharedmemory);其中的管道机制和共享内存机制可用于RTAI的实时任务和Linux进程之间的通信。
此外,RTAI还提供了LXRT机制,使得可以在Linux的用户空间创建软实时进程,满足软实时应用的要求。
RTAI还在不断的发展之中,而且它在实时环境中的应用也越来越多,它将来的主要发展方向包括实现更多硬件平台上的移植、为RTAI提供C++开发环境、实时文件系统、对基于Flash的文件系统的支持、高级的实时内存管理机制等。
RTAI在ARM平台上的移植,从3.2版本开始,是基于Adeos实现的,它的硬件抽象层HAL使用Adeos提供的服务。也就是说,RTAI实现了Adeos中的一个域,通过Adeos实现RTAI域的初始化、中断的申请、中断服务程序的注册等。
RTAI在Adoes系统中的域优先级高于Linux域(也就是根域),每当中断到来之后,Adeos先调度RTAI对该中断进行处理、执行中断相关的实时任务,只有当RTAI没有实时任务和中断需要处理的时候,Adeos才会调度Linux运行,这就保证了RTAI的中断响应速度和实时任务不受Linux的影响,从而提供了实时系统的可确定性。图4-1表示了RTAI,Linux和Adeos这三个软件实体之间的相互关系。
如图4-1所示,我们可以把整个实时Linux系统划分成硬件平台、Adeos,RTAI,Linux kernel和Linux应用程序五大部分,可以把各个部分之间的关系归为9类,下面对这9类关系分别作简短的描述,有助于理解整个系统的架构和相互关系。
关系①表示实时任务如何与RTAI提供的实时任务接口相互作用。实时任务(本文所指的实时任务,如果没有特别说明都是硬实时的)都是以Linux内核模块方式实现的,要实现一个实时任务,在模块初始化的时候要调用RTAI的任务创建函数初始化实时任务相关的数据和环境,指定定时器的运行模式(单触发模式或周期模式),初始化定时器,然后开始执行任务;需要注意的是,当没有加载任何RTAI的实时任务模块的时候,RTAI的任务调度和时钟中断都没有启动。
关系②表示实时任务通过RTAI提供的管道(FIFO)和共享内存与Linux用户空间中的进程进行通信,通过这种方式,实时任务获取的实时数据就可以传递到用户空间让非实时进程对数据进行后续的处理。
关系③表示RTAI本身的实现需要用到Linux内核提供的某些功能;例如,RTAI本身(包括各种提供给实时任务的服务模块)是以Linux内核驱动模块的形式存在的,这就需要用到Linux内核的动态内核模块加载功能;另外,RTAI目前的内存管理模块在初始化时是使用Linux的内存分配接口分配足够的内存。
关系④表示传统的Linux内核和Linux用户程序的关系。
关系⑤表示RTAI和Adeos之间的交互。最新的RTAI版本3.2是基于Adeos实现的,RTAI实现了Adeos内的一个域,这个域的优先级高于Linux内核所在的根域,可以保证所有的RTAI中断和实时任务都不会受Linux本身的影响,从而确保快速的中断响应和实时任务的按时完成。
关系⑥表示RTAI和底层硬件之间的交互,当外部事件触发了实时任务之后,实时任务在处理的过程中一般要对外部设备执行某些操作,例如控制采集卡进行数据采集、控制步进电机等。
关系⑦⑧⑨表示Linux、Adoes和硬件平台之间的关系,详细分析将在后面关于Adeos分析的讨论。
RTAI分析(续)
[在阅读RTAI的分析之前,最好先阅读Adeos相关的内容]
-------------
RTAI初始化
RTAI的初始化是由用户动态加载RTAI的硬件抽象层模块rtai_hal.o开始的,涉及到Linux用户空间、Linux域、RTAI域和Adeos,其初始化流程如图4-2。
从图4-2可以看出,RTAI的初始化通过函数__rtai_hal_init完成,这个函数位于rtai-3.2/base/arch/arm/hal/hal.c中,它完成的主要功能包括(注意:RTAI初始化是在根域中完成的,也就是说当前域为Linux):
1.通过调用adeos_alloc_irq分配一个虚拟中断rtai_sysreq_virq,在前面分析Adeos的时候,我们知道虚拟中断可用于域之间的交互,rtai_sysreq_virq就是用于RTAI请求Linux执行某些必须在Linux域内执行的操作。Linux域内处理这个虚拟中断的入口点是rtai_ssrq_trampoline,这是在初始化函数中通过调用adeos_virtualize_irq实现的。
2.用rtai_syscall_trampoline替换Adeos默认的系统调用入口函数adeos_syscall_entry,这是用来处理特殊的RTAI系统调用(与一般的Linux系统调用相比)和实现LXRT(LinuxRealTime,一种通过RTAI在Linux用户空间实现软实时的机制)。
3.调用rtai_proc_register注册RTAI相关的proc文件系统项,通过标准Linux下的proc文件系统提供相关的RTAI系统信息。
4.调用rtai_archdep_init进行一些与硬件体系结构相关的初始化操作。
5.初始化RTAI的属性结构变量,然后调用Adeos的域注册接口adeos_register_domain进行RTAI域的注册,RTAI域实体变量名为rtai_domain。
从前面章节对Adeos域注册的分析,我们知道在域注册的最后,如果新注册的域指定了自己的域初始化函数,Adeos会切换到新注册的域,新域开始运行的时候会调用域本身的初始化函数,RTAI域本身的初始化函数是rtai_domain_entry,位于文件rtai-3.2/base/arch/arm/hal/hal.c中,它完成的主要功能如下(注意,此时的初始化操作都是在RTAI域中完成的):
1.通过adeos_virtualize_irq向Adeos注册RTAI的中断处理函数rtai_irq_trampoline,注册时的处理中断模式掩码为IPIPE_DYNAMIC_MASK,这也就是告诉Adeos不要将中断直接传递给中断管道的下一个低优先级域(在这里就是Linux域),而是由RTAI的中断处理程序来决定是否将这个中断传给下一个低优先级的域(可以通过调用adeos_propagate_irq将中断沿着中断管道向下传播)。
2.通过adeos_catch_event向Adeos注册RTAI的事件和异常处理函数rtai_trap_fault。
3.调用adeos_suspend_domain挂起RTAI域。 |
|
|
|
|
|