您如何构造大型嵌入式项目?[关闭]


21

背景

初级研发电子工程师(公司中唯一的EE)-硬件和编码不是问题。我最大的问题是对项目以及从何处开始进行适当的概述。

到目前为止,我只做过较小的软件项目(不到500行代码),但是我不能设想自己做更大的项目而不丢失功能概述或缺乏功能。

您如何最好地构建结构/使用什么工具来构建大型嵌入式软件系统?

我目前正在做什么

我通常从勾勒项目的功能开始。它可以是一对多的分层流程图或相关图表(框图等),并且可以对组件/芯片进行一些研究。然后,我在参考数据表/ Internet时直接跳入编码(我想很快失败了),一次编码一种功能,并用伪数据对其进行测试,或类似的测试。它可能正在将数据写入MEM芯片,然后如果可行,则它可能是主芯片和MEM芯片之间的SPI驱动器。

我在寻找什么答案

真的是。我会整理出我认为明智的内容。它可能是一本书,一篇文章,个人经历,建议等。

我对了解老年人如何解决这一问题非常感兴趣。


编辑

首先,感谢您分享您的多年经验!非常感谢所有答案。我的看法是:

  • 创建清晰准确的规格文档。
  • 创建一个软件设计文档。(我现在要添加的内容) 设计文档模板
  • 在模块中考虑它看起来有多冗余。(我需要更多地关注)
  • 遵循编码标准来构造头文件/源文件。(从未这样做) Barr C组标准
  • 首先专注于创建底层实现。(通讯等)
  • 尽可能/合理地实施设计模式。 设计模式
  • 设置一些用于版本控制的内容(Github等-从未使用过太多)
  • 研究持续集成/持续部署(偶然发现的新事物) CI和CD基础知识

4
这个问题不属于这里...可能在softwareengineering.stackexchange.com
Swanand

11
也许这个问题确实属于这里。几十年前,我请来了一个多芯片设计团队,我们通过将每个芯片分解为各种功能来跟踪进度,然后估算(一组新手,有动机但又新手)了解/设计/测试/审查60多种功能。即使我们不符合最初的管理计划,管理人员也需要耐心,因为他们可以通过我们知道需要设计和集成的60多个功能轻松跟踪进度。
Analogsystemsrf

