将“getter”函数replace为macros查找

问题

我试图通过大型平台抽象库(PAL)将多个基于硬件的产品移植到资源有限(即千字节计数 )的小型embedded式系统中。

目前的PAL有一个简单的getRegister()函数,它返回一个特定产品的寄存器地址。 例如,假设产品名为coconutpineapple ,代码将如下所示:

 #include "headers/Include/coconut.h" #include "headers/Include/pineapple.h" enum prodType { PROD_COCONUT = 0, PROD_PINEAPPLE, PROD_MAX, PROD_INVALID = (-1) }; uint64_t getRegister(enum prodType prod, int regName) { uint64_t r = 0; switch (prodType) { case PROD_COCONUT: switch (regName) { case REG_BASE: r = COCONUT_REG_BASE; break; case REG_CORE: r= COCONUT_REG_CORE; break; } break; case PROD_PINEAPPLE: switch (regName) { case REG_BASE: r = PINEAPPLE_REG_BASE; break; case REG_CORE: r= PINEAPPLE_REG_CORE; break; } break; default: // Error. break; } return r; } 

目标

我想改变这个函数是一个简单的编译时macros,因此getRegister(PROD_COCONUT, REG_BASE)只是查看一个值表并返回相应的寄存器值。 原因是,如果我知道一个平台只支持coconut ,我可以使用macros来不包含其他产品(即pineapple )的标题,并减less程序的大小。


迄今为止工作

到目前为止,我正在考虑这样的事情:

 enum regs { REG_BASE = 0, REG_CORE, REG_MAX, REG_INVALID = (-1) }; struct keyValPair { int idx; enum reg; uint64_t val; }; struct keyValPair tableCoconut[] = { { 0, REG_BASE, COCONUT_REG_BASE }, { 1, REG_CORE, COCONUT_REG_CORE }, }; 

所以,我想能够做一些索引到表中的效果,以便tableCoconut[REG_BASE]返回COCONUT_REG_BASEO(1)时间返回一个值,而不必在表中迭代/search。 理想情况下,这是一个编译时的macros扩展,而不是一个真正的函数调用。


是否有(简单/干净)的方式来实现一些中间映射,以便:

  • 我可以从我的keyValPair结构( 可选 )中删除idxvariables。
  • 有一个O(1) (即不基于search的查找)的映射( 必需 )?

这是假设寄存器值是不连续和唯一的? 我正在考虑使用几年前的一些类似的问题 ,但是不能完全用macros来得到这种双射分离的连续映射。 我试图也许通过macros和##操作创build一个自动递增索引值通过与预处理器的##连接操作创build一个中间索引与一个前缀附加到REG_BASE / REG_CORE

编辑

并非所有的产品都有相同的寄存器。 BANANA_REG_CORE中可能没有提供条目的banana产品。

假设你的枚举从0开始,然后从那里依次上升,你可以使用枚举值直接索引到一个数组中,并检索你想要的值。 虽然这可能不会发生在编译时,数组查找是O(1),所以它应该是快速的。

所以你可以像这样构建一个数组:

 uint64_t tableCoconut[] = { COCONUT_REG_BASE, COCONUT_REG_CORE }; 

tableCoconut[REG_BASE]tableCoconut[REG_CORE]会给你你想要的值在O(1)。

您可以进一步扩展以考虑多个产品:

 uint64_t tableAll[2][2] = { { COCONUT_REG_BASE, COCONUT_REG_CORE }, { PINEAPPLE_REG_BASE, PINEAPPLE_REG_CORE }, }; 

并执行O(1)查找,如tableAll[PROD_COCONUT][REG_BASE]tableAll[PROD_PINAPPLE][REG_BASE]