我们将编写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)
假设
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;