0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

使用SPARK和Ada进行代码清理

星星科技指导员 来源:嵌入式计算设计 作者:Quentin Ochem 2022-06-29 14:33 次阅读

您能以多快的速度将软件推出并准备好?

长期以来,这个单一的问题推动了大部分嵌入式工业行业。按时发布此年度版本,满足该功能里程碑。只要软件功能相对简单或次于系统功能,就可以了。

但随着系统复杂性和互连性的日益增加,曾经是良性的小故障或“故障”现在正在造成威胁,有时甚至危及人的生命。无人机自动驾驶汽车和医疗设备是这一趋势的三个非常重要的代表。那么问题就不再是软件能否按时交付,而是正确、安全、可靠的软件能否及时交付。这是一个完全不同的野兽。

除了验证它正在做它应该做的事情之外,没有太多可以做的事情来交付正确的软件。不幸的是,传统的软件开发方法并不是为了简化正式规范或优化验证成本而设计的。而且越晚检测到问题,修复的成本就越高,以至于在第一天需要几分钟才能解决的问题可能会在集成过程中持续数月。是的,使用传统语言和环境编写极其强大的软件是可能的,但成本高得离谱。

特别是对于在微控制器MCU) 上运行的嵌入式应用程序,一个更加复杂的因素是编写测试的难度。当涉及低级嵌入式功能时,编写甚至运行广泛的测试活动可能是不切实际的。任何可以在这些程序之前帮助清除问题或确保正确性的东西都可以节省大量成本。

另一方面,从一开始就利用表达性和正式的规范,使实施者更容易尊重需求,提供自动验证,从而防止问题或在开发周期的早期发现问题。

Ada 和 SPARK 语言在这方面提供了独特的解决方案,将规范、编码和验证集成到一个通用的形式中。这些语言的核心原则是在软件级别尽可能多地指定,以便在实现时可以验证尽可能多的组件。

下面逐步检查实际的 Ada 或 SPARK 实现。

规格

在将 Ada 和 SPARK 语言与替代语言进行比较时,突出的一件事是可以添加到软件源代码中以捕获除实际功能之外的约束和意图的信息量。数据类型不仅仅是一个整数或浮点数:它是一个语义实体,可以与一组有效值、一组操作、最小精度、内存表示,甚至物理维度相关联。同样,函数不仅仅是一种从参数计算值的方法:它有一组可以调用的条件,在它返回时提供一组保证,并对它的环境(参数和全局变量)产生影响)。

Ada 和 SPARK 有很多特性可以用来丰富规范,但是为了本文的目的,我们选择一个例子:

poYBAGK78nGAD0OmAABUGzjQXjE060.png

这个简单的过程在其属性和行为方面揭示了很多:

首先,C 是一个in out参数,所以它必须在被调用之前被初始化,并且它的值在子程序中被修改。请注意,没有指示它是通过复制还是引用传递,这是由编译器根据语言约束和效率自动决定的。

E 是输入参数,或不打算修改的输入值。一个前提条件是在调用之前容器未满。就设计而言,这是一个极其重要的转变,就像在其他语言中的Push过程可能负责检测错误的调用上下文(如果容器已满)并实施缓解技术(或防御性代码)。另一方面,使用先决条件,该过程可以安全地假设容器未满(否则它会被静态或动态检测到,但稍后会详细介绍)并避免这些额外的代码。验证输入的责任隐含在调用者身上,然后调用者可以将其提升给自己的调用者,直到到达代码中数据验证确实有意义的地方。

后置条件提供了有关过程行为的关键属性——这里,E 包含在修改后的容器中并且计数增加的事实。

查看与嵌入式开发相关的一些约束,另一个有用的方面是指定内存映射约束。Ada 允许声明式表示法来指定数据结构在内存中的布局方式和地址,从而避免容易出错的按位操作和一致性检查。例如:

pYYBAGK78niAFDibAAD08l6mA7w598.png

上面声明了一个数据结构以及一些与边界相关的字段:

