我正在编写一个带有结构化模式的头文件。我的目标是定义一个在调用另一个宏后将递增的基址。这样做的目的是保持新基址的运行计数,并在编译时检查它是否超过最大物理地址。
我之前曾想过使用全局变量来计算地址,但这会在运行时解决,我需要在编译时,在输出任何二进制文件之前这样做,以防止可能的内存损坏。
这就是我的意思:
以下是我希望头文件在检查时看起来像(或等效的东西):
#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个字节的缓冲区。所以这意味着基地址可以是
这是否可以在编译器中使用(ARMCC RVCT 5.03)?
提前致谢
答案 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汇编程序及其宏功能,看看是否可以使用它。