简体   繁体   English

有人可以解释什么是 (void (*) (void))((uint32_t)&__STACK_END) 吗?

[英]Can someone explain what is (void (*) (void))((uint32_t)&__STACK_END)?

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 (* const interruptVectors[])(void) - 是一个必须包含函数名称的函数指针数组,但我无法理解(void (*) (void))((uint32_t)&__STACK_END)语法。

(void (*) (void)) looks like a pointer to a function that returns nothing, without arguments and has no name. (void (*) (void))看起来像一个指向函数的指针,它什么都不返回,没有参数,也没有名称。 Is it possible?可能吗?

(uint32_t)&__STACK_END is a pointer. (uint32_t)&__STACK_END是一个指针。 And why are function pointer and pointer together?为什么函数指针和指针在一起?

Thanks in advance!提前致谢!

This looks like interrupt vector table for ARM processor or similar.这看起来像 ARM 处理器或类似的中断向量表。 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.不是因为处理器关心类型,而是因为 C 关心。

So &__STACK_END is presumable some pointer type which points to data address at the end of stack.所以&__STACK_END可能是一些指针类型,它指向堆栈末尾的数据地址。 This is then converted to plain 32-bit number, and finally converted to function pointer.然后将其转换为普通的 32 位数字,最后转换为函数指针。

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.可能可以跳过第一次转换为uint32_t并直接从数据指针转换为函数指针,但这样做可能是为了确保在给定编译器上正确完成转换。

Stricly speaking in C standard this conversion from data pointer to function pointer is not legal, even with integer cast in the middle.严格来说,在 C 标准中,这种从数据指针到函数指针的转换是不合法的,即使中间有整数转换也是如此。 However, most embedded compilers can do this, because this is typical thing you need to do.但是,大多数嵌入式编译器都可以做到这一点,因为这是您需要做的典型事情。

The first value of the vector table of a CORTEX-M is the initial value of stack pointer, that looks like yours case. CORTEX-M 的向量表的第一个值是堆栈指针的初始值,看起来像你的情况。 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.此语法是将整个向量表定义为类型为 void(*function)(void) 的函数指针的常量数组,同时将第一个值定义为堆栈指针值作为常量的技巧。

Personally I think there are better ways to define this more clearly.我个人认为有更好的方法可以更清楚地定义这一点。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM