【发布时间】:2021-08-17 08:19:12
【问题描述】:
我们需要为外部存储器创建一个静态地址表。 存储结构的大小是已知且固定的。但是,这些结构的地址必须从内存段的开头开始。 我们打算通过使用宏来做到这一点,因为在编译时让表格随着表格元素的变化而变化。
实现看起来像这样:
#define BLOC (0xFF)
#define FINAL_ADR(N) (ADR_##N + SIZE_##N)
#define GET_ADR(N) (FINAL_ADR(N) + (BLOC - (FINAL_ADR(N) & BLOC)))
#define ADR_0 (0x0)
#define SIZE_0 (5)
#define ADR_1 GET_ADR(0)
#define SIZE_1 (300)
#define ADR_2 GET_ADR(1)
#define SIZE_2 (130)
...
const struct {
uint32_t addr, size;
} mem[] = {
{.addr = ADR_0, .size = SIZE_0},
{.addr = ADR_1, .size = SIZE_1},
{.addr = ADR_2, .size = SIZE_2},
};
上面的代码尝试根据元素的前一个地址和大小来分配一个地址。
- 元素 0 从位置 0x00 开始,占用 5 个字节(1 个部分)。
- 元素 1 应从位置 0xFF 开始并占用 300 字节(2 个部分)。
- 元素 2 应从位置 0x2FD 开始并占用 130 个字节(1 个部分)。
如果我们尝试实现上面的宏,编译器就会失败。因为宏在元素 2 处引用自己:
ADR_2 = ((GET_ADR(1)+ SIZE_1) + (0xFF- ((GET_ADR(1)+ SIZE_1) & 0xFF)))
是否可以绕过这个间接自引用宏?有没有更好的方法来做到这一点?
【问题讨论】:
-
IMO 这毫无意义。
-
我不确定您要做什么,但我的印象是编写一个生成表的外部程序并在构建过程中包含该程序的执行听起来更容易。
-
我们有一些应用程序数据需要存储在外部存储器中。这些结构的大小是已知的并且是固定的。但是,这些结构的地址必须从内存部分的开头开始。上面的代码('GET_ADR')试图做的是从最后一个开始计算结构的起始地址。
-
为此使用链接器脚本,不必自己计算