【CSDN 编者按】在嵌入式环境中,C、C++作为最常见的编程语言,早已被广泛应用在底层工具链、库中。不过,近日嵌入式工程师Omar Hiari提出一种完全不同的看法,他认为一开始就考虑安全问题的编程语言Rust才是嵌入式领域的未来。虽然要将嵌入式应用程序代码迁移到一种新的编程语言上非常麻烦,但他认为这是可行的,只是需要一些方法和实践。
原文链接:https://apollolabsblog.hashnode.dev/why-you-should-be-worried-about-the-future-of-cc-in-embedded-a-case-for-rust
本文由CSDN翻译,转载需注明来源出处。
以下是译文:
软件故障在嵌入式领域时常发生,随着物联网(IoT)和网络物理系统(CPS)等技术的普及,这些故障也没有得到应有的重视。当人们谈论自动驾驶汽车、机器人、无人机时,他们总认为这些出错的机率很小。但在了解一些历史上著名的软件事故、Bug案例研究后,你就不会这么想了。
重现问题简直是一场噩梦
首先,需要声明的是,我主要从事汽车嵌入式领域。此外,在职业生涯中,我还接触到了功能安全领域。
功能安全,简单来说,是指一个系统或是设备整体安全的组成部分。其达成安全性的方式是靠系统或组成零件在接受输入讯号后,可以正常的动作,来减少导致人类受伤的事故风险。例如一个马达中加装温度感测器,若温度超过一定值,即停止马达运转,此机能就属于功能安全。
在进入到汽车行业这些年,我担任过几个项目的技术负责人,其中部分职责会涉及到处理客户退货的问题。之所以这些汽车会被退回,大概率是由于电子单元或模块出现了问题,而我们团队需要确定导致该问题的根本原因。如果问题的根源确认是模块中出现了一个错误,我们会针对这个错误提出一个修复方案,并且将它整合到未来的更新中。有时我们会花费几天,甚至是几周来找出Bug的原因。
我现在还记得我第一次处理这些问题的的经历,那时我还是一个做模块测试的实习生。我们发现,有几个被退回的模块,在现场测试时出现了不一样的结果。有些能够正常工作,有些不能。在和软件团队调试了很长时间后,我们终于找出了问题所在,原来是因为一个未初始化的变量!我惊讶于这样的错误竟然没有被检测出来。
随着在这个行业不断地成长,我所遇到的问题越来越复杂。有时,我们会在成千上万的模块中找一个有问题的模块。通常情况下,第一步是尝试复现这种问题,以便用调试工具追踪问题的来源。这简直是一场噩梦!复现某些行为需要几天或者几周的时间,有时甚至需要更长的时间,因为要复现这个问题,需要非常具体的实现过程相组合。在大多数情况下,这些实现过程会存在一些未经测试的配置,最终导致触发Bug。
正常导致汽车故障的大多数问题本质上出在软件上。有趣的是,即使是在一些质量至上,而且拥有大量经验丰富软件工程师的公司也会出现这种情况。基本上,这些遇到现场问题的模块,已经进行了彻底的测试、代码审查、代码标准的实施(例如MISRA-C)。
一开始就考虑安全问题?
后来,在从汽车嵌入式领域进入功能安全领域时,我发现我的经历更加有趣。
在功能安全方面,像工业IEC-61508和汽车ISO-26262这样的标准在汽车行业开始流行起来。遵循这些标准的目的是为了减少产品故障的风险,风险的大小取决于产品的使用方式或者地点。通过在开发过程中加入更多的测试和检查,可以让产品达到一定的安全水平。
以ISO-26262为例,该标准对软件和硬件中可能发生的故障类型进行了分类。硬件的故障被分为两种类型:随机硬件故障和系统故障。在软件方面,只有一种类型,即系统性故障。根据ISO-26262,随机硬件故障被定义为:
在硬件元素的生命周期中,可能会发生不可预测的故障,并且遵循概率分布。
该标准还补充说:
随机硬件故障率可以以合理的精度进行预测。
而系统性故障被定义为:
故障以确定的方式与某种原因相关,只能通过改变设计或制造过程、操作程序、文件或其他相关因素来消除。
这意味着,系统故障或多或少源于人为错误,并不是真正可以预测的。因此,如果我们考虑修复软件问题,就意味着需要更多额外的检查。当然,在应用程序中也可以添加一些方法让其自己检查(例如N-版本编程),尽管如果把这些方法添加到动态的应用软件代码中,消耗的内存空间会增多。
鉴于我前面提到的,人们可能会认为这种变化是喜闻乐见的。但情况恰恰相反,大多数工程师都会反对整合功能安全流程。事实上,如何让工程师和团队接受这一点,让许多管理安全开发者感到很头疼。
这种推动力通常来自于产业链的顶端,即建立一种 "安全文化"。我认为,部分原因是由于流程和额外的文件或者可交付成果方面的重大变化,而不一定是因为个人反对安全的想法本身。(如果有什么是是工程师不喜欢做的,我想写文件一定排在首位。)
(1:产品已经测试过发布了。2:你没忘记写文件吧?)
还有一点也让管理安全开发者感到头疼,即说服团队,让他们知道产品需要从一开始就以安全前提来设计。这意味着,工程师不应该只致力于让现有产品开始应用其功能来满足安全要求。换句话说,就是对现有产品进行修补以使其满足安全要求。这主要是针对硬件和应用软件来说。让我感到不解的是,为什么这一项不能应用在编译语言或者编译器上呢?与编译器一起使用的语言并没有从一开始就考虑到安全问题。相反,它们是根据功能安全应用中的标准准则进行修改的。比如创建语言的”子集“,删除其中被认为不安全的部分。这意味着排除了编程语言结构中存在的不安全因素。
迫在眉睫的问题
对于一些了解甚少的人来说,在汽车领域最普遍的编程语言是C。但从我的亲身经历来看,我认为C、C++并不是能够引领未来应用趋势的语言。事实上,从长远来看,坚持使用C、C++,不管有多少标准引入都令我感到担忧。毫无疑问,C、C++是强大的语言,但与即将到来的应用程序相比,目前的应用程序还是太简单了。此外,随着行业的发展,工程师的水平会参差不齐。所以无论流程多么严格,出现系统性错误的可能性都会越来越大。
随着经验的不断积累,实践不断增加,以及在C、C++这样的语言中不断增加补丁,但是类似的问题仍然是由于系统性错误而产生,是不是至少应该考虑切换到另一种思路来设计语言,即一开始就把安全性作为前提来设计?又或者只是创造出一种更加现代的语言,正如系统性故障所定义的一样:
只能通过改变设计来消除问题。
一条可能的前进道路
我在Rust中找到了一条可能通往嵌入式的道路,它似乎就是我在这个行业多年来所要找的。Rust的设计初衷是为了成为一种安全的语言。当然,要把嵌入式程序代码迁移到一种新的编程语言上是非常麻烦的。显然,阻碍因素之一是在汽车等嵌入式环境中,C、C++的工具链和库已经根深蒂固了,早已成为了生态系统中的一部分。然而,虽然代码迁移有困难,但也不是不可能,我们可以制定计划,循环渐进地进行切换。
在非嵌入式环境中,Rust已经获得了相当大的知名度,并且得到了亚马逊、Discord、Dropbox、Facebook、谷歌和微软等公司的投资。事实上,微软和谷歌已经为Rust在某些领域能够消除70%的安全问题做了担保。
到目前为止,关于嵌入式,某些团体已经有了一些有趣的动向。有一个Rust嵌入式工作组正在社区内工作,以弥合与Rust团队的差距,同时发展嵌入式生态系统。该小组在发展生态系统方面的速度令人印象深刻。(如果对这个工作小组的成就感兴趣可以访问这个网站:https://www.autosar.org/news-events/details/autosar-announces-new-working-group-for-programming-language-rust-in-automotive-software-context-202/)
另一个是Ferrous Systems,它在支持Rust生态系统方面也做了大量工作。Ferrous在为Rust创建不同的工具和扩展方面做出了重大努力,并且正在ferrocene项目下为ISO26262认证Rust编译器工具链。
有趣的是,在我写这篇文章的时候,AUTOSAR(AUTomotive Open System ARchitecture汽车开放系统架构)也宣布了一个在新的汽车背景下的Rust工作小组。(感兴趣可以访问这个链接:https://www.autosar.org/news-events/details/autosar-announces-new-working-group-for-programming-language-rust-in-automotive-software-context-202/)
(补充:我不属于也没有参与过上述任何实体)
Rust可能是嵌入式未来
市场方向表明,我们开始从C、C++向更安全、更现代的编译型编程语言转变的时机到了。(并不是对于所有的应用,只是对于那些C或者C++可能出现问题的应用)
Rust编程语言虽然相当年轻,但似乎是最适合这种情况的。对于公司和个人来说,使用Rust编程可能是一个很好的战略决定,能够在未来获得优势。对于个人来说,即使像Rust这样的语言永远不会被采用,但它至少会给个人一个全新的视角,让他知道如何成为一个更好的C/C++开发者。
END
— 推荐阅读 —
—点这里↓↓↓记得关注标星哦~—
一键三连 「分享」「点赞」p「在看」
成就一亿技术人