5

I am trying to invoke the following macro in my .cpp file:

#define IAP_ROM_LOCATION                0x1FFF1FF1UL
#define IAP_EXECUTE_CMD(a, b)           ((void (*)())(IAP_ROM_LOCATION))(a, b)

However, when I call said function like so:

IAP_EXECUTE_CMD(0, 0);

I get an error saying too many arguments specified? How is this? I would appreciate any pointers.

Development environment is GCC for Cortex-M3.

Paul R
  • 202,568
  • 34
  • 375
  • 539
James
  • 2,356
  • 2
  • 24
  • 49

4 Answers4

15

For readability, define a signature for the function to be called:

typedef void signature_t(int, int);

Then you can cast your ROM location

#define IAP_EXECUTE_CMD(a, b)  ((signature_t*)IAP_ROM_LOCATION) ((a),(b))

and with a recent GCC (current version of GCC is 4.6) I would make that an inline function

static inline void iap_execute_cmd(int a, int b) {
    ((signature_t*)IAP_ROM_LOCATION) ((a),(b));
}
Basile Starynkevitch
  • 216,767
  • 17
  • 275
  • 509
5
(void (*)())(IAP_ROM_LOCATION)

This part casts IAP_ROM_LOCATION to a pointer to a function that takes no arguments and returns nothing (void (*)()). Hence you get an error when you want to pass any arguments to that function.

Björn Pollex
  • 72,744
  • 28
  • 189
  • 274
2

You can also do it with macros only:

#define IAP_ROM_LOCATION        0x1FFF1FF1UL
#define IAP_FUNC_SIGNATURE      void (*)(int, int)
#define IAP_EXECUTE_CMD(a, b)   ((IAP_FUNC_SIGNATURE)(IAP_ROM_LOCATION))((a), (b))
Agnius Vasiliauskas
  • 10,657
  • 5
  • 47
  • 68
1

OK, my C is rather rusty, but it seems to me that your IAP_EXECUTE_CMD() macro is casting the unsigned long address as a pointer to a function which returns void and accepts zero arguments. Therefore, any arguments passed to the function call would be too many.

Mike Nakis
  • 50,434
  • 8
  • 92
  • 124