为什么 Rust 实际上对您的汽车有好处。
这篇文章是对我们的嵌入式 Rust 先驱之一 Julius Gustavsson 的采访,他是沃尔沃汽车公司的技术专家和系统架构师。
JF = Johannes Foufas(采访者),JG = Julius Gustavsson(采访者)。
JF:你是如何发现 Rust 的?
JG:我想这是在 2014 年,那时我已经从事 C 和 C++ 15 年了。我在一家大型瑞典科技公司的一个新团队中工作。他们有相当先进的代码风格,他们为自己的代码库感到自豪。它看起来真的很好。你知道,我很高兴能开始在那里工作,但是,你瞧,我正在调试和以前一样的模糊内存问题。
我突然想到一个想法,这是最好的吗?
这就是我的职业生涯吗?
我要为此度过余生吗?
有趣的是,我认为是在同一周或之后的一周,我看到了这篇 Reddit 帖子,他们正在接近最后的 Rust 1.0 版本。显然,它仍然符合其最初的主张,这是我在 2009 年左右第一次发现 Rust 时发现的。
Julius to the left, Johannes to the right
从那时起,我就在场外关注了 Rust 项目。几年后当我来到沃尔沃汽车时,我已经被它所吸引,我认为这对沃尔沃汽车很有用,因为它体现了您在开发安全关键型软件时想要的相同类型的意识形态。你真的很想在前面有质量。
JF:这就是我们最挣扎的地方,那些晦涩难懂的错误。它们不会经常发生,但是当它们发生时,就会很痛苦。
JG:是的,当然。
JF:你当时是私下编写 Rust 代码还是?
JG:没什么大不了的。但是当我开始在沃尔沃时,我的第一个项目是在我们的原型版本上与我们的 Signal Broker 进行 Android 集成。 核心计算机 .它是一种面向代理的硬件抽象层 (HAL),它本身是用 Elixir 编写的。我使用 Rust 和 async Futures 做到了这一点。这也是一个很大的确认,这确实是有用的东西。一切从一开始就有效。我的意思是,一旦你得到它来构建它通常在你运行它时总是有效的。当然,它不能解决您实现中的任何逻辑错误。但是,如果您的逻辑检查通过,它就会在编译后立即神奇地工作。但是,有时您当然可能很难编译它,尤其是当您尝试做编译器认为错误的事情时。
JF:从那以后你变得更严肃了?
JG:然后我向经理们推销,“如果我们想在公司内认真地开展 Rust 工作,那么我想参与其中并成为一名员工”,因为那时我是一名顾问。
所以这就是我在沃尔沃工作的开始,那时我遇到了同样抱负的 Niko (Nikolaos Korkakakis)。于是,我们联手开始在核心计算机的低功耗节点上工作。这基本上是一个侥幸,我们拥有这个没有人真正关注的节点。每个人都忙于其他节点。并且它恰好运行在当时 Rust 的嵌入式裸机空间中得到最好支持的架构上。它也不是安全关键组件,因此我们不必担心安全认证。
JF:是的,这总是很麻烦。
JG:我们不必担心对安全至关重要的事情。
但同时,它必须非常可靠,因为如果它不工作,汽车将无法启动。
此外,由于功能范围有限,我们可以作为第一个项目的小团队。
JF:你有什么不足吗?
您是否需要来自开源社区的任何东西,还是您自己开发的?
JG:不,我们没有一切。一些零件丢失了。我们运行在 ATMEL/Microchip ATSAME 芯片 ,并且有一个开源项目。
在 Rust 中,您拥有这个硬件抽象层,类似于 Autosar 中的 MCAL。
所以这个项目是最近才开始的,但它只有几个外围设备,而且我们需要的许多外围设备还没有到位。像这样的司机就是这种情况 能够 我们在汽车行业使用了很多。因此,我们一直积极参与该项目。
JF:那时你有没有和任何人合作过?
JG:是的,我们见面了 格雷普 在 Rust 会议上。 Grepit 成立于 2014 年,是吕勒奥科技大学的衍生公司。他们是以下作品的作者: https://crates.io/crates/cortex-m-rtic ,它是一个用于构建实时系统的并发框架。
有了它,您可以在系统中实现实时行为,但仅此而已。它没有为您提供任何更高级别的抽象或许多其他 RTOS 通常会为您提供的服务之类的东西。但是您可以从许多可用的开源组件中获得它。所以是的,我们与 Grepit 合作让我们启动并运行。开发驱动程序并将其推向项目的上游。也有一些实现缺乏我们必须从头开始开发,但这并没有对我们造成太大阻碍。您可以使用很多简洁的工具。
JF:现在你有来自 C++ 世界的经验。你直接看到了什么好处?我的意思是现在,当你在 Rust 中工作时?
JG:我想说我从一开始就看到的好处是你不必考虑竞争条件和内存损坏,以及一般的内存安全。你知道,从一开始就编写正确且健壮的代码。所以这基本上是我的第一印象,但现在我也开始意识到还有很多其他方面。您从第一个方面的副作用中获得同样大的好处。首先让我们备份并简要描述一下 Rust 是如何实现内存安全的,这是非常独特的。它基于对程序中数据生命周期的静态分析,并确保对该数据的任何引用永远不会超过数据本身的生命周期。您也永远不允许在任何给定时间超过一个可变实例,或者您可以对数据有多个读取实例,但您可能永远不会混合这两个实例。通过在编译时静态执行此操作,您可以获得免费的内存安全,因为您知道生命周期何时结束,然后编译器将在该位置注入清理代码。
JF:除非你使用 unsafe 关键字?
JG:嗯,不安全的部分给了你一些额外的灵活性,可以让你在脚上开枪。但是,并不是所有的赌注都被取消了。即使在不安全的情况下,仍然有很多不变量得到支持。例如,终生的东西仍在坚持。不同之处在于您可以使用原始指针。它们基本上会删除所有生命周期信息,或者您可能会绕过编译器不允许您做的事情。这还包括编译器无法自行推理但必须留给人类的事情,并且始终在明确标记的不安全块中完成,以便您可以专门对其进行审核。
但它不像我认为许多人认为的那样,仅仅因为你回到 C 是不安全的。事实并非如此。您有很多安全措施,尽管与安全子集相比它们更加宽松。但是,编译器强制执行这种内存模型、生命周期和所有权模型的好处意味着每个人都在同一个页面上,这反过来意味着您可以以更容易和直接的方式导入和使用第三方组件。由于 Rust 带有一个内置的工具链来负责构建以及获取和解析依赖项,因此添加新的依赖项也更加容易和安全。
您不再需要检查:
它建立吗?
是我的构建系统让它失败了吗?
您无需更改构建系统即可构建和链接。如果我走到那一步,
该库是否与我对内存和所有权有相同的假设?
谁来释放这段记忆?
如果我必须创建一个缓冲区,谁来删除它,所有这些东西!
由于不必担心这一点,您在使用第三方组件时会感到更加自在。
JF:所以有一个关于如何完成的规则?
JG:是的。
JF:包裹怎么样?你只是拿任何东西,还是你有理由使用什么?
JG:我们试图将依赖关系降到最低,因为我们正在创造能够长期存在的产品。因此,我们引入的所有依赖项都是我们认为可以自行维护的,以防我们需要进行错误修复或其他任何事情。 Cargo 有一个内置插件,可以对代码进行审计并将其检查到数据库中,并报告产品生命周期内可能出现的任何漏洞或任何其他问题。
一开始我没有意识到的另一个好处是让新人入职更容易,因为新人可以自由地使用代码库,尝试改进、更改或重构它,而编译器不会运行编译直到所有不变量再次得到支持。这意味着您可以毫无畏惧地进行重构,并且新人无需经过仔细审查即可开始编写代码,因为您知道有很多不成文的不变量,只有少数人知道。而且我非常有信心,随着时间的推移,这也会减少保修问题,因为您可以预先获得更高的质量。
JF:是的,您不需要在产品上运行这么多工具来知道它是否安全,我们在 C 和 C++ 代码上运行一整套工具来尝试找出这些难以发现的错误。
JG: 是的,你不需要同样的程度。有一些运行时特性和类似的东西,您可能需要检查。它还取决于您希望代码的正式验证程度。你想静态地确保这些事情永远不会发生吗?
有一些运行时行为,您总是需要一些其他工具来帮助您。
JS:有这样的工具吗?
JG:它们变得越来越可用。我不确定是否有开箱即用的产品可以满足我们的所有需求,但我们正在尝试一些。例如, 美里 ,这基本上是在编译期间在虚拟机中运行代码,以找出代码库中的任何不合理之处。
JF:不也有一些大学的人制作的另一种工具吗?
JG:是的,例如 克莱 ,一个建立在 LLVM 编译器基础设施之上的动态符号执行引擎。它已适应 Rust。该工具可以为您提供关于某些情况下是否会出现恐慌的明确答案。我们自己还没有开始使用它,但这是我们想要探索的东西。还有 卡尼验证器 看起来很有希望。
JF:剖析器怎么样,是语言自带的还是?
JG:不幸的是,不在嵌入式目标上,或者至少现在还没有。因此,在最近发布的 Rust 中,有一个检测代码覆盖率标志,您可以将其提供给编译器,以便您获得额外的指令。这将随后向您显示您实际执行的代码路径。我们需要在那里做一些工作以将其应用于嵌入式目标。我知道它适用于桌面,因为它可以动态生成这些文件。但是,当然,在嵌入式目标上,您没有文件系统或文件,因此您需要自己处理将其写入某个内部缓冲区的问题。对于分析,您可以使用标准的桌面工具,但我不确定这对目标的转化效果如何。当我们进行测试时,我们会尝试将所有独立于硬件的逻辑与它们自己的 crate 隔离开来。因为这样我们就可以运行它们并使用该语言提供的内置测试支持。我们可以在这些基础设施上运行常规测试基础设施,但是当我们在实际目标硬件上进行集成测试时,我们会使用集成测试工具。
JF:所以你可以非常依赖 X86?
JG:是的,我们为主机构建代码并在那里进行测试。这也是 Rust 实力的一部分。跨平台支持相当无缝。它只是工具链的一部分,与 C 或 C++ 相比是完全不同的体验。
JF:如何测试它们?
我的意思是,Rust 是否提供了任何测试框架?
JG:有一个内置的单元测试框架。代码中的任何函数都可以作为测试运行,只需使用特定标签对其进行注释即可。您可以在常规代码中散布测试,当您为测试构建时,这些测试就会运行。进行单元测试的门槛几乎不存在。它是内置的,非常了不起。您可以轻松编写基准测试以查看您的功能如何改进。相同的测试框架也可用于编写集成测试,这些测试很容易在您的桌面上运行,但是当您在目标上执行时,它就不是那么无缝了。但是有一个新的 Rust 项目叫做 探测器 这使我们能够以相当无缝的方式与目标硬件进行通信。它提供了一个 广发银行 接口类型作为库,因此您可以为目标编写测试应用程序。对于您的主机,它只是将 probe-rs 作为库加载,然后您可以交互并发送类似 GDB 的命令或通过线路进行低级硬件操作,作为测试的一部分。
JF:你对未来有什么展望?
JG:我们有非常雄心勃勃的计划。
我们想在沃尔沃汽车公司扩展 Rust
为了在更多节点上启用它并做到这一点,我们需要获得对某些硬件目标的编译器支持和对其他目标的操作系统支持。替换已经开发和经过良好测试的代码是没有意义的,但是如果可行的话,从头开始开发的代码绝对应该用 Rust 开发。这并不是说 Rust 是灵丹妙药。 Rust 仍然有一些粗糙的边缘,它需要你做出某些权衡,这可能并不总是最好的做法。但总的来说,我认为 Rust 具有巨大的潜力,可以让我们以更低的成本预先生成更高质量的代码,这反过来又会降低我们的保修成本,所以这是双赢的底线。
JF:但是 Rust 可以与基于 C 的代码库共存吗?
JG:它可以在几乎任意的粒度、模块级别或功能级别共存,这取决于你在做什么。例如,您可以重写需要网络安全的部分、易受攻击的部分。 C 和 Rust 之间的开销为零,C 可以调用 Rust,反之亦然。即使对于 C++,也有一些方法,尽管您必须通过 C 接口,但有一些不错的 crate 可以帮助您生成额外的样板,以便 C++ 和 Rust 可以无缝通信。
安全关键行业也有很多人接受,我们会尽可能地支持这些努力。
例如,有这个 二茂铁项目 旨在通过 ASIL D 认证编译器。二茂铁将是现有开源编译器 rustc 的 ISO26262 认证版本。
AUTOSAR 和 SAE 也成立了一个 Rust 工作组。
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明
本文链接:https://www.qanswer.top/38924/30422411
标签:代码,好处,编译器,实际上,JF,JG,我们,Rust From: https://www.cnblogs.com/amboke/p/16725244.html