使用ATmega328P开始嵌入式系统的DevOps入门

Ari Mahpour
|  已创建:五月 29, 2024  |  已更新:July 1, 2024
使用ATmega328P开始嵌入式系统的DevOps入门

DevOps和敏捷方法论已经通过强调协作、自动化和持续改进,彻底改变了软件开发。将DevOps原则应用到我的设计和项目中,已经成为改变游戏规则的一步,提高了效率和可靠性。在这篇文章中,我们将介绍如何为一个使用ATmega328P微控制器现有嵌入式系统项目设置持续集成(CI)工作流。通过本文,你将看到这些实践如何简化你的开发过程并交付更高质量的产品。

理解嵌入式系统的DevOps和敏捷

DevOps是一套实践,由软件界推广,它将软件开发(Dev)和IT运维(Ops)融合为一个持续的流程。在软件界,开发软件然后“扔过墙”给运维团队让他们部署给客户曾是常态。DevOps引入了一种方式,不仅拆除了这堵墙,还将整个过程自动化。在硬件界,我们发现产品开发和生产之间有相似之处,不断地将设计“扔过墙”给我们的制造工程团队,以确保一切都为生产做好了准备。

在嵌入式产品设计中,我们仍然需要将软件通过生产,但面临着比以往任何时候都要快的挑战,并且要以尽可能高的质量交付。通过DevOps原则,我们旨在解决其中的一些挑战。

  • 硬件依赖性:嵌入式系统依赖于硬件和这些PCB的特定修订版。如果不简化为自动化和高度可扩展,测试和部署可能会变得复杂。DevOps实践通过使用相同的硬件和软件设置,并将其通过自动化的持续集成(CI)系统,帮助自动化这些过程。
  • 长时间构建:构建嵌入式软件可能难以设置,并导致长时间的构建。CI通过将构建卸载到云端,利用开发者通常无法访问的更强大的实例,自动化并加速了这一过程。
  • 手动测试:在实际硬件上进行测试是必不可少的,但通常是手动的、乏味的和耗时的。通过硬件在环(HIL)测试的自动化提高效率和准确性,并可以卸载到配置有CI系统的自动化测试设备的设置中。

通过应用DevOps原则,我们能够使用敏捷方法论在构建-测试-部署范式中快速迭代,为我们希望发布到生产的每个附加功能。

它是如何工作的

“构建、测试和部署”是你在讨论DevOps时经常会听到的一组常用词汇。在嵌入式系统中,我们做的事情也是一样的,因为我们的部署同样会进入生产环节(然后是最终客户)。在项目的仓库中,我们使用Gitlab CI来驱动我们的端到端工作流程,以实现嵌入式DevOps。我们使用所谓的“管道”来创建完成特定任务的作业,例如编译软件、在目标上运行测试或将其作为官方包发布。在Gitlab中,管道是一系列按顺序流动的作业集合,如下所示:

示例管道

图1:在Gitlab中使用的ATmega328P DevOps工作流程示例管道

这里是CI脚本(.gitlab-ci.yml文件)的细节分解,以给你一个如何工作的概念。

  • Docker:容器化构建和运行环境以进行硬件在环测试中所讨论的,这个阶段构建Docker镜像,以创建一个一致的环境来构建、测试和刷新代码。这确保了在不同的机器和架构(例如桌面PC与树莓派)上构建过程的可重现性。
  • 测试:这个阶段运行单元测试,以验证你的代码是否按照你的意图进行操作。自动化测试在修改或重构现有代码时快速且重要。
  • 构建:这个阶段将源代码编译成二进制文件。在这个项目中,它生成像.elf和.hex文件这样的构件,这些被用来刷新ATmega328P芯片。
  • HIL(硬件在环):这个阶段涉及在实际硬件上测试软件,以确保它在现实条件下正确工作。它将软件加载到硬件上并运行测试,以验证我们设计的功能实际上是否在最终产品上工作。
  • 部署:这个阶段处理将构建的构件发布到包注册表中,使它们可供使用。
  • 发布:这个阶段创建一个新的软件发布,自动化交付过程以确保快速和可靠的更新。这是生产团队将用来检索他们的整个产品组装所需软件版本的。

细节

有一些细微的细节,将这个工作流程从一个基本的DevOps实现转变为一个运行平稳、文档齐全且易于观察的系统。在CI工作流程中有一些微妙的细节是重要的。

  • 语义版本控制:无论是通过自动化机制还是手动设置版本,对于生产周期来说都极其重要。例如,这在CI脚本中设置为一个变量,然后在发布和发布作业中使用。
  • Docker构建逻辑:你会注意到有一个用于Docker容器构建的逻辑块:

 


if [ "$CI_COMMIT_REF_SLUG" == "$CI_DEFAULT_BRANCH" ]; then

  export IMAGE_TAG=$CI_REGISTRY_IMAGE/$IMAGE_TYPE:latest

else

  export IMAGE_TAG=$CI_REGISTRY_IMAGE/$IMAGE_TYPE:$CI_COMMIT_REF_SLUG

fi

 

此逻辑确保了我们的“latest”标签仅使用在主分支上构建的Docker镜像(即在合并请求成功通过后)。这确保了只有成功的合并请求才会发布最新最好的docker镜像,供每个人和每个流水线拉取。

  • 报告和覆盖率:在像Gitlab这样的现代CI系统中,我们能够在我们的合并请求和流水线中提取和显示测试及覆盖率报告。例如,在这个合并请求中,我们捕获了代码覆盖率:
合并请求中的代码覆盖率

图2:合并请求中的代码覆盖率

在这个截图中,Gitlab总结了在目标硬件上运行的测试:

在目标上运行的测试摘要

图3:在目标上运行的测试摘要

最终,一旦我们的代码通过了单元测试和目标测试的验证,发布和发布阶段就会生成一个漂亮的包,生产团队可以使用:

软件包发布

图4:软件包发布

通过所有这些自动化步骤,我们可以以敏捷的方式迭代地发布新功能。不需要开发许多功能,将它们发送到QA部门,然后由生产团队审查包发布。这里的一切都在一个工作流中发生,并且完全自动化。

结论

在本文中,我们探讨了如何将 DevOps 和敏捷方法应用于嵌入式系统开发,特别是使用 ATmega328P 微控制器。我们讨论了在 Gitlab 中实施 CI 工作流的好处,包括自动化、更快的构建时间和高效的测试。通过分解 CI 脚本并解释每个阶段,我们展示了如何创建一个健壮且流畅的开发过程,以提高效率和产品质量。通过遵循这个实用指南(以及仓库中的源代码),你也应该能够建立自己的嵌入式 DevOps 工作流。

项目的源代码可以在这里找到:https://gitlab.com/embedded-designs/atmega328p-serial-led-control

关于作者

关于作者

Ari 是一位在设计、制造、测试以及集成电气、机械和软件系统方面拥有丰富经验的工程师。他热衷于将设计、验证和测试工程师凝聚成一个高效团队,共同工作。

相关资源

相关的技术文档

返回主页
Thank you, you are now subscribed to updates.