C preproc:粘贴有效令牌和令牌值

时间:2014-08-25 18:16:29

标签: c token c-preprocessor stm32 pasting

我正在使用STM32F1微控制器,为此提供了一个标头,用于定义寄存器的位掩码和值,如下所示:

#define RCC_CFGR_PLLMULL    //Mask of PLL multiplier setting bits
#define RCC_CFGR_PLLMULL1   //Value of PLL multiplier bits for PLL x1
#define RCC_CFGR_PLLMULL2   //Value of PLL multiplier bits for PLL x2
#define RCC_CFGR_PLLMULL3   //Value of PLL multiplier bits for PLL x3

等等。

我想要做的是将PLL乘数定义为整数,以便我可以使用它来推导时钟值 - 即PLLCLK = IN_CLK * PLL_MULT - 并将值粘贴到RCC_CFGR_PLLMULL以获得正确的设置位。我通常用于此的宏如下:

#define APPEND_VAL_HELPER(A, B)   A##B
#define APPEND_VAL(A, B)          APPEND_VAL_HELPER(A,B)

然后,如果我将SOME_NUM定义为123:

#define FOO                       APPEND_VAL(BAR, SOME_NUM)

FOO定义为BAR123的结果。通常这是有效的。这就是问题所在:在这种情况下,RCC_CFGR_PLLMULL是粘贴之前的有效令牌。这导致它在APPEND_VAL的调用中扩展,我得到类似((uint32_t)0x003C0000)123的东西。我无法弄清楚如何扩展B而不扩展A,至少在GCC中是这样。有一些解决方法,但我正在寻找一个干净的解决方案。它存在吗?

1 个答案:

答案 0 :(得分:0)

我不确定你会考虑什么"清洁"解决方案,但这对我有用,并且看起来不太糟糕:

/* target header */
#define RCC_CFGR_PLLMULL         0x003C
#define RCC_CFGR_PLLMULL1        0x0003

/* pasting macros */
#define APPEND_VAL_HELPER(A, B)  A ## B
#define APPEND_VAL(A, B)         APPEND_VAL_HELPER(A, B)
#define RCC_CFGR(T, N)           APPEND_VAL(RCC_CFGR_, APPEND_VAL(T, N))

您可以将其用作例如

#define FOO RCC_CFGR(PLLMUL, 1)

您也可以

#define BAR RCC_CFGR(PLLMUL, )

BAR定义为RCC_CFGR_PLLMUL(无尾)。

显然,这是特定于可能的目标宏的一个子集,但它完成工作并干净地读取。据我所知,没有办法编写一个完全通用的令牌粘贴宏 - 那些最常见的宏会遇到诸如你描述的问题之类的问题。