Home > Back-end >  Can someone explain what is (void (*) (void))((uint32_t)&__STACK_END)?
Can someone explain what is (void (*) (void))((uint32_t)&__STACK_END)?

Time:06-29

This is some startup file excerpt with interrupt vectors.

#pragma DATA_SECTION(interruptVectors, ".intvects")
void (* const interruptVectors[])(void) = 
{
 (void (*) (void))((uint32_t)&__STACK_END),
 resetISR,
 nmi_ISR,
 fault_ISR,
 ... /* More interrupt vectors */

void (* const interruptVectors[])(void) - is a array of function pointers that must contain function names, but I can't understand (void (*) (void))((uint32_t)&__STACK_END) syntax.

(void (*) (void)) looks like a pointer to a function that returns nothing, without arguments and has no name. Is it possible?

(uint32_t)&__STACK_END is a pointer. And why are function pointer and pointer together?

Thanks in advance!

CodePudding user response:

This looks like interrupt vector table for ARM processor or similar. Interrupt vector table contains addresses of interrupt handlers, so it is essentially an array of function pointers.

First entry of this table is initialization value for stack pointer. It's obviously not function pointer, but data pointer, so some type conversion is needed. Not because processor cares about types, but because C does.

So &__STACK_END is presumable some pointer type which points to data address at the end of stack. This is then converted to plain 32-bit number, and finally converted to function pointer.

It might have been possible to skip first cast to uint32_t and cast directly from data pointer to function pointer, but it is perhaps done to make sure that conversion is done correctly on given compiler.

Stricly speaking in C standard this conversion from data pointer to function pointer is not legal, even with integer cast in the middle. However, most embedded compilers can do this, because this is typical thing you need to do.

CodePudding user response:

The first value of the vector table of a CORTEX-M is the initial value of stack pointer, that looks like yours case. This syntax is a hack to define the whole vector table as a constant array of function pointer of type void(*function)(void) while defining the first value as the stack pointer value as a constant.

Personally I think there are better ways to define this more clearly.

  • Related