mhl
mhl

Reputation: 705

Pointer to function in ROM

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

Answers (5)

Clifford
Clifford

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

Bingo
Bingo

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

sarnold
sarnold

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

asaelr
asaelr

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

ouah
ouah

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

Related Questions