一、引言
在航空航天领域蓬勃发展的当下,新太空公司与无人机企业不断涌现,市场竞争愈发激烈,这使得新航空电子系统的开发时间被迫大幅缩短。为了在快速变化的市场中立足,商业现成(COTS)计算系统在航空电子设备中的应用日益广泛。这些系统通常配备更强大但也更复杂的硬件,例如具有(异构)多核架构的片上系统(SoC),其不仅能为外部设备提供丰富多样的接口,还拥有足够的计算资源来运行复杂的航空电子算法与精密的用户应用程序。然而,硬件复杂度的提升以及功能需求的增加,给软件开发带来了前所未有的挑战,现有的开发方式亟待改进。
编程语言在软件开发中起着核心作用。目前,C/C++凭借其在航空电子领域长期积累的优势,构建起了庞大且成熟的开发生态系统,在航空电子软件开发中占据主导地位。但随着技术的发展,新的编程语言不断涌现,Rust就是其中备受瞩目的一员。Rust自2009年由Mozilla Research开发,2015年发布首个稳定版本1.0,如今已在众多领域得到应用。其独特的语言特性,如增强的内存安全性和出色的并发处理能力,与航空电子软件对安全性和可靠性的严格要求高度契合,这使得Rust在航空电子软件开发领域展现出巨大的潜力。
本文将深入探讨Rust在航空电子软件开发中的可行性。通过分析Rust在各领域的应用现状,明确航空电子软件对新编程语言的关键需求,并详细介绍将Rust移植到航空航天常用实时操作系统RTEMS的过程,依据既定需求评估Rust的表现,进而总结Rust在航空电子软件开发中的优势与挑战,展望其未来发展方向,为航空电子软件开发人员提供有价值的参考,助力行业探索更高效、可靠的开发方案。
二、Rust的发展与应用现状
2.1 Rust的起源与发展历程
2009年,Rust在Mozilla Research诞生,最初它主要聚焦于提升Firefox浏览器的性能和安全性。经过多年的开发与完善,2015年,Rust 1.0版本正式发布,标志着其走向成熟。此后,Rust的发展势头愈发强劲,2021年,开发工作移交至Rust Foundation,该基金会承担起维护和推动Rust未来发展的重任。
2.2 Rust在不同领域的应用情况
如今,Rust的应用领域极为广泛。在系统编程方面,它已成功融入Linux内核开发,为内核的稳定性和安全性贡献力量;在Android操作系统中,Google宣布采用Rust进行内核和驱动开发,这进一步拓展了Rust在移动操作系统领域的应用。
在物联网(IoT)领域,Rust同样备受关注。随着智能家居等IoT设备的普及,设备安全成为关键问题。由于常见的内存安全问题常常为安全攻击提供可乘之机,而Rust在内存安全方面的出色表现,使其成为开发安全可靠IoT应用的理想选择。例如,相关研究通过额外测试、工具以及采用Rust编程等方式,有效预防了C语言开发应用中的内存安全问题。
在安全领域,Prossimo项目致力于使用Rust实现常见互联网协议,以替代当前C语言的实现,为互联网行业的安全发展注入新动力。同时,网络安全社区也积极研究Rust在安全方面的优势,深入评估其对提升软件安全性的作用。
在汽车行业,AUTOSAR联盟成立了Rust工作组,并发布了关于Rust代码与AUTOSAR软件平台API绑定的文档。AdaCore和Ferrous Systems等公司更是依据ISO26262标准开发出认证的Rust编译器,还提供依据其他行业标准(如ECSS和DO-178C)的认证服务,推动Rust在汽车软件开发中的应用。
在航空航天领域,欧洲航天局(ESA)资助了多项与Rust相关的活动,深入研究Rust在软件开发各环节的可行性、应用方式以及开发软件的验证方法。然而,目前航空业对Rust作为关键系统编程语言的研究相对较少,实际项目应用案例也较为稀缺,这也为后续研究留下了广阔的空间。
三、航空电子软件对新编程语言的需求
3.1 航空电子软件开发的现状
当前,航空电子软件开发领域呈现出以C/C++为主导的格局。多数硬件供应商提供的软件开发工具包(SDK)和板级支持包(BSP)都基于C语言;控制算法的代码生成工具也通常将C或C++作为首选语言,并遵循特定的编码标准,如C语言的MISRA-C标准、C++的AUTOSAR标准;常见的航空航天操作系统大多使用C语言编写;飞行软件的手动代码也多采用C或C++。对于可靠性和安全性要求极高的系统,如商用客机和载人航天系统,则会选用Ada语言,因其编译器执行更为严格的编码规范和广泛的编译时检查。这种现状使得C语言在航空电子软件开发中积累了丰富的资源,包括编码指南、工具、库、文档以及商业和开源的供应商支持。
3.2 新编程语言的关键需求
在这样的背景下,一种新的编程语言若想在航空电子软件开发领域立足,必须满足一系列严格的要求:
- 目标平台支持(REQ1):航空电子软件运行于搭载实时操作系统(RTOS)的机载计算机上,因此新编程语言需获得编译器对常用目标硬件架构和操作系统的支持,特别是那些已在相关领域通过认证的系统。例如,在航天领域广泛应用的RTEMS RTOS,以及在航空航天行业常用的VxWorks和QNX等RTOS。
- 与C代码的互操作性(REQ2):鉴于C语言在航空电子软件中的主导地位,新编程语言必须能够与现有的C代码轻松互操作,即可以相互调用,这需要遵循通用的调用约定。
- 低性能开销(REQ3):航空电子软件运行于实时环境,对性能要求苛刻。新编程语言应具备与C相当的性能,且性能稳定,通常不适合采用垃圾回收机制,因为垃圾回收可能产生难以预测的延迟。
- 底层硬件接口编程能力(REQ4):航空电子软件常涉及对底层硬件接口的操作,新编程语言应具备通过寄存器访问编写驱动程序的能力,以满足嵌入式设备软件开发的需求。
- 实用的语言特性(REQ5):新编程语言需为开发者提供实际的益处,如具备有助于避免常见编程错误(如内存访问违规和并发竞争条件)的语言特性,具备更好的可维护性,能够更轻松地开发高质量代码。这一要求相对灵活,因不同语言而异,它更侧重于开发者是否愿意使用该语言。
- 跨领域应用(REQ6):航空航天行业的软件开发规模相对较小,新编程语言若仅在航空航天领域使用,将难以发展壮大。拥有广泛的跨领域用户基础,有助于该语言在工具改进、文档完善以及人才储备方面积累优势,为航空航天行业所利用。
这些需求不仅是评估Rust在航空电子软件开发适用性的重要依据,也为其他有意进入该领域的新编程语言设定了标准。
四、将Rust移植到RTEMS的尝试
4.1 RTEMS操作系统概述
RTEMS是一款在太空任务中广泛应用的实时操作系统,遵循BSD3开源许可证。它的部分API包含在RTEMS资格数据包(QDP)中,该数据包是ESA资助项目的成果,旨在对RTEMS API的稳定子集进行预认证,以便用于安全关键应用。RTEMS提供了轻量级的Classic API和符合POSIX标准的API,支持单进程多线程执行模型,能够适配多种硬件架构和BSP,并具备多种实时调度器,如速率单调调度、基于优先级的抢占式调度以及多核系统的对称多处理调度。
RTEMS的工具链基于GCC交叉编译器和newlib嵌入式C库。在构建过程中,操作系统源代码通过交叉编译器针对目标平台进行编译,生成静态库和相应的头文件。构建可执行文件时,至少需要一个包含主程序入口点和操作系统配置的C源文件,通过编译时定义进行操作系统配置,静态分配所需资源,最终将该源文件与其他兼容对象和操作系统静态库链接成可在目标平台运行的二进制可执行文件。
4.2 Rust编译器结构剖析
Rust编译器在其Github仓库中进行开发,仓库不仅包含编译器源代码,还涵盖了一系列相关库,如core、alloc和std。这些库包含了与操作系统和部分硬件架构相关的功能实现。例如,在多线程实现方面,针对类Unix操作系统,使用POSIX pthread API,而对于其他操作系统,则采用不同的线程模型。通过适当的编译时配置,Rust编译器能够为不同的目标平台选择正确的代码路径。此外,Rust标准库依赖于libc项目,该项目声明了底层操作系统C API的实际C类型和函数原型,共同为自定义Rust代码的编译和高级功能的运行提供支持。
4.3 为RTEMS添加Rust支持的实现
记录的原型移植选择AMD Zynq 7000作为参考硬件平台,其对应的BSP在RTEMS中得到良好支持,并且可通过Qemu进行仿真,方便移植过程中的调试工作。其他硬件架构可复用与RTEMS相关的移植部分,仅需针对不同硬件架构添加少量特定代码。
为RTEMS添加Rust支持的首要目标是将Rust源代码编译为可与操作系统库链接的兼容目标代码。最初考虑直接为GCC交叉编译器添加Rust语言支持,就像对其他语言(如C++、Fortran、Ada)所做的那样,有项目正在致力于开发GCC的Rust前端,但目前仍处于早期阶段,不够成熟,暂无法深入研究。
因此,采用将Rust编译器与RTEMS交叉编译器结合使用的方法。具体而言,两个编译器分别将各自的源文件编译为兼容的目标文件,然后通过链接生成最终的可执行文件。在这个过程中,确保GCC和rustc的目标特定编译标志匹配以生成ABI兼容的对象至关重要,但由于两个编译器设置标志的表示法不同,这一过程具有一定难度。若在Rust中正确声明C函数,即可从Rust调用C函数;同理,在C中通过extern声明Rust函数并确保类型兼容,也可从C调用Rust函数。这种方法的优点是仅需配置正确的Rust目标标志,无需在Rust编译器仓库中添加与操作系统相关的代码;缺点是Rust运行时无法使用操作系统基础设施,导致Rust应用代码的开发不能依赖Rust标准库,许多高级功能(如线程、高级字符串操作与格式化、文件和I/O操作、系统时间函数以及堆分配数据结构)无法使用,在一定程度上限制了Rust在项目中的应用。
为解决上述问题,进一步将Rust标准库移植到RTEMS,使Rust能够感知其运行的操作系统。具体操作包括在Rust编译器源代码中添加RTEMS到支持的操作系统列表,添加捕获硬件相关设置(如编译标志)的特化文件,并实现标准库函数。由于RTEMS与POSIX的兼容性,Rust标准库中的许多现有实现可通过适当的编译时开关复用。同时,还需将相应的与操作系统和硬件相关的API类型和函数原型添加到libc中,这些原型分布在RTEMS源代码和底层newlib C库中。
完成上述步骤并修复Rust编译器对更新版本libc的依赖后,成功为RTEMS编译出具有支持功能的Rust编译器。借助Rust构建系统cargo的构建脚本功能,能够编译简单示例应用的C和Rust代码。最终生成的二进制文件在仿真目标上运行,验证了示例应用和单元测试的正确执行。此次移植成果被添加到Rust项目的官方源仓库中,新增了Tier 3目标armv7 - rtems - eabihf并公开可用。
五、Rust在航空电子软件开发中的表现评估
5.1 对各项需求的满足情况分析
依据前文提出的航空电子软件对新编程语言的六项需求,对Rust进行评估:
- 目标平台支持(REQ1):Rust编译器基于llvm作为后端,具备为几乎所有相关目标平台自动生成机器代码的能力,支持不同硬件平台的编译。通过将Rust标准库移植到特定操作系统,如已对VxWorks、QNX和本次的RTEMS进行的移植,可实现对相应操作系统的支持。不过,目前这些操作系统的移植版本均处于Tier 3级别,未纳入Rust持续集成流水线的常规质量控制,意味着Rust社区不保证平台的预期运行效果以及编译器代码变更不影响现有功能。对于QNX 7.10版本,已有针对aarch64和x86_64硬件目标的合格编译器,但尚未依据航空航天行业标准进行认证;VxWorks和RTEMS目前也未获得相关认证,但这并不妨碍基于这些RTOS进行Rust软件开发。
- 与C代码的互操作性(REQ2):Rust借助其Foreign Function Interface(FFI),能够与现有C代码实现双向互操作。但目前Rust无法直接调用C++库,需要C语言作为中间层进行封装。
- 低性能开销(REQ3):Rust的许多语法特性通过零成本抽象实现,在编译时进行评估,不会增加应用程序的运行时开销。作为一种无垃圾回收机制且基于llvm后端的编译型语言,Rust在计算性能上可与类似的C应用程序相媲美。
- 底层硬件接口编程能力(REQ4):自2018年Rust嵌入式工作组组建以来,Rust对嵌入式系统的支持不断增强。虽然需要使用unsafe Rust,但开发者能够进行底层寄存器访问和驱动程序开发。
- 实用的语言特性(REQ5):相较于C语言,Rust提供了一系列独特的语言特性。例如,matches语法比简单的switch语句功能更强大,有助于更灵活地处理控制流;其错误处理系统和可选类型在处理意外情况时,能够实现更丰富的信息流。Rust最具特色的特性当属生命周期和所有权规则,它们能够在编译时捕获常见的C语言错误(如悬空指针和竞态条件),而无需额外工具辅助。在工具方面,cargo作为统一的构建系统,不仅提供了通用的用户界面,还对项目源代码结构起到引导作用,能够自动解决依赖问题,这是C/C++开发需要借助第三方工具才能实现的功能。同时,cargo也是编译和运行单元测试的入口,相比C/C++,Rust无需外部框架即可完成此项工作。不过,这些特性对于从C语言转向Rust的开发者而言,需要一定的适应过程。
- 跨领域应用(REQ6):在跨领域应用方面,Rust比Ada更为成功。Rust不仅积极应用于安全加密库的实现,还成为Linux内核官方支持的语言之一,与C语言共同为内核开发贡献力量。在其他领域,Rust也有诸多应用案例,这为其在航空航天领域的发展提供了有力的支持。
5.2 与Ada语言的对比
Ada语言同样满足航空电子软件开发的多项关键需求,它在编译时执行严格的检查,具备强大的类型系统和异常处理机制,能够有效保障软件的安全性和可靠性,这也是其在航空航天领域被广泛应用于开发安全关键系统的原因。然而,在跨领域应用的普及程度上,Rust凭借其在多个行业的广泛应用,展现出比Ada更强大的发展势头。这意味着Rust在工具生态系统、社区支持以及知识共享等方面可能具有更大的优势,更有利于吸引不同领域的开发者参与到航空电子软件开发中,为行业带来新的思路和创新。
六、Rust在航空电子软件开发中的优势与挑战
6.1 优势
- 内存安全与可靠性:Rust的所有权和生命周期机制从根本上解决了许多常见的内存安全问题,如悬空指针、内存泄漏和数据竞争等。在航空电子软件这样对安全性和可靠性要求极高的领域,这一特性尤为重要。它能够在编译阶段发现潜在的内存错误,减少运行时错误的发生,提高软件的整体质量和稳定性,降低因软件故障导致的航空事故风险。
- 并发编程支持:随着航空电子系统中多核处理器的广泛应用,并发编程变得越来越重要。Rust提供了丰富且安全的并发编程原语,如线程、通道和互斥锁等,使得开发者能够轻松编写高效且安全的并发代码。这有助于充分利用多核处理器的性能优势,提升航空电子系统的实时处理能力,例如在处理多个传感器数据或执行复杂的飞行控制算法时,能够更快速、准确地响应。
- 语言特性提升开发效率:Rust的语法特性,如强大的模式匹配、闭包和迭代器等,使代码编写更加简洁、高效。模式匹配功能能够方便地处理复杂的数据结构和条件判断,减少冗长的if - else语句;闭包和迭代器则为数据处理和算法实现提供了更灵活、直观的方式,提高了代码的可读性和可维护性。此外,Rust的类型系统虽然严格,但通过类型推导等机制,减少了开发者编写冗余类型声明的工作量,进一步提升开发效率。
- 跨平台支持与可移植性:基于llvm后端的Rust编译器能够支持多种硬件架构和操作系统,为航空电子软件开发提供了极大的便利。无论是在传统的航空电子硬件平台,还是新兴的异构多核系统上,Rust都能够进行高效的开发。并且,通过将标准库移植到不同的操作系统,Rust能够在各种实时操作系统(如RTEMS、VxWorks和QNX)上运行,增强了软件的可移植性,降低了跨平台开发的成本。
- 活跃的社区与生态系统:Rust拥有一个庞大且活跃的社区,开发者们积极贡献代码、分享经验,并开发了丰富的库和工具。在航空电子软件开发中,开发者可以借助社区的力量,快速获取解决问题的方案,复用已有的高质量库,加速项目开发进程。同时,社区的活跃也意味着Rust语言和相关工具会持续得到改进和优化,更好地满足航空电子软件开发的需求。
6.2 挑战
- 资格认证问题:在航空电子领域,软件需严格遵循行业标准进行认证,如DO-178C或ECSS。目前虽有针对特定目标的合格Rust编译器,但尚未依据这些关键的航空航天标准进行认证。对于RTEMS而言,其POSIX API尚未纳入QDP,若要构建完全合格的工具链,要么将POSIX API添加到QDP,要么重写RTEMS移植部分以依赖Classic API。即便拥有合格工具链,用Rust编写的源代码也需与C代码遵循相同标准进行认证。然而,从Rust代码生成必要证明和指标的经验相对匮乏,这使得早期采用者需投入额外工作。同时,还需要具备相关知识的审核人员对Rust代码进行评估,这些前期投入可能会阻碍Rust在实际项目中的应用。
- 与现有代码集成难题:尽管Rust可通过FFI与C代码互操作,但与C++代码直接交互存在困难,需借助C语言编写包装代码。由于C++ ABI未定义且依赖特定编译器,这一问题在其他编程语言与C++交互时也普遍存在。在大型航空电子项目中,代码库通常包含大量C++代码,Rust与这些代码集成的复杂性增加了项目的开发和维护成本,限制了Rust在现有项目中的快速推广。
- 语言学习曲线陡峭:Rust的所有权、生命周期和借用等概念对于习惯C/C++编程的开发者来说较为陌生,理解和掌握这些概念需要花费一定时间和精力。此外,Rust的错误提示信息虽然详细,但对于初学者可能过于复杂,难以快速定位和解决问题。在航空电子软件开发团队中,让开发者熟练掌握Rust语言,需要投入额外的培训资源和时间成本,这在一定程度上影响了Rust的推广速度。
- 部分功能缺失:在实时调度方面,Rust核心语言虽提供线程创建和同步功能,但缺乏线程优先级分配和线程亲和性设置功能,这在航空电子软件中常用的基于优先级的调度场景中是关键缺失。尽管可通过调用底层C函数或使用外部库来实现,但这些解决方案的可靠性和通用性仍需验证,能否满足嵌入式RTOS上航空电子软件的需求有待进一步研究。此外,目前Rust标准库在某些特定航空电子应用场景下的功能可能不够完善,开发者可能需要自行实现或寻找第三方库来补充,增加了开发的复杂性。
- 生态系统适配问题:航空电子软件开发依赖特定的工具、库和开发流程。虽然Rust拥有丰富的生态系统,但与航空电子领域现有的成熟生态系统(如C/C++相关的工具链、代码生成器和测试框架)相比,在功能和适配性上存在差距。例如,现有的航空电子代码生成工具大多针对C/C++,直接用于Rust开发存在困难;Rust的测试框架在满足航空电子软件严格的测试要求方面,可能需要进一步扩展和定制。将Rust生态系统与航空电子领域现有生态系统进行有效融合,是Rust在该领域广泛应用面临的挑战之一。
七、未来发展方向与建议
7.1 针对挑战的解决方向
- 加快资格认证进程:航空航天行业组织、Rust社区以及相关企业应加强合作,制定针对Rust的航空航天标准认证路线图。投入资源研究如何依据DO-178C或ECSS等标准对Rust代码和工具链进行认证,建立相应的认证流程和方法。同时,鼓励在实际项目中开展Rust代码认证的试点工作,积累经验,推动Rust在航空电子领域的全面认证。
- 优化与现有代码集成方案:Rust社区可致力于开发更高效、易用的C++与Rust交互工具和技术,简化包装代码的编写过程,提高集成效率。例如,开发自动生成包装代码的工具,减少手动编写的工作量和出错概率。在项目实践中,探索更合理的代码架构设计,将Rust代码与现有C++代码进行有效分离和整合,降低集成的复杂性,提高系统的可维护性。
- 降低学习门槛:为帮助航空电子开发者更好地学习Rust,应提供更多针对该领域的学习资源,如专门的教程、案例分析和培训课程。在教程编写中,结合航空电子软件开发的实际场景,深入浅出地讲解Rust的核心概念和应用方法。同时,优化Rust编译器的错误提示信息,使其更直观、易懂,帮助开发者快速定位和解决问题,缩短学习周期。
- 完善语言功能:对于Rust在实时调度功能上的缺失,社区可通过官方RFC(Request for Comments)机制,推动在语言层面添加线程优先级分配和线程亲和性设置等功能。在等待语言层面改进的过程中,加强对现有外部库的评估和优化,确保其在航空电子软件中的可靠性和稳定性。此外,持续完善Rust标准库,针对航空电子应用场景的特殊需求,增加相关功能和接口,提高语言的适用性。
- 适配航空电子生态系统:Rust开发者和航空电子行业从业者共同合作,对Rust生态系统进行定制和扩展,使其更好地适配航空电子开发需求。例如,开发与航空电子代码生成工具兼容的Rust插件,将Rust的构建工具与现有的航空电子开发流程进行整合。同时,借鉴航空电子领域C/C++生态系统的成熟经验,建立适合Rust的代码规范、测试标准和质量保证体系,促进Rust在航空电子领域的生态发展。
7.2 结合行业趋势的发展建议
- 拥抱新兴技术趋势:随着航空航天技术的不断发展,人工智能、机器学习和大数据等技术在航空电子领域的应用逐渐增多。Rust在这些新兴技术领域也展现出一定的潜力,例如在处理大规模数据和实现复杂算法时,Rust的高效性能和内存安全特性具有优势。航空电子开发者应积极探索Rust在这些新兴技术场景下的应用,结合行业需求,开发新的算法和应用程序,推动航空电子系统的智能化发展。
- 强化安全与可靠性研究:安全和可靠性始终是航空电子软件的核心要求。Rust虽在内存安全方面表现出色,但在航空电子领域复杂的运行环境下,仍需进一步研究其安全性和可靠性。例如,开展针对Rust在航空电子系统中面对极端环境(如辐射、高温、强电磁干扰等)时的可靠性测试;研究如何利用Rust的语言特性实现更高级别的安全机制,如形式化验证等,以满足航空电子软件日益增长的安全需求。
- 推动开源项目发展:开源项目在Rust的发展过程中发挥了重要作用,在航空电子领域同样如此。鼓励开发者和企业参与航空电子相关的Rust开源项目,共享代码和经验,形成社区合力。通过开源项目,加速Rust在航空电子领域的应用创新,促进技术的快速传播和发展。同时,建立开源项目的质量保证和维护机制,确保开源代码的可靠性和可持续性,为航空电子软件开发提供稳定的技术支持。
- 加强跨行业交流与合作:Rust在多个行业都有应用,航空电子领域可借鉴其他行业的成功经验。加强与汽车、医疗等同样对软件安全性和可靠性要求较高行业的交流,了解他们在使用Rust过程中的实践经验和遇到的问题,共同探索解决方案。此外,与硬件厂商密切合作,推动Rust与新型硬件架构的适配和优化,充分发挥硬件性能优势,提升航空电子系统的整体性能。
八、结论
Rust在航空电子软件开发领域展现出显著的潜力和优势,其内存安全、并发编程支持、丰富的语言特性以及跨平台能力等,为解决航空电子软件开发面临的挑战提供了新的思路和方法。通过将Rust移植到RTEMS的实践,证明了为Rust编译器添加新目标平台支持是可行的,且Rust能够与现有C代码进行有效的互操作,为在现有航空电子项目中逐步引入Rust奠定了基础。
然而,Rust在航空电子领域的广泛应用仍面临诸多挑战,如资格认证、与现有代码集成、语言学习难度、部分功能缺失以及生态系统适配等问题。要实现Rust在航空电子软件开发中的全面应用,需要航空航天行业组织、Rust社区、企业和开发者共同努力。通过加快资格认证进程、优化集成方案、降低学习门槛、完善语言功能、适配生态系统,并积极拥抱新兴技术趋势、强化安全可靠性研究、推动开源项目发展和加强跨行业交流合作,逐步克服这些挑战,使Rust成为航空电子软件开发的有力工具,为航空航天行业的发展注入新的活力,推动航空电子系统在安全性、可靠性和性能方面的持续提升。