Reputation: 705
I have microcontroler that I am working with. When debugging it is necessary to call a function from that is hard coded in ROM. Technical Reference shows how to do this:
# define Device_cal (void(*)(void))0x3D7C80
and calling procedure looks like this:
(*Device_cal)()
I can't understand what actually happens here, so my question is: How does it work?
Upvotes: 5
Views: 1092
Reputation: 93476
This is not an answer (that has already been done satisfactorily), but some advice:
I would suggest the following method instead:
typedef void (*tVOID_ROMFUNCTION_VOID)( void ) ;
tVOID_ROMFUNCTION_VOID Device_cal = (tVOID_ROMFUNCTION_VOID)0x3D7C80 ;
Device_cal() ;
That way you can create any number of global function pointers on initialisation while the calls look like normal statically linked functions. And you avoid confusing pre-processor macros voodoo at the same time.
By creating different function-pointer types with different signatures, the compiler will be able to perform some parameter type checking for you too.
Upvotes: 2
Reputation: 3833
The symbol is pasted in which creates a temporary (un named ) pointer to a function at a fixed memory location and then calls it via dereferencing.
Upvotes: 0
Reputation: 104050
The #define
causes (*Device_cal)()
to be expanded into this immediately before compiling:
(*(void(*)(void))0x3D7C80)()
The void(*)(void)
is a declaration for a function pointer that takes void
and returns void
types. The (*())
represents a cast for the next token in the expression (0x3D7C80
). Thus this asks to treat the data at location 0x3D7C80
as a function. The final ()
calls the function with no arguments.
Upvotes: 3
Reputation: 5456
well, you "define" a pointer to function, and call it.
void(*)(void)
mean a pointer to function, that gets no arguments, and return void
.
If you cast 0x3D7C80
to that type, and call it, you basically call the function that its address is 0x3D7C80
.
Upvotes: 2
Reputation: 145829
void (*) (void)
is a type. It's a pointer to a function that takes no parameter and returns void
.
(void(*)(void)) 0x3D7C80
casts the 0x3D7C80
integer to this function pointer.
(*Device_cal)()
calls the function.
(Device_cal)()
would do the exactly the same.
The parentheses around *Device_cal
and Device_cal
are required because otherwise the cast to the integer would not have the higher precedence.
Upvotes: 7