首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

实时操作系统到Linux系统的应用移植

实时操作系统到Linux系统的应用移植

从一个操作系统到另一个操作系统应用程序的移植即使在最好的情况下也经常是一个艰巨的任务。把一个实时的嵌入式应用程序移植到一个新的操作系统上可以说是一项最困难的任务。
为了帮助开发人员计划在不久的将来转移到嵌入式Linux上,或者考虑将现有的应用程序运行在嵌入式Linux上这种投资的必要性,Jim 解释了这一转换的过程,评估了涉及到的困难和挑战,并且阐述了认识这种转换的益处。
越来越多的公司正在转向嵌入式Linux,把它作为他们下一代产品的操作系统。然而他们以前都是使用实时操作系统作为他们的嵌入式系统。事实上,VDC的报告显示了嵌入式Linux可以占到32位和64位领域设计的三分之一,是其他所有嵌入式系统的两倍。
很明显,关于从老式RTOS产品的应用程序移植到Linux的可行性的问题必须得到回答,由此这种移植才能够被有效的用于工程管理。
一个典型的基于RTOS的应用程序依赖于很多因素,其中最重要的是编程/内存模型、API、性能、特别是实时响应的能力。另外一个重要的考虑是软件开发环境,但那是软件环境文章值得讨论的话题。
编程模型
几乎所有使用的RTOS有一个简单的编程模型,它由多线程的执行(通常称为任务)构成,包含在单一的地址空间中。举例来说,一个c语言的程序有一个单一的主函数,它创建所有其他的线程。每一个线程依次被定义为总程序中的一个c函数。典型的,不管是RTOS还是非保护内存中的应用程序,他们的物理地址和逻辑地址都是一样的。可能会有一些超级用户模式下的操作使用限制了在用户模式下的应用程序发出一些指令。基本上,所有的内存对于应用程序来说是虚拟的。
在过去,大多数嵌入式处理器没有内存管理单元,因此RTOS单地址空间模式是必须的。然而今天大多数的中高端处理器配备了MMU,因此如果需要的话,MMU能够管理内存。
该体系结构的描述提出了一个移植RTOS代码到Linux上的简单架构。
RTOS的全部应用代码移植到一个Linux单进程
RTOS的任务转换成Linux线程
RTOS的物理地址空间映射到Linux的虚拟地址空间
诸如VME机架的多板或多处理器架构,移植到一个多进程的Linux应用。
构架上的考虑:进程和线程的创建
是否使用遵循API的VXWORKS和PSOS等RTOS仿真软件包,开发人员最终必须决定是否将线程或是进程作为执行RTOS的任务。在这点上,Linux内核对待不管是线程还是进程都是同等的,都是以调度为目的。然而不同的API创建和管理每个实体的类型、性能、资源的成本和益处都是关联的。
通常来说,进程比线程大一点,因为他们传送着更多的上下文信息。一个Linux线程的上下文如同RTOS的一个任务,主要由cpu寄存器、堆栈、当前的程序指针以及一些内核数据结构的入口组成。一个进程加上一个完整的虚拟地址空间。这样,至少内核必须创建和跟踪进程的页转换、所有代码的类型、上下文、数据等。对于重量级进程上下文的主要影响有两点:创建的时间和相互的上下文切换时间。
只要可能,RTOS的代码都会争取要轻量级的执行。同样的,当很多RTOS提供了动态的任务创建API,其他以静态任务定义页表为特色,所有RTOS的商家不鼓励使用频繁的任务创建以节省时间和空间。Linux进程的创建不是故意那么麻烦;Linux进程是重量级的,因为他们提供了更多的保护性和依赖性。
这个熟悉地老式的架构,因为简单,所以非常容易遭受破坏。正在运行的任务能够覆盖应用程序的代码和数据,另外还会写入到外围设备的寄存器、破坏内核的数据结构、覆盖内核代码。任务的堆栈能够很容易的溢出,并且一个接一个被覆盖掉或者通过控制内存来破坏堆的顶部、其他数据或者附近的代码。
更高的层次来说,这种非正式有组织的,高度非遮掩的架构提出了对于代码质量的两个主要挑战:自身的失败机会以及和主要事件再次失败的结合。
当个别任务或者其他软件组件失败了,它失败的原因几乎不可能被定位。甚至当检测到失败并且尝试恢复时候会以整个系统的失败而结束。监视代码不能够经常安全地重启任务,RTOS不能够恢复由失败任务动态定位的资源。结果就是复位通常是通过强制使用看门狗定时器来完成的,看门狗定时器重新启动整个系统或者软件引起的系统错误。
通常当一个程序跑飞了,它没有任何征兆。一个错误的任务能够破坏在RTOS系统中任何地方的数据和代码。幸运的是,虽然这些破坏的影响瞬间产生,但是好像破坏的影响会在几秒、几小时、几个月以后才会出现。
当异常的征兆出现了,去联想预想不到的应用程序行为是及其困难的,这些行为由于原始的原因或者是很微小的,或者是破坏性的。
Linux编程模型的内部编译的可靠性
Linux作为一个unix兼容的操作系统代表着一个更加强大的应用和系统编程模型。应用程序执行在他们受保护的地址空间,因为它们之间的地址相互是不可见的,并且它们通过硬件的MMU来预防覆盖掉他们自己的代码,MMU出现在多数现代化的32位64位的处理器中。
当他们共享Linux内核的虚拟地址空间时,他们不能够覆盖内核代码或数据。既然进程不能够相互看到,他们就不能够相互破坏数据或代码
API和实时库
在开源标准以前,RTOS的制作者定义了他们自己的系统调用或API,这对于每个RTOS的制作者来说都是独一无二的。接口函数是为流行的编程语言而提供的,诸如c、c++,这使得API函数对于使用高级语言的程序员是合适的。
在过去的十年中,尽管只有POSIX规范的一部分和嵌入式应用程序相关,大多数的RTOS制作者还是给标准的POSIX提供了兼容库。很多客户使用他们自己的API集使本地RTOS接口分层以获得独立性和便捷性,而不是想被锁定成为一个私有的特殊版权的接口。
开发人员使用标准的API建立应用程序来获得两个另外的目的:允许代码被移植成像Linux那样的标准操作系统以及允许以后同样的代码在这样的一个环境下比使用私有的API更加容易移植。
很多包括标准调用的商业RTOS以POSIX或者BSD来设定,但是那些API经常只存在于windows下。特别是一个内核私有的API是最常被使用的,就是这些API锁定了项目到一个特殊的平台或者解决方案。
如果开发人员正在移植标准的代码或者考虑哪个API运用到新的代码中,那么理解在Linux和其他操作系统中使用的最普遍的标准是非常重要的。
返回列表