13
@斯旺德,我不同意。常见问题解答说:“ [关于...的问题,用于裸机或RTOS应用程序的固件编写”-我要说这肯定也包括计划阶段。该问题专门指出“大型嵌入式系统”。
阿拉霍

2
虽然此处是固件编程的主题,但查看问题是否过于广泛且基于观点的一种好方法是在短时间内获得答案。这绝对太广泛了。帮助部分会说“如果可以写一本书……”之类的东西,并且已经为此写过书!
管道

2
OP创建了一个很好的摘要。我想向他们强调,GitHub不是运行Git存储库的唯一方法。您可以在本地运行,无论是否运行特殊的Git服务器。Git并不是源代码管理系统(SCS)/版本控制系统(VCS)的唯一形式,但它现在是一种非常流行的形式。当我以拥有大量C和C ++培训的EE身份开始工作时,我几乎不会接触到此类东西。
TafT

Answers:


23

有几个方面会影响项目结构的详细程度。对我而言,主要因素之一是我是唯一的一种编码(在撰写本文时,您是唯一的EE,对您来说情况似乎如此)或是否涉及其他编码。然后就是“大”到底意味着什么的问题。通常,我将设计过程分为以下步骤:

需求定义 如果您获得适当的软件规格来进行大量规划,那么此工作已经完成。如果您只是模糊的需求,那么您要做的第一件事就是理清客户的实际需求(有时他们一开始并不真正了解)。我知道直接进入编码很诱人,但这带来了丢失一个重要功能的风险,而这个功能可能在一开始就不很明显,并且不能仅仅在开发过程中的某个地方轻易地被压缩到您的代码中。

系统边界和可维护性 在嵌入式系统中,您通常会有一些系统接口,有些接口到外部(操作员),也有内部接口。很好地定义这些内容,并尝试将依赖性降到最低,这将简化连续的工程设计和可维护性。另外,在需要的地方注释/文档代码,您永远都不知道还有谁要使用它,他很乐意在真正知道函数的作用之前不必深入研究十几层代码。

定义可验证的任务 特别是如果其他开发人员正在使用相同的代码库,则不可避免的是要定义明确的任务(功能)以及它们之间所需的接口。只要有可能,就应该独立于其他功能对各个功能进行测试/验证,这就是您需要良好定义接口的地方,因此您可以定义测试用例。

一个功能接一个地 让人喜欢进步,因此,如果您有各种各样的任务,那么他们通常会在最大的进步上工作。在开始下一个任务之前,我通常会尝试完成一项任务并将其置于经过验证和测试的状态。这使您的代码可以被其他人测试,并且您最终不会忘记某些东西。

版本控制 在项目的整个生命周期中,有时您需要较旧的版本,也许是为了确定某个新版本引入的错误,或者只是要构建一种行为与3年前完全相同的设备。确保您的代码中有明确的版本修订和标签。Git绝对是您的朋友。


3
特别是要求!没有什么比构建产品或功能做错事了。
ConcernedHobbit

13

Humpawumpa写了一个很好的答案!我只是想补充他的一些观点,但是由于此评论太长了,我将写一个单独的答案。

我曾经担任过OP的职务–不是唯一的EE,而是唯一在一家小公司中进行过MCU开发的EE。

即使您是唯一的开发人员,我也无法充分强调模块化的重要性。随着项目的发展,这是保持理智的唯一途径。您需要严格地编写每个模块仅处理一个功能概念的模块,并使它们的外部接口尽可能少。高级模块将符合功能要求,而低级模块将与硬件资源(即设备驱动程序)紧密联系。

我花了大量时间维护详细的数据流程图1,该流程图精确地显示了各个模块如何共享信息。在实时性能方面,某些功能会有非常不同的要求。确保您知道信息共享如何影响这一点。该图具有跨越其边界的边界,该边界将非中断代码与各种中断驱动的域分开。


1与流程图非常不同,流程图专注于控制流程。


12

对于任何大型项目,即使我打算自己做整个事情,我也要计划好象涉及多个开发人员

原因很简单:

1复杂性。大型项目总是会涉及复杂性。计划该项目就好象涉及多个团队一样,这意味着已经考虑并记录了复杂性。我看到大型项目遇到问题的次数很高,通常是因为某些事情“从裂缝中溜走了”。别忘了还必须考虑机械组装,而不仅仅是考虑盒子的尺寸-是否需要散热器?为了安全起见,盒子必须接地吗?仅此类别中就有很多问题。

2要求。假设涉及到多个人,则意味着最高要求(我经常挑战这些要求,因为它们可能带来不必要的复杂性和成本)必须分解为各种较小的所需和可实现的任务(可以将其提交给较大组织中的另一个团队),而不是只看一个斑点。

3分区。有两种主要的分区类型:硬件功能和硬件/软件。第一种类型是确定需要提供哪些单独的(但正在通信)功能块。第二个是权衡较简单(有时)的硬件和软件,但请记住,仅将更多内容移至软件并不一定能解决硬件问题。在某些情况下(更多的处理能力,更复杂的接口等等),将更多的精力投入到软件中实际上可以大大增加硬件的复杂性。

4个接口。分区过程将有助于定义内部接口;外部接口通常是整体要求的一部分(尽管并非总是如此)。系统的不同部分可以通过多种方式进行协作,这可能是复杂的通信协议,也可能只是好/坏的信令。

5验证。这是低级别测试(针对硬件和驱动程序)和系统级别的混合。在定义明确的模块中完成项目可以进行可靠的验证(可以通过分析或实际测试,并且通常是两者的结合;对设计的更新可能使用相似性参数)。

6个标准。我使用编码和绘图标准,好像它是一个更大的团队。我使用Barr Group的编码标准,因为它们不太繁琐,但确实可以防止代码中出现许多类的错误。对于PCB输出文档,我遵循IPC-D-326(其称为IPC-D-325),因为这是一种将意图传达给PCB制造商和组装商的行之有效的方法。这看起来很奇怪,但是遵循纪律遵循许多标准意味着质量是一致的。

7版本控制。我将修订控制用于项目的所有部分(系统,硬件,软件,机械,测试要求-一切)。我使用的CAD工具支持所有软件和FPGA构建工具的版本控制。

我从事过许多嵌入式项目(周围有很多经验丰富的人),团队规模从1个(我自己)到数十个(或一组特定项目的数百个)不等,涉及多个学科,有时在地理位置上也很遥远网站。使用相同的总体方法(已知有效)意味着我可以相对隔离地接管特定任务并完成它,并作为较大项目的独立部分对其进行彻底测试。这也意味着如有必要,我有时可以将一些事情排除在外。

完成所有这些操作会增加一些前期时间,但最终对于复杂的嵌入式系统而言,这是一条更快的途径。


5

其他答案给出了很多很棒的技巧。在我的嵌入式开发生涯中,有两个最重要的发现:

  1. 将尽可能多的代码放入单独的,定义明确的模块中。
  2. 使模块在PC上可自动测试。

这就是在嵌入式系统上进行“连续集成”样式开发所需要的。总是会有一些与硬件紧密联系在一起的代码无法进行自动测试,但是请尽量减少代码。通过使用模拟数据或来自实际硬件的数据捕获,您可以走得更远,然后将其输入测试系统。


4

要添加到现有答案...

我总是从头开始。根据您的硬件设计,您知道您的I / O是什么。从构建封装该I / O的驱动程序模块开始,这样您的高级代码不必对低级内容有太多了解。

构建低级接口时,当然需要测试工具。如果您将其设计为从一开始就连接到PC(也许带有RS-232端口,也许是USB,也许是以太网上的telnet),则可以在构建应用程序时将该测试线束接口保持在原位。随着应用程序的成形,您可以继续添加更多的测试工具挂钩,这也将使您在进行代码时进行回归测试。


4

我倾向于思考四个问题。前两个属于系统项目的开始,下两个属于末尾。

  1. 他们实际上是否需要该系统?系统会在一定时间和成本范围内解决客户问题吗?一个常见的问题是构建客户不会使用的系统。

  2. 我们可以实际构建该系统吗?是否有可能提供必要的性能,精度,电源使用...?


创建早期原型是回答这两个第一个问题的好方法。在早期阶段,降低风险非常重要。


接下来的两个问题更针对项目的后期阶段:

  1. 我们真的完成了吗?一切设计,编码,测试,交付

  2. 他们实际使用该系统吗?

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.