views:

107

answers:

5

Hi, im programming embedded devices and I was wondering what to use for a macrofunction, for example an init of some registers. should i make this static/const or define it as a macro?

for example, this:

 #define FPGA_INIT()\
{ \
  /* Set function and direction of start_code pin*/\
  P0SEL &= ~0x04; \
  P0DIR |= 0x04; \
  FPGA_START_CODE = 0; \
}

or this?

static void fpga_init()
{ 
  /* Set function and direction of start_code pin*/
  P0SEL &= ~0x04; 
  P0DIR |= 0x04; 
  FPGA_START_CODE = 0; 
}

And what's the difference in memory-placement?

+4  A: 

If you use a macro, then wherever you use it, the pre-processor will replace it with the full body of it. This means that if you call it say for 10 times, then you need 10 times more the memory. However the code will execute faster, since there isn't the overhead of making a function call.

I would in generally avoid using macros for functions. Macros are difficult to debug and maintain. A cleaner solution if you need in-place code is to use inline functions, which most modern compilers support.

kgiannakakis
"the code will execute faster": not necessarily, with a static function like this, the compiler knows every place it is called and therefore has the option of 'inlining' it anyway if it perceives this to be the better option. I'd stick with a function in this case (and most, but not all, other cases for that matter).
Al
Thanks.Unfortunately, my compiler doesn't support inline functions. (the curse of being an embedded programmer: The tools.....).A pro of using a macro is that you don't have to make prototypes (I hate prototypes, after working a few months in C#). In this case, I'll keep it as a macro, but I'll use more functions on my next 'project'. I recently noticed im implementing as much as i can as a macro, starting to get a bad habbit :p
SirLenz0rlot
In the init function is is actually space optimation you save maby hmm abaut 4 bytes memory. But this is not sure. The compiler can make extract same code because we don't need use stack here (we don't have arguments and we don't return value).I recomment funtions for cleaner solution. It is unusual that you run out of memory.
Tuukka
+1  A: 

A macro saves you the overhead of a function call during operation (speed).

A function saves you the overhead of having the same code in multiple places (program space).

Pick which of speed and space is more critical for you and use the approprate option.

Vicky
+6  A: 

In general, it is best to reserve the use of preprocessor macros for times when you need the capability of the preprocessor to manipulate the code before it is compiled---you should not use preprocessor macros to define procedures that can be implemented as normal functions. Because the preprocessor substitutes the macro code wherever the macro is invoked, it can be difficult to debug errors that occur. For example, if you call your FPGA_INIT() macro, the (presumably) global variables P0SEL, P0DIR, and FPGA_START_CODE might be hidden by locals of the same name.

If you declare a fpga_init() function, the compiler will place the code for that function along with the code for other functions you declare, according to whatever rules it knows for the platform you are targeting. If you declare a FPGA_INIT() macro, the compiler will never know it exists, as all references to it will be resolved by the preprocessor; the compiler will see and compile the macro's statements separately within each function it was invoked.

Unless you need to call this code with great frequency (in an inner loop), the performance of the macro and function implementations will likely be indistinguishable. If you do need to call the code frequently, you should try measure the performance each way: depending on the architecture of your processor, it may be faster to use the preprocessor to place the code inline, or it may be faster to have the code in a separate function (particularly if expanding every invocation causes an important loop to overflow a cache line).

Matthew Xavier
An optimizing compiler will inline small static functions anyway (and large ones, if they are only called once), so a macro wins you less than nothing in that case. So even calling the function within a loop is not something to worry about.
Tim Schaeffer
A: 

Trust your compiler- make it a regular function, let the compiler pick what to do with it.

DeadMG
Dude, you have an awful lot of faith in embedded compiler toolchains, some of them need all the help they can get. Especially anything esoteric, echelon lonworks transceivers as an example. Of course some compilers are very good with whole program optimization etc.
Hayman
+1  A: 

Put the function into a header file and prefix with the inline keyword:

inline void fpga_init()
{ 
  /* Set function and direction of start_code pin*/
  P0SEL &= ~0x04; 
  P0DIR |= 0x04; 
  FPGA_START_CODE = 0; 
}

The inline keyword recommends that the compiler place the statements "in-inline" with other code, similar to a #define macro. This is better than a macro because it behaves like a function and doesn't have the pitfalls of a macro.

Thomas Matthews