数据的大小固定为 16 位,接下来的两个方面(具有值High_Order_First)基本上告诉编译器使用大端表示。

下一个子句提供特定的位表示(例如,Size从索引位1到4的字节0开始。

最后,为R提供了它在内存中的地址。

实施(在 SPARK/Ada 或 C 中)

Ada 和 SPARK 语言提供了现代命令式语言的大部分功能。这些功能如何实现的最显着特性是它们为编译器解释提供的空间很小并且避免了捷径。例如,没有隐式转换,并且轻松地执行指针运算之类的操作需要 5 行代码。但是,在实际编码阶段花费的额外时间很容易通过易于验证来重新获得,无论是用于代码阅读、测试还是静态分析。

在讨论的这一点上,值得一提的是房间里的大象:对于新开发的代码来说,使用一种新语言可能是一个好主意,但通常存在一个不容忽视的预先存在的环境。这通常是来自其他项目或现成库的代码。这段代码可能是用 C 语言或 C++ 创建的。仅此一项就经常驱动开发语言的选择。

幸运的是,SPARK 和 Ada 已被设计为与 C 环境很好地集成。一些指令可以将 C 直接映射到 Ada,反之亦然,而无需任何包装代码的开销。这种映射甚至可以自动生成。

因此,如果不推荐的话,在 SPARK 或 Ada 中仅开始开发几个组件,而在其他情况下保留在 C 环境中是完全合理的。

目前可用于 Ada 和 SPARK 的主要编译器技术是 GCC,但也可以提供其他编译器技术。这意味着 SPARK 和 C 代码可以使用相同的技术进行编译,具有相同的优化和代码生成通道。结果,C 和 SPARK 代码之间的性能几乎没有差异,并且没有从一种语言到另一种语言的控制流的损失。

谈到我们之前的一个例子,让我们假设正在使用一个用 C 实现的容器。我们试图与之交互的 C 代码如下所示:

poYBAGK78oKATkTCAAAToRMnhxI551.png

除了来自 C 的实现声明之外,规范在 Ada/SPARK 中完全相同。

pYYBAGK78omATLbXAABqTT0eGgk084.png

Ada 或 SPARK 代码可以像在 Ada 中实现一样使用此过程。与导入类似,导出允许 C 调用用 Ada 编写的子程序。如果需要,这些接口层可以通过绑定生成器自动生成。

尽管将 SPARK 和 C 一起编译解决了许多用例,但仍然存在最终代码必须是 C 的情况。确实,一些用户虽然对使用 SPARK 进行开发感兴趣,但仍需要将 C 代码交付给他们的客户。

可以使用一个特殊的编译器来覆盖这个用例,即“GNAT 通用代码生成器”。它本质上将 Ada 语言的一个子集编译为 C。借助这项技术,SPARK 几乎成为一种建模语言,其输出集成在 C 环境中。它也可以被视为一种交付形式验证的 C 代码的方式,验证在 SPARK 级别执行。

在数据表示示例(寄存器案例)中,在代码中使用这段数据非常简单。分配一个值如下所示:

poYBAGK78pGAb2ocAAALyR35hnM557.png

这里不需要按位运算,因为编译器会在后台自动生成适当的代码。

确认

Ada 和 SPARK 在源代码中提供了大量信息,可供各种检查器使用。例如,作为第一道防线,编译器将检测到许多不一致之处,并可以在测试阶段自动在可执行文件中插入动态验证。有了这个级别的信息,就可以超越经典的静态分析并应用程序验证技术来演示整个应用程序的属性。

对于较低级别的数据结构,也会进行自动一致性验证。编译器验证特定大小是否足以实现所需的数据范围,没有数据重叠等。此外,形式证明可用于验证分配的值是否始终在任何分配的范围内。

继续前面的另一个示例,假设在我们想要验证的一段代码中调用了Push 。例如,我们可以让以下语句从输入文件中读取数字,直到它达到 0:

pYYBAGK78peANHeCAABDFxa3C4Q122.png

这个Push调用将被 SPARK 工具标记为不正确,因为无法知道循环不会达到容器 C 的最大容量。证明者无法证明Push的前提条件,这显然应该在调用,而不是在被调用的过程中。如果到达文件末尾而没有击中0 ,则示例代码中可能会出现另一个潜在错误。如果指定了适当的先决条件,证明者将能够判断循环中缺少检查以验证是否仍需要读取输入。

这种问题通常会在某个时候发生。如果覆盖极端案例的单元测试足够广泛,那么问题将在该级别得到解决。然而,当真正的数据开始输入系统时,他们可以找到自己的方式进行集成测试,或者当用户试图破坏系统时进行 beta 测试。在最坏的情况下,其中一些错误会通过部署找到并需要在客户报告后进行追踪。问题不是它们是否会被发现,而是当它们被发现时修复它们的成本会有多高。越晚发现,越多的人参与到链条中,需要更多的调查来确定源头、修复问题、证明修复的合理性、测试修复、重新交付产品等。使用技术早期集成验证 - 在这种情况下,

旧的又是新的

Ada 和 SPARK 方法的独特之处在于它集成了软件规范、实现和验证,提供了一种以现代系统所需的完整性级别生产软件的经济高效的方法。医疗、汽车和工业物联网 (IIoT) 等行业一直在寻找传统 C 语言开发的替代方案,Ada 和 SPARK 提供了经过验证的解决方案。

作为 Ada 语言的提供者,AdaCore 在过去几年中观察到对该技术的新兴趣。今天的限制提供了一个尝试新事物的好机会——或者正在卷土重来的旧事物。

审核编辑:郭婷

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 物联网
    +关注

    关注

    2865

    文章

    41524

    浏览量

    358083
  • C语言
    +关注

    关注

    180

    文章

    7521

    浏览量

    127404
  • 编译器
    +关注

    关注

    1

    文章

    1569

    浏览量

    48598
收藏 人收藏

    评论

    相关推荐

    Spark基于DPU Snappy压缩算法的异构加速方案

    一、总体介绍 1.1 背景介绍 Apache Spark是专为大规模数据计算而设计的快速通用的计算引擎,是一种与 Hadoop 相似的开源集群计算环境,但是两者之间还存在一些不同之处,这些不同之处
    的头像 发表于 03-26 17:06 196次阅读
    <b class='flag-5'>Spark</b>基于DPU Snappy压缩算法的异构加速方案

    RDMA技术在Apache Spark中的应用

    背景介绍 在当今数据驱动的时代,Apache Spark已经成为了处理大规模数据集的首选框架。作为一个开源的分布式计算系统,Spark因其高效的大数据处理能力而在各行各业中广受欢迎。无论是金融服务
    的头像 发表于 03-25 18:13 1053次阅读
    RDMA技术在Apache <b class='flag-5'>Spark</b>中的应用

    基于DPU和HADOS-RACE加速Spark 3.x

    、Python、Java、Scala、R)等特性在大数据计算领域被广泛使用。其中,Spark SQL 是 Spark 生态系统中的一个重要组件,它允许用户以结构化数据的方式进行数据处理,提供了强大
    的头像 发表于 03-25 18:12 915次阅读
    基于DPU和HADOS-RACE加速<b class='flag-5'>Spark</b> 3.x

    越来越慢了,苹果笔记本清理内存怎么清理

    如果你的苹果笔记本开始变得越来越慢,那么清理内存可能是一个解决问题的好办法。大量的垃圾文件和不必要的数据,这些都会对性能产生负面影响。但是,不用担心!本文将详细介绍苹果笔记本清理内存怎么清理,让你的苹果笔记本恢复到巅峰状态。
    的头像 发表于 12-26 13:10 444次阅读
    越来越慢了,苹果笔记本<b class='flag-5'>清理</b>内存怎么<b class='flag-5'>清理</b>

    c盘怎么清理垃圾而不误删文件

    分:备份文件 在进行任何清理操作之前,我们应该始终备份重要的文件。这是因为C盘清理可能会意外删除一些我们不希望删除的文件。我们可以使用外部存储设备,如U盘、移动硬盘或云存储来备份重要文件。确保所有文件都被备份到一个安全的
    的头像 发表于 12-08 14:51 376次阅读

    ADA4084-1/ADA4084-2/ADA4084-4的应用介绍

    电子发烧友网站提供《ADA4084-1/ADA4084-2/ADA4084-4的应用介绍.pdf》资料免费下载
    发表于 11-27 09:56 0次下载
    <b class='flag-5'>ADA</b>4084-1/<b class='flag-5'>ADA</b>4084-2/<b class='flag-5'>ADA</b>4084-4的应用介绍

    ADA4177-1/ADA4177-2/ADA4177-4电流运算放大器介绍

    电子发烧友网站提供《ADA4177-1/ADA4177-2/ADA4177-4电流运算放大器介绍.pdf》资料免费下载
    发表于 11-27 09:22 1次下载
    <b class='flag-5'>ADA</b>4177-1/<b class='flag-5'>ADA</b>4177-2/<b class='flag-5'>ADA</b>4177-4电流运算放大器介绍

    在multisim中利用双运放ADA4096-2构建了一个低通滤波器进行仿真,引脚如何分配?

    我在multisim中利用双运放ADA4096-2构建了一个低通滤波器,并进行了仿真,之后感觉ADA4096的带宽只有500KHZ,因此想换成ADA4084-2试一下。但multisi
    发表于 11-27 06:44

    ADA4940和ADA4941的区别是什么?

    目前做一个16/18位AD采集,使用全差分sarADC,如AD7982/AD7915 推荐输入驱动,有ADA4941和ADA4940。 通过对比两者的性能,发现结构上稍有不同,但是性能
    发表于 11-16 06:27

    LTspice自带的ADA4895模型和ADA4895.cir模型存在差异,具体以哪个为准?

    如下图,对ADA4895进行噪声分析,左侧为LTspice的ADA4895模型(Vrms=0.633mV),右图为ADA4895.cir模型(vrms= 1. 78mv),两者的噪声差
    发表于 11-14 07:46

    焊接时候的松香怎么清理

    松香助焊剂影响板子的美观,怎样才能清理干净?
    发表于 11-10 07:42

    Redis 的数据清理策略

    本文整理 Redis 的数据清理策略所有代码来自 Redis version :5.0, 不同版本的 Redis 策略可能有调整
    发表于 09-19 14:24 150次阅读
    Redis 的数据<b class='flag-5'>清理</b>策略

    NVIDIA 携手腾讯开发和优化 Spark UCX 实现性能跃升

    腾讯网络平台部与数据平台部,联合 NVIDIA 合作开发和优化 Spark UCX,最终实现 Spark Shuffle 稳定加速 15% - 20%,平均降低现网 Spark 任务
    的头像 发表于 08-25 20:50 416次阅读
    NVIDIA 携手腾讯开发和优化 <b class='flag-5'>Spark</b> UCX 实现性能跃升

    清理PCB中的布线与过孔

    “ 在KiCad的PCB编辑其中,有一个实用的工具,可以用来清理布线与过孔。不仅可以移除没有使用的布线与过孔,还可以清理冗余的重叠导线。 如需了解更多关于KiCad的资讯,请参考:**KiCad常用
    发表于 06-25 12:19

    BBC micro:bit上对AdaSPARK代码实现

    micro:bit是 BBC 为计算机教育设计的非常小的 ARM Cortex-M0 开发板。它配备了支持蓝牙的Nordic nRF51 32 位 ARM 微控制器。它的价格为 15 美元,是开始嵌入式编程的最便宜但最有趣的工具包之一。
    发表于 06-21 15:51 0次下载
    BBC micro:bit上对<b class='flag-5'>Ada</b>和<b class='flag-5'>SPARK</b>的<b class='flag-5'>代码</b>实现