编写不带硬件的嵌入式软件


8

考虑到硬件团队将花费两个月的时间来开发一些硬件,但是到那时我将需要准备好软件。

我的问题是,如何在没有硬件的情况下编写软件并进行测试?

是否要遵循任何标准?你怎么做呢?


根据硬件的复杂程度,您可以尝试使用模拟器。如果它只是具有简单外围设备的微控制器,那将是相当可行的。不仅如此,您在那条路线上还不走运。
2016年

6
尝试找到适用于您使用的微型计算机和任何其他外围设备的开发板,并尝试以最类似于您的硬件团队设计的方式将它们全部连接起来。它将是一个大而丑陋的问题,但是您应该能够构建一个与真实事物足够接近的系统-至少在您的固件可以
识别的范围内

最糟糕的是,如果您不能正确地模拟硬件,则可以禁用它。就在几周前,我想测试与另一个程序的网络通信,却发现这是exit()因为它试图映射/ dev / mem中的硬编码地址。
isanae '16

1
实际上,在许多情况下,使用模拟器进行嵌入式软件开发实际上是可取的-调试起来容易得多。当然,问题在于您需要一个不错的模拟器。有时候会有一个通用的人可以适应,有时候一个聪明的实习生可以用咖啡因推动的编码狂潮来写一个。
2016年

Answers:


34

在固件开发的初始阶段没有硬件会发生。解决此问题的常见策略是:

  1. 在编写任何代码之前,请花一些时间仔细地架构系统。当然,您仍然应该这样做,但是在这种情况下,它比平时更重要。与基于面食的混乱相比,调试经过深思熟虑的软件要容易得多。

  2. 适当地模块化一切,最大程度地减少模块之间的接口。这将有助于包含各个模块的错误,并使单个模块的测试更加容易。

  3. 自底向上编写代码,硬件接触的驱动程序优先,高层应用程序逻辑紧随其后。这样可以尽早发现架构带来的不便。随着硬件的出现,不要害怕更改体系结构,但要确保所有文档都已相应更新。

  4. 模拟。大多数微控制器公司都提供其微控制器的软件模拟器。这些只能走得很远,但仍然非常有用。模拟硬件的输入和测量输出可能很困难,但是以这种方式检查高级逻辑并不难。

    这是模块化设计再次提供帮助的地方。如果您不能合理地模拟某些低级别的硬件交互,则可以使用该模块的另一个版本,该版本接触该硬件,但会将其自己的模拟动作传递给更高级别。高层不知道这种情况正在发生。您将不会以这种方式检查低级模块,但是大多数情况下都是如此。

简而言之,请使用良好的软件设计规范,无论如何您都应该这样做。


要添加:在ASAP中获得开发板(是的,多个,因为您可能会杀死至少一个...),并准备好低层驱动程序。尽可能对单元代码进行单元测试。是的,您可以统一硬件接触代码。不,您不能完全模拟硬件,但是即使在第一次刷新之前,也可以正确获得90%的功能。我在一个最近的项目中完成了所有上述工作,当真正的硬件出现时,我们已经具备了99%的功能并可以正常工作。
CHendrix

13

没有任何关于您正在开发的东西或您的硬件最终将基于哪个微控制器家族的见识,大多数微控制器家族都有可用的低成本开发系统,这些系统上有一套通用外围设备,这可能使您能够模拟至少一些最终目标硬件。


1
同意 我会说得更厉害。在这种情况下,必须与硬件同时完成软件,我只会使用具有合适开发或评估板的微控制器。
史蒂夫G

即使您确实了解OP正在开发什么,大多数微控制器系列仍然提供可用的模拟器。
Olin Lathrop

我同时使用两种方法。但是,我还要关注所需的生产线测试设备。您可以与生产工程师和设计硬件一起测试驱动程序,然后将其形成生产测试的一部分。如果幸运的话,他们甚至可以为开发板/原型构建硬件,因此他们也领先于该过程。这完全取决于您如何提出帮助请求……
Spoon

这是对这个问题的最佳答案,因为在PCB上尝试之前,我总是有一个开发板来首先对核心功能进行编程。
lucas92 '16

2

根据应用程序对硬件的依赖程度,您可以开始在标准PC(Windows,Linux ...)上实施该项目。无论如何,大多数外围设备访问都应该被抽象化,因此实现一些虚拟功能并不是什么大不了的事情,这些功能稍后将被替换。如果无法模拟某些行为,则至少可以对系统进行建模(API ...),因此,一旦硬件准备就绪,实际的实现将变得更快,更清晰。

当然,有很多事情是无法模拟的,例如实时行为或复杂的硬件驱动程序。另一方面,可以使用从文件或网络端口读取值的线程轻松模拟中断驱动的ADC。

当然,所有这些都高度取决于各种因素:

  • 您可以在控制器和PC(例如gcc)上使用相同/相似的工具链吗?
  • 系统对硬件的依赖性如何?
  • 您对PC编程的经验如何?

我首先要在PC上设计几乎每个固件模块。


同样在这里。编译器(内部语言,特殊关键字,闭源OS和网络堆栈与BSD不太兼容)之间的某些差异和错误(与C ++一起)迫使大量使用特定于文件的预先包含的文件和预处理器,但是DSP本身的代码几乎可以完全相同和PC。对于PC版本,我可以使用繁重的运行时错误检查(CodeGuard),并且其调试功能无法在嵌入式平台上实现。额外的好处是,对于任何网络和负载测试,我几乎没有额外的虚拟设备。
TMSZ

有了Raspberry Pi和BeagleBone的可用性,您的开发环境就可以轻松地成为您的运行时环境-工具链等没有问题。此外,您可以使用valgrind / helgrind,gdb等
。– jhfrontz

1

尝试为您的芯片获得一个模拟器。您应该模拟所有预期的输入以及一些意外的输入。尽可能模块化/抽象并编写单元测试。如果可以的话,这些测试可以成为您实际代码的一部分,并将它们转变为功能(板载自测)。

如果您无法获得模拟器,则可以通过HAL(硬件抽象层)来尽可能多地进行抽象。所有驱动程序都支持它。尝试在某些C函数调用之后抽象所有特定于平台的程序集,并将其也视为驱动程序。将其余部分编写为可移植的C / C ++代码,并为x86创建一个瘦的HAL,并在所有测试用例的计算机上运行它。

这样,当您获得硬件时,只需调试HAL。它越薄,调试起来就越快,并且一切正常。请记住,如果你使用的平台特定的汇编更快OPS,DO很想得到位精确检验


如果使用定点DSP,则位精确度特别重要。
RonanPaixão16年

它可能适用于或可能不适用于特定情况,但总的来说,精确度是有代价的。QEMU最近(2年前)决定实施精确的FPU,它猜测性能会发生什么变化?
德米特里·格里戈里耶夫

使用FPU时位精度并不重要。但是,如果使用定点,则非常重要。特别是因为软件定点在任何地方都需要额外的检查。
RonanPaixão16年

这是不良编码实践的结果。人们已经学会了在a == b对浮点数进行比较时采取预防措施,但是他们仍然盲目地使用定点数进行比较。
德米特里·格里戈里耶夫

尽管不良的编码实践是一个问题,但还有许多其他问题,尤其是在边缘情况下。很快就会想到溢出精度损失舍入饱和度宽度与位移之间的关系也是如此。有了所有这些,很容易忽略普通测试用例中的一些精度损失。问题是当您的应用程序遇到的情况较少且错误从小数位变为整数位时,如果范围计算错误,则会发生这种情况。只需查看MATLAB的Fixed-Point Designer的功能页面,就可以一窥其他问题。
RonanPaixão16年

1

您的问题有点广泛。硬件(HW)可能意味着完全定制ASIC / FPGA开发,汇编程序编程的DSP,或者“仅”基于现成的微处理器/微控制器/ SoC等的典型嵌入式系统。(当然,SoC可能还包含DSP您可能要编程...)。对于高销售量,使其成为ASIC并不少见。

但是对于一个为期2个月的项目,我希望它基于某些微控制器:

无论如何,您应该强调硬件团队给您一个原型,您可以在绝对期限之前开始测试您的代码-正如某些人已经提到的那样,它可能包括一个通用开发板,但我认为这是他们的职责。为您提供合适的设备,并可能还会提供一些必需的/类似的外围设备进行测试。

模拟器在某种程度上也是可能的,但是您可能仍需要表征一些您可能获得的真实世界的传感器/数据。在这里,硬件团队还需要至少为您提供帮助。

除此之外,软件设计已经可以完成,并且所有高级模块都可以(并且应该)在没有真正硬件的情况下实现和进行单元测试。理想情况下,您还将与硬件团队一起定义一个API,它们将为您提供最低级别的功能,因此它们在硬件方面所做的任何更改(例如,简单地重新定义它们使用的端口引脚)都不会总是对你至关重要

在所有情况下,沟通都是关键。


0

是的,您可以在目标板生产之前为目标板开发代码。

怎么样 ?

首先,您必须了解该系统的主要目标。因此,您可以从大量的可用资源(如digikey,mouser)中适当选择控制器。

并选择Proteus之类的模拟器。现在您可以开始编码,它将模拟确切的处理器/控制器。但是您不能期望像硬件一样的准确性。


为什么要投票?我可以知道这个答案有什么问题吗?
Photon001
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.