用硬编码的内存地址主机testingC程序

我们将编写C代码的function/unit testing。 这个C程序将作为embedded式软件运行。 但是我们需要在Linux环境下运行testing。

问题是部分被测代码看起来像这样:

my_addresses.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主机环境下这样做不会那么顺利。

有没有办法在testing过程中解决这个问题? 我们可以以某种方式“redirect”程序来使用其他地址,这些地址是在testing过程中分配给内存的有效地址吗?

我们的第一个尝试是在testing期间用另一个头文件replace“my_addresses.h”,其中(extern)声明variables而不是硬定义 – 然后将malloc的内存分配给MY_BASE_ADDRESS等等。问题在于“static const”在c文件中声明。 当然,你不能把一个variables赋给一个静态的consttypes。

我们最好不要修改被testing的代码(尽pipe在最坏的情况下可能会这样)。

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

像例如

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

在Linux环境中,你可以定义一个全局数组,然后使用这个地址作为基指针。

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

假设

  • 您的嵌入式内存布局足够小,可以在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;