嵌入式系统中的安全相关功能
需要特定领域的设计、验证和确认 (V&V) 手段,这有助于系统地识别实施错误。在开发周期中遵守现有指南(例如道路车辆的 ISO 26262 和 ISO/PAS 21448)可使软件在设计上正确。也就是说,软件的架构是专门为以有效的方式满足所有安全要求而设计的,因此软件功能不当行为的剩余风险可以忽略不计。
此外,
系统总体设计和实施
,尤其是软件的设计和实施,都遵循特定的实践,例如评估输入值属性和其他条件、遵守 MISRA C 编码实践等。遵循这些实践有利于代码的简单性、模块化、清晰度和正确性,从而简化软件验证方法(例如功能的形式验证)以及验证过程(即测试)。
软件测试
对于基于 AI 的框架至关重要,因为它们与通常的安全相关开发过程的性质不太匹配,需要特定的安全标准,如汽车 ISO/PAS 21448(SOTIF)。这是因为很难指定、设计和验证更依赖于测试过程的 AI 框架。挑战在于生成有限数量的测试场景,为软件的低级属性(例如代码覆盖率、边界值、及时性)和高级属性(例如 AD 框架的驾驶场景)提供足够的覆盖范围。测试过程从单元级别开始评估和量化低级属性,以便后续集成阶段可以专注于测试集成接口和更高级别的属性。
包拆分
。当在非汽车内的机器上运行 AD 框架时,用户需要外部数据来模拟汽车在真实场景中接收的信息。一些 AD 系统(例如 Apollo)依赖于 ROS“bags”,这是基于 ROS 的程序使用的一种文件格式,用于存储可以包含任何类型信息的消息数据。在 Apollo 中,消息用于模块之间以及与各种传感器之间的通信。每条消息都附加到某个主题(例如,前置摄像头、LiDAR 传感器、感知输出等)。
运行 Apollo 模块意味着同时运行其所有模块。借助 ROS bag,如果播放 bag(即 bag 内的所有消息将按照记录时的顺序和时间间隔发送到系统),并且 bag 包含模块所需的所有数据,单个模块也可以独立运行。因此,模块处理在真实场景中记录的来自传感器或其他模块的消息。但是,对于某些模块,其所需的数据可能并非全部包含在 bag 中,而是仅在并发运行时由其他模块生成。
寿命调整
。比较原始版本和独立版本中处理的消息数量和启动的回调函数,Apollo 可以限制每个主题可以存储的消息数量(并非所有消息都可以在到达后立即处理)。这可能导致丢弃太旧的消息。这样做是因为每条消息都有一个生命周期,一旦在其生命周期内未使用,该消息就变得无用。但是,这里对 Apollo 进行修改,将这个限制移得足够远,因此让它处理包内的所有消息而不会丢弃任何消息,从而获得测试的确定性。
在类似于真实车辆配置的 docker 镜像中运行 Apollo,整个框架在 Linux 操作系统上运行。高性能 GPU 采用高带宽独立内存来为内存密集型工作负载(例如目标检测或其他深度学习工作负载)提供所需的性能。使用 Apollo 提供的代表性数据集和输入视频来运行模块并进行实验 [12]。
开发几个脚本来执行 Apollo 模块,同时始终以相同的方式(即确定性地)运行 ROS 包,并解析 Apollo 的输出以收集需要的结果。为了收集 GPU 内核信息,使用 NVIDIA 分析器工具 nvprof [18]。专注于回调(处理、pfi)函数,因为它们是在 Apollo 稳定运行期间触发的函数。此外,这些函数通常负责模块的核心功能,使其成为实验的目标。专注于六个代表性模块(其余模块要么没有带来额外的见解,要么只能在真实的汽车硬件中实例化):感知、预测、规划、定位、守护和控制。由于空间限制,特别关注感知,因为它是 Apollo 中最耗时的模块。