【问题标题】:Host testing C program with hard coded memory addresses使用硬编码的内存地址主机测试 C 程序
【发布时间】:2015-05-19 16:19:42
【问题描述】:

我们将为 C 代码编写功能/单元测试。该 C 程序将作为嵌入式软件运行。但是我们需要在 Linux 环境中运行测试。

问题是被测试的部分代码如下所示:

我的地址.h:

#define MY_BASE_ADDRESS     (0x00600000)
#define MY_OFFSET_ADDRESS   (0x108)

my_code.c

#include "my_addresses.h"

static const My_Type* my_ptr =
  (My_Type*)(MY_BASE_ADDRESS + MY_OFFSET_ADDRESS);

/* my_ptr is dereferenced and used ... */

显然,这不会在 Linux 主机环境中运行得那么好。

在测试期间有什么方法可以解决这个问题吗?我们能否以某种方式“重定向”程序以使用其他地址,即测试过程中分配的内存的有效地址?

我们的第一次尝试是在测试期间用另一个头文件替换“my_addresses.h”,该文件(extern)声明变量而不是硬定义 - 然后将 malloc 的内存分配给 MY_BASE_ADDRESS 等。问题是“ c 文件中的 static const" 声明。当然,您不能将变量分配给静态 const 类型。

我们最好不要修改被测代码(尽管在最坏的情况下可能会发生这种情况)。

【问题讨论】:

  • 这实际上并不实用......我认为它首先不应该那样工作。为什么地址会被硬编码在标题中?您当前的问题是您通过不这样做避免的众多问题之一。要么将对象更改为 硬编码地址,要么更改对这些地址的使用以获取所需对象的真实位置。
  • @Eregrith 是的,这不切实际(至少对于主机测试而言)。但事情就是这样,我们无能为力。
  • 应该是static const My_Type * my_ptr ?或者你有类似typedef M_Type_t * My_Type的东西吗?
  • @PJTraill 是的,正确的。 “My_Type”应该是指向类型的指针的 typedef。更新问题以使情况更清楚(将其写为指向 My_Type 的指针)。

标签: c linux unit-testing memory-management functional-testing


【解决方案1】:

您可以检查例如__linux__ 宏并使用条件编译。在 Linux 上使用数组作为基础,并使其足够大以保存所需的所有数据。

类似的东西,例如

#ifdef __linux__
int8_t array[1024];
# define MY_BASE_ADDRESS array
#else
# define MY_BASE_ADDRESS 0x00600000
#endif

【讨论】:

  • 如果有很多这样的东西,你可能更喜欢定义一个中间宏,例如#ifdef __linux__ #define FIXED_ADDRESSES 1 #else #define FIXED_ADDRESSES 0 #endif ... #if FIXED_ADDRESSES 等等 甚至#ifdef __linux__ #define ADDRESS_DECL(fixed, type, name, size) fixed #else #define ADDRESS_DECL(fixed, type, name, size) type name [size]; ... 老鼠,这个版本不会飞! ...#endif
【解决方案2】:

在 Linux 环境中,您可以定义一个全局数组,然后将其地址用作基指针。

const char my_buffer[1024];
#define my_base_addr (&my_buff)

【讨论】:

    【解决方案3】:

    假设

    • 您的嵌入式内存布局足够小,可以在 Linux 上对其整体(或几个块)保持不变,
    • 您的编译器对下面的常量内存地址表达式很满意,并且
    • My_Type 在您的示例中被定义为 typedef My_Type1_t * My_Type;

    您可以 (1) 将嵌入式内存布局的定义与决定它的放置方式分开,也许 (2) 如果您为布局声明 struct,则可能获得一些类型安全:

    #pragma (essential: stuff to force structs to contain no extra padding)
    typedef struct {
      char pad0[0x108];
      My_Type1_t foo;
      char pad1[0x210];
      My_Type2_t bar;
      ...
    } Memory_Layout_t;
    #pragma (preferably: something to revert to previous struct layout options)
    

    (如果您不喜欢计算pad1 的大小,请使用union。)

    然后制作变体:

    #ifdef __linux__
    Memory_Layout_t Embedded_Memory;
    #  define Embedded_Memory_P (& Embedded_Memory)
    #else
    #  define Embedded_Memory_P ((Memory_Layout_t *) (0x00600000))
    #endif
    

    并引用它

    static const My_Type my_ptr = & Embedded_Memory_P->foo;
    

    【讨论】:

      猜你喜欢
      • 2012-08-06
      • 1970-01-01
      • 2014-01-26
      • 1970-01-01
      • 2018-06-09
      • 2018-11-20
      • 1970-01-01
      • 2012-12-11
      • 2015-06-28
      相关资源
      最近更新 更多