我正在开发一个依赖于某些外部硬件的嵌入式C项目。我希望删除访问这些部分的代码,这样我就可以在不使用任何硬件的情况下模拟系统。到目前为止,我已经使用了一些宏,但这迫使我改变我的生产代码,我想避免。

实施例

stub.h
#ifdef _STUB_HW
#define STUB_HW(name) Stub_##name
#else /*_STUB_HW*/
#define STUB_HW(name) name
#endif /*_STUB_HW*/

my_hw.c
WORD STUB_HW(clear_RX_TX)()
{ /* clear my rx/tx buffer on target HW */ }

test_my_hw.c
#ifdef _STUB_HW
WORD clear_RX_TX()
{ /* simulate clear rx/tx buffer on target HW */ }

使用此代码,我可以使用预处理程序标记 _STUB_HW 打开/关闭存根

有没有办法在不必更改我的prod代码和避免大量ifdef的情况下完成此操作。如果我可以避免,我不会在同一个文件中混合使用prod和test代码。我不关心测试代码的外观,只要我能尽可能多地保留生产代码。

编辑:

如果可以在不替换整个文件的情况下选择/重命名函数,那将会很好。就像从 nRF _ ## 开始所有函数然后给出一个新名称,然后将 test_nRF _ ## 插入 nRF _ ## ,如果它是可行的

有帮助吗?

解决方案

我只创建两个文件ActualDriver.c和StubDriver.c,它们包含完全相同的函数名称。通过将生产代码与不同对象相关联的两个构建,没有命名冲突。这样,生产代码不包含测试或条件代码。

其他提示

正如Gerhard所说,使用一个公共头文件“driver.h”。以及包含实际和存根函数的单独硬件层实现文件。

在eclipse中,我有两个目标,而且“从构建中排除”。不使用的driver.c文件,并确保构建中包含正确的文件。 Eclipse然后在构建时生成makefile。

要指出的另一个问题是确保定义固定大小的整数,以便从溢出角度看代码的行为相同。 (虽然从您的代码示例中我可以看到您正在这样做。)

我同意上述内容。对此的标准解决方案是定义一组不透明的抽象函数调用,这些函数调用是“驱动程序”。到hw,然后在主程序中调用它。然后提供两种不同的驱动程序实现,一种用于hw,一种用于sw。 sw变体将以某种适当的方式模拟hw的IO效果。

请注意,如果目标是较低级别,即编写要模拟每个硬件访问的代码而不是整个函数,则可能有点过时。但是在这里,不同的“write_to_memory”和和“read_from_memory”和“read_from_memory”。功能(或宏,如果目标上的速度是必要的)可以定义。

在任何一种情况下都不需要更改函数名称,只需要两个不同的批处理文件,make文件或IDE构建目标(取决于您使用的工具)。

最后,在许多情况下,更好的技术解决方案是使用完整的目标系统模拟器,例如 Qemu Simics SystemC CoWare VaST 或类似内容。这使您可以始终运行相同的代码,而是从软件的角度构建一个与实际硬件类似的硬件模型。它确实需要更大的前期投资,但对于许多项目来说,这是值得的。它基本上摆脱了为目标和主机提供不同构建的令人讨厌的问题,并确保始终将交叉编译器与部署构建选项一起使用。请注意,许多嵌入式编译器套件都内置了一些基本的模拟功能。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top