3

マクロ展開の順序を制御/指定する方法について誰かがアイデアを持っていることを願っています。コンテキストは次のとおりです。


// 32 bit increments, processor has registers for set, clear and invert
#define CLR_OFF 1
#define SET_OFF 2
#define INV_OFF 3


#define SET(reg,bits) *((volatile unsigned long*)(& reg+SET_OFF)) = bits
//Now if I use this I can do it quite nicely with
#define STATUS_LED 0x0040;
SET(LATB, STATUS_LED); // LATB is port of the LED.

最近、ハードウェアをかなり動かさなければならなかったので、LATB 情報を STATUS_LED とグループ化することにしました...


#define STATUS_LED_PORT LATB
#define STATUS_LED_MASK 0x0040;
#define STATUS_LED STATUS_LED_PORT, STATUS_LED_MASK

//And I try to use it via
SET( STATUS_LED );

しかし残念なことに、SET マクロの引数 1 に LATB,0x0040 が渡されます。マクロとして使用しない場合、このメソッドは適切に機能します。


inline void SET(u32_t *reg, u32_t bits) { ((volatile u32_t *) (((u32_t)reg) + SET_OFF*4 )) = bits; }
//Change the STATUS_LED macro to
#define STATUS_LED &STATUS_LED_PORT, STATUS_LED_MASK
SET( STATUS_LED); //Works great!

しかし、残念ながら、私のコンパイラは関数をインライン化する必要性を認識しておらず、4 ではなく 6 つの命令でレジスタを設定するため、ビットバンギング中に使用する場合は予測できません。

誰かが最初に STATUS_LED マクロを展開する方法を知っていることを願っています。 SET( ##STATUS_LED )

現在、先に進むための私の解決策は、SET と SETRM (set register、mask) の 2 つのマクロを使用することですが、SET のコードが次のように見えるため、解決策があるはずだと感じています...


#define SETRM(reg,bits) ...
#define SET(args) SETRM(args) //WHY WOULD THIS GET EXPANDED HERE??

そして最後に、私のプロセッサのコンパイラはマクロへの n 引数をサポートしていません。

お時間をいただきありがとうございます。ご意見をいただければ幸いです。先に進むことができますが、どこでも SET を使用できれば、はるかにクリーンになります。

4

2 に答える 2