在调用另一个宏之后连续递增宏的值

时间:2014-10-02 22:34:35

标签: c macros c-preprocessor armcc

我正在编写一个带有结构化模式的头文件。我的目标是定义一个在调用另一个宏后将递增的基址。这样做的目的是保持新基址的运行计数,并在编译时检查它是否超过最大物理地址。

我之前曾想过使用全局变量来计算地址,但这会在运行时解决,我需要在编译时,在输出任何二进制文件之前这样做,以防止可能的内存损坏。

这就是我的意思:

以下是我希望头文件在检查时看起来像(或等效的东西):

#define DRAM_DEFINE_PTR              0x30000000
#define DRAM_DATA1_BASE              0x30000100
#define DRAM_DATA1_SIZE              0x050
#define DRAM_DATA2_SIZE              0x400
#define DRAM_DATA3_BASE              0x30000600
#define DRAM_DATA3_SIZE              0x300

#define DRAM_DEFINES(x,y)            (...) 
// store base 'x' and size 'y' in a structure and increment DRAM_DEFINE_PTR accordingly

1.     DRAM_DEFINES (DRAM_DATA1_BASE,        DRAM_DATA1_SIZE)
2.     DRAM_DEFINES (0x0,                    DRAM_DATA2_SIZE)   //base is previous base + size
3.     DRAM_DEFINES (DRAM_DATA3_BASE,        DRAM_DATA3_SIZE)
// more DRAM_DEFINES

实际上,下面的代码块会将第1行和第2行扩展为:

1.     DRAM_DEFINES (0x30000100,        0x50)
       // DRAM_DEFINE_PTR now equals 0x30000150

2.     DRAM_DEFINES (0x30000150, 0x400)
       // DRAM_DEFINE_PTR now equals 0x30000550

3.     DRAM_DEFINES (0x30000600 , 0x300)
       // DRAM_DEFINE_PTR now equals 0x30000900
and so on

然后在文件末尾进行#error检查以确保我们没有越过边界

#if (DRAM_DEFINE_PTR > 0x40000000)
   #error "\nCAPACITY EXCEEDED by ", DRAM_DEFINE_PTR - 0x40000000, " bytes"
#endif

从上面我们可以看出,并非每个内存区域都要完全使用。就像2到3之间一样,有50个字节的缓冲区。所以这意味着基地址可以是

  • 使用#define OR
  • 的硬编码值
  • 偏离先前区域的基数+之前区域的大小

这是否可以在编译器中使用(ARMCC RVCT 5.03)?

提前致谢

3 个答案:

答案 0 :(得分:1)

为什么不使用全局变量来存储地址?

答案 1 :(得分:1)

您可以使用Boost预处理器库evaluated slots functionality在翻译一个单元的过程中更新宏的值。它定义了几个"插槽"可以通过预处理器代码将其视为可变全局变量,这将允许您在进行时添加值,而不是使用单个固定表达式永久定义它。它是纯标准兼容的C(或C ++)。

主要的语法滋扰是你必须给自己提供两行更新操作,因为它由#define / #include对提供支持。

#define DRAM_PTR_SLOT 2    // any slot
#define DRAM_DEFINE_PTR BOOST_PP_SLOT(DRAM_PTR_SLOT)
#define SET_DRAM_DEFINE_PTR BOOST_PP_ASSIGN_SLOT(DRAM_PTR_SLOT)

#define BOOST_PP_VALUE 0x30000100 + 0x50
#include SET_DRAM_DEFINE_PTR    // DRAM_DEFINE_PTR now evals to 0x30000150

#define BOOST_PP_VALUE DRAM_DEFINE_PTR + 0x50
#include SET_DRAM_DEFINE_PTR    // DRAM_DEFINE_PTR now evals to 0x300001A0

它并不是非常优雅 - 没有办法将指令打包到另一个宏中,所以你无法将这个隐藏在类似问题的语法中 - 但你可能是能够至少隐藏自己的某些特定于域的包装器宏下的Boost名称。

答案 2 :(得分:0)

使用CPP可能无法做到这一点,因为它没有考虑到这样的设计。我将研究ARM汇编程序及其宏功能,看看是否可以使用它。