用硬编码内存地址测试主机C程序

用硬编码内存地址测试主机C程序,c,linux,unit-testing,memory-management,functional-testing,C,Linux,Unit Testing,Memory Management,Functional Testing,我们将为C代码编写功能/单元测试。此C程序将作为嵌入式软件运行。但是,我们需要在Linux环境中运行测试 问题是,测试中的部分代码如下所示: 我的大学地址。h: #define MY_BASE_ADDRESS (0x00600000) #define MY_OFFSET_ADDRESS (0x108) 我的密码是c #include "my_addresses.h" static const My_Type* my_ptr = (My_Type*)(MY_BASE_ADDRE

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

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

我的大学地址。h:

#define MY_BASE_ADDRESS     (0x00600000)
#define MY_OFFSET_ADDRESS   (0x108)
我的密码是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”声明。当然,不能将变量分配给静态常量类型


最好不要修改测试中的代码(尽管在最坏的情况下可能会出现这种情况)。

您可以检查
\uuuuuu linux\uuuu>宏,并使用条件编译。在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\u 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;

这并不像现在这样实际。。。我认为一开始就不应该这样。究竟为什么地址会硬编码在报头中?你目前的问题是你通过不这样做而避免的许多问题之一。要么将对象更改为硬编码的地址,要么更改这些地址的用法以获得所需对象的真实位置。@Eregrith是的,这不实用(至少对于主机测试而言)。但事实就是这样,我们无能为力。这应该是
静态常量My_Type*My_ptr
?或者你有类似于
typedef M_Type\u t*My_Type
的东西吗?@pjtrail是的,正确。“My_Type”应该是指向类型的指针的typedef。更新问题以使情况更清楚(改为将其作为指向My_Type的指针)。如果有很多这样的内容,您可能更喜欢定义一个中间宏,例如
\ifdef\uu linux\uuuuuu
\define FIXED_ADDRESSES 1
\else
\code>\define FIXED_ADDRESSES 0
\endif>
#如果地址固定
等,甚至
#ifdef(linux)
#定义地址(固定、类型、名称、大小)固定
#否则
#定义地址(固定、类型、名称、大小)类型名称[大小]。。。老鼠,这个版本是不会飞的<代码>#endif