代码之家  ›  专栏  ›  技术社区  ›  eaanon01

模拟中的存根函数

  •  6
  • eaanon01  · 技术社区  · 17 年前

    我正在从事一个依赖于外部硬件的嵌入式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

    编辑:

    如果可以在不替换整个文件的情况下选择/重命名函数,那就太好了。就像从开始的所有函数一样 nRF_## 然后给一个新名字,然后插入 test_nRF_## nRF_##

    3 回复  |  直到 17 年前
        1
  •  9
  •   Gerhard    17 年前

    我只是让两个文件ActualDriver.c和StubDriver.c包含完全相同的函数名。通过创建两个构建,将生产代码与不同的对象链接起来,就不会有命名冲突。这样,生产代码就不包含测试或条件代码。

        2
  •  1
  •   JeffV    17 年前

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

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

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

        3
  •  1
  •   jakobengblom2    17 年前

    我同意上述说法。标准解决方案是定义一组不透明的抽象函数调用,这些函数调用是硬件的“驱动程序”,然后在主程序中调用。然后提供两种不同的驱动程序实现,一种用于硬件,一种用于软件。sw变型将以某种适当的方式模拟硬件的IO效应。

    请注意,如果目标是在较低的级别上,即编写模拟每个硬件访问而不是整个功能的代码,则可能有点麻烦。但在这里,可以定义不同的“写入内存”和“从内存读取”函数(或宏,如果目标速度至关重要)。

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

    Qemu , Simics , SystemC CoWare VaST ,或类似的。这使您可以一直运行相同的代码,并构建一个硬件模型,从软件的角度来看,该模型的工作方式与实际硬件类似。这确实需要更大的前期投资,但对于许多项目来说,这是非常值得的。它基本上消除了为目标和主机生成不同版本这一令人讨厌的问题,并确保始终将交叉编译器与部署版本选项结合使用。请注意,许多嵌入式编译器套件都内置了一些基本的模拟功能。