电子说
随着软件功能的日趋强大,软件开发工作量随之剧增,软件开发团队也不断尝试改进软件的开发方法,旨在保证软件功能,质量的情况下,减少成本,加快开发速度。
要实现上述目标,关键在于工作量——在软件开发中尽可能减少工作量。
软件开发相关的工作量包括功能需求定义,功能需求的实现和测试,非功能需求,以及修复开发过程中引入的错误的工作量。
站在软件开发者的角度,在实现软件完整功能的情况下,如何减少开发的总工作量,唯一能够减少的部分就是用于修正错误的工作量。
对软件开发而言,一旦发现错误,就必须加以修正,以保证软件产品质量。因此,要在不影响产品质量的前提下减少工作量,唯一的解决办法就是防止开发过程中引入软件错误。
在已知的软件错误中,内存安全是软件行业中最常见的错误类别[1][2]。然而,嵌入式软件行业的标准语言 C 和 C++ 是非内存安全编程语言,这意味着嵌入式系统很容易出现这类错误。
减少这类错误的方法之一是在软件测试、审查和验证方面投入人力物力,而另一种思路是用内存安全语言取代现有语言[3]。
虽然许多内存安全语言(如 Python、Java)已在软件行业得到广泛应用,但它们并不适合嵌入式系统。这是因为嵌入式系统对占用空间、堆栈使用和性能有严格的限制(这是C和C++的优势)。
Rust就是在这样的背景下诞生的,它同时实现了高效性和内存安全。
Rust 是什么
Rust语言在2006年作为 Mozilla 员工 Graydon Hoare 的私人项目出现,而 Mozilla 于 2009 年开始赞助这个项目。第一个有版本号的 Rust 编译器于2012 年 1 月发布。Rust 1.0 是第一个稳定版本,于 2015年5月15日发布 [4] 。
Figure 1. Rust Logo
Rust是一种在科技界大受欢迎的语言,Rust已经连续七年(2016,2017,2018,2019,2020, 2021, 2022)在Stack Overflow开发者调查的“最受喜爱编程语言”评选项目中折取桂冠[5]。
微软用Rust重写它的一些核心windowns库,在 Android 13 中,21% 的新原生代码使用了 Rust,此外,除 C 语言外,Rust 是唯一一种支持编写 Linux 内核组件的语言,并被广泛用于后端软件、基础设施和微服务。(找元器件现货上唯样商城)
Figure 2. rust-gentle-intro [6]
Rust是一种系统编程语言,旨在成为无垃圾回收的内存安全语言。
Rust使用了包含特定规则的“所有权”机制来管理内存,允许编译器在编译过程中执行检查工作,而不会产生任何的运行时开销。Rust中的每一个值都有一个对应的变量作为它的所有者;在同一时间内,值有且仅有一个所有者;当所有者离开自己的作用域时,它持有的值就会被释放掉。
Rust使用“借用规则”实现对值进行可变和不可变引用:一个值可以有一个不可变引用或多个可变引用,但不能同时有两个引用。编译器中一个名为“借用检查器”的特定部分会对此进行检查。
Rust中的生命周期规则:Rust的每个引用都有自己的生命周期,它对应着引用保持有效性的作用域。生命周期最主要的目标在于避免悬垂引用,进而避免程序引用到非预期的数据。[7][8]
Cargo 是 Rust 的软件包管理器[9],软件包被称为板条箱(Crate),cargo 有一个命令:cargo build,它能自动解决项目依赖关系。另外,使用 cargo test 命令能触发单元测试,使用 cargo doc 命令还能生成文档网页。cargo 的文档列出了 30 多条不同的命令,用于支持软件包处理、构建文档和测试。此外,cargo 还可用于安装其他 Rust 二进制文件,如工具 svd2rust。
嵌入式系统中的 Rust
Figure 3. Embedded Rust Architecture
Embedded Rust 的结构可以分为上述5层,如上图所示,从下往上的顺序,最底层是MCU硬件层,有各个资源,外设,由不同的芯片决定;第2层是PAC,可以理解为芯片的头文件,里面是各个寄存器的信息;第3层是在PAC的基础上对寄存器进行操作一些调度函数,里面对寄存器进行直接操作;第4层是硬件抽象层,这一层的意义是从芯片强相关的驱动函数上抽象出来,提供一个通用接口,这个通用接口由最上层的软件驱动层、软件应用层去调用,实现对芯片资源的调度。
在Embedded Rust中,使用svd2rust工具将芯片资源的描述文件SVD文件转化为PAC,该接口具有良好的可读性,便于审查和维护。此外,它还能防止出现错误,因为如果设置的值对该字段无效,代码将无法编译。
RUST 与 C 语言的关系
Rust对硬件的内存需求,堆栈使用,运行效率可以和C相媲美,具体的细节差异会和编译优化等级,应用等有些许差异。
此外,Rust有一个令人振奋的点,它可以和C语言共同使用。
Rust和C代码间的互用性始终取决于两种语言间的数据转换。为了实现互用性,在stdlib中,有两个专用模块,叫做std::ffi和std::os::raw 。
std::ffi提供了一些工具去转换更复杂的类型,比如Strings,将&str和String映射成更容易和安全处理的C类型。
std::os::raw处理底层的基本类型,这些类型可以被编译器隐式地转换,因为Rust和C之间的内存布局足够相似或相同[10]。
Rust 是一种现代系统编程语言,可用于网络应用程序和裸机嵌入式系统。不过Rust的生态和函数库资源等比较有限,而和C之间的互通性可以让Rust更加便捷的应用到现有的软件中,更快的投入使用。
因此,我们将长期生活在 Rust 和 C 语言的混合环境中。尽管 Rust 声称内存安全(这一点已经得到证实),但是Rust 和 C 代码的结合可能会导致安全的 Rust 生成的程序被不安全的 C 实现所违反的情况。为了确保 Rust 的安全性,有必要在 C 和 Rust 之间找到一个合理的分界点。
尽管如此,事实证明 Rust 是在嵌入式系统中替代 C 和 C++ 的合适候选语言,尤其是在新代码开发方面。除内存安全外,Rust 语言的其他方面,如强大的类型系统和错误处理,也为 Rust 带来了卓越的可读性和可维护性。这提高了防错能力,从而在不增加开发阶段额外成本的情况下实现更安全的代码。
英飞凌产品支持Embedded Rust
软件安全对汽车市场至关重要,Rust 编程语言内置内存安全软件开发支持,是设计关键任务汽车软件的重要推动力。英飞凌科技公司为在嵌入式领域创建 Rust 生态系统迈出了第一步。首先推出的是市场领先的 AURIX™ TC3xx 和 TRAVEO™ T2G 汽车 MCU。TRAVEO™ 使用官方 Rust 工具链和 Arm Cortex-M 目标编译器,而英飞凌的工具合作伙伴 HighTec EDV-Systeme 则为 AURIX™ 开发了专用 Rust 编译器。
Figure 4. AURIX™ and TRAVEO™ T2G
AURIX™ TC3xx 和 TRAVEO™ T2G 微控制器产品系列为功能安全和网络安全提供了广泛的集成硬件功能。对 Rust 的支持是对这些硬件功能在软件方面的补充。英飞凌为 AURIX™ 和 TRAVEO™ 提供了外设访问板条 (PAC),以实现对微控制器外设的本地访问。
HighTec Rust 编译器专为 AURIX™ TC3xx 和 TC4x 微控制器量身定制,利用先进的开源 LLVM 技术,为具有安全、可靠、高性能和快速部署要求的应用提供全套 Rust 语言特性,包括内存安全、并发性和互操作性。
审核编辑 黄宇
全部0条评论
快来发表一下你的评论吧